Modifique o DEFINER em várias exibições

25

Estou com problemas para fazer backup dos meus bancos de dados após uma atualização. Eu ando bisbilhotando no meu sistema tentando descobrir o porquê. Uma consulta que eu executei retornou esse resultado.

Got error: 1449: The user specified as a definer ('cittool'@'%') does not exist when using LOCK TABLES

Após alguma investigação, parece que o definidor para essas visualizações é uma conta de desenvolvedor antiga que foi removida do sistema. Os bancos de dados e visualizações com esse problema são usados ​​com pouca frequência e a maioria é mantida para fins de arquivamento.

Existem cerca de 40 visualizações com um definidor que não existe mais. Existe uma maneira fácil de mudar o definidor para uma conta diferente em tudo de uma só vez? Existe uma maneira de o mysqldump simplesmente despejar todas as visualizações em um arquivo para que eu possa editar esse arquivo e recriar as visualizações?

Zoredache
fonte
para mim, acabei de adicionar a conta ausente ao banco de dados e o erro desapareceu.
user1794918

Respostas:

13

Crie um arquivo de texto com todas as definições de exibição:

mysql -uusername -ppassword -A --skip-column-names -e"SELECT CONCAT('SHOW CREATE VIEW ',table_schema,'.',table_name,'\\G') FROM information_schema.tables WHERE engine IS NULL" | mysql -uusername -ppassword -A --skip-column-names > AllMyViews.sql

Você edita AllMyViews.sql a partir daí. Em seguida, solte as visualizações

mysql -uusername -ppassword -A --skip-column-names -e"SELECT CONCAT('DROP VIEW ',table_schema,'.',table_name,';') FROM information_schema.tables WHERE engine IS NULL" | mysql -uusername -ppassword -A

Após editar o AllMyViews.sql, recarregue-os

mysql -uusername -ppassword -A < AllMyViews.sql

De uma chance !!!

RolandoMySQLDBA
fonte
Marque +1 como uma ótima alternativa se a definição de view_chave de informações não estiver aparecendo, mas o SHOW CREATE VIEW funciona bem.
Derek Downey
Embora eu gostasse mais da solução do DTest em teoria, algo no meu sistema estava impedindo que ele funcionasse. Basicamente, usei o acima para despejar as instruções show create em um arquivo e tive que editá-las manualmente um pouco e depois executá-las.
precisa
O SHOW CREATE VIEW não funciona quando o usuário definidor não existe - ele lança o mesmo erro que o mysqldump:The user specified as a definer ('abc'@'1.2.3.4') does not exist
Marki555
@ Marki555 Então, você deve criar esse usuário temporariamente. correr CREATE USER 'abc'@'1.2.3.4';. Em seguida, tente novamente.
RolandoMySQLDBA
Eu notei que a exibição usa algum procedimento armazenado e essa mensagem de erro é realated para o definidor desse procedimento, não ver a si mesma
Marki555
25

Você pode usar o ALTER VIEW em conjunto com o esquema de informações . Você mencionou despejá-lo em um arquivo de texto, então talvez algo como isto:

SELECT CONCAT("ALTER DEFINER=`youruser`@`host` VIEW `",table_name,"` AS ", view_definition,";") 
FROM information_schema.views WHERE table_schema='databasename'

Misture isso com a linha de comando do mysql (assumindo * nix, não familiarizado com o windows):

> echo "*abovequery*" | mysql -uuser -p > alterView.sql
> mysql -uuser -p databasename < alterView.sql

Nota: Você não pode alterar as entradas information_schema diretamente . Nota2: Isso funciona apenas para um banco de dados por vez, se você deixar WHERE table_schema, precisará inserir comandos USE entre cada um.

Derek Downey
fonte
Eu gosto disso porque parece um pouco menos envolvido e mais conciso do que o meu. +1 !!! (Esqueci o ALTER VIEW) #
RolandoMySQLDBA
Alguma idéia de por que o campo view_definition estaria vazio? SELECT table_name,view_definition FROM information_schema.views WHERE table_schema='cittmp'; retorna| Staff | |
Zoredache
Da discussão no bate-papo, parece que é um problema de permissão com o super privilégio. bugs.mysql.com/bug.php?id=39733
Derek Downey
Solução perfeita! +1
Pablo Martinez
Pelo menos no RedHat, se você estiver produzindo para um arquivo, precisará escapar dos tiques anteriores, por exemploecho "SELECT CONCAT("ALTER DEFINER=\`youruser\`@\`host\` VIEW...
clav
3

Ao automatizar a solução da Derek, isso mudará DEFINER para root@localhoste definido SQL SECURITY INVOKER(verifique se você deseja isso primeiro!) Em todas as visualizações em todos os bancos de dados:

mysql -BNe 'show databases' | \
egrep -v '^(information_schema|performance_schema)$' | \
while read DB
do 
    mysql -BNe "SELECT CONCAT(\"ALTER DEFINER=\`root\`@\`localhost\` SQL SECURITY INVOKER VIEW \",table_name,\" AS \", view_definition,\";\") FROM information_schema.views WHERE table_schema=\"$DB\"" | \
    mysql $DB
done

AVISO: verifique se você fez um backup completo do mysql (por exemplo, parando o mysqld e fazendo backup de todos os arquivos em / var / lib / mysql) antes de executá-lo - apenas por precaução ... Funcionou para mim, mas o YMMV .

você também deve verificar todas as suas tabelas / visualizações com:

mysql -BNe 'show databases' | \
egrep -v '^(information_schema|performance_schema)$' | \
while read DB
do 
   mysql -BNe 'show tables' $DB | \
   while read t
   do
      echo "check table $t;"
   done | mysql -BN $DB
done | \
egrep -v 'status\s*OK'

não deve mais reclamar de definidores inválidos nas visualizações.

Matija Nalis
fonte
Sem vergonha, isso foi adicionado aos meus trechos. Obrigado!
stefgosselin
3

Exporte todas as visualizações do banco de dados <DB>:

mysql -BNe "SELECT TABLE_NAME FROM TABLES WHERE TABLE_SCHEMA = '<DB>' AND TABLE_TYPE = 'VIEW'" \
    information_schema | xargs mysqldump --single-transaction --no-data <DB> >views.sql

ou:

mysql -BNe "SELECT TABLE_NAME FROM VIEWS WHERE TABLE_SCHEMA = '<DB>'" \
    information_schema | xargs mysqldump --single-transaction --no-data <DB> >views.sql

Edite views.sql(altere o definidor) e recrie-os:

cat views.sql | mysql <DB>

Especifique -ue -palterne, se necessário.

x-yuri
fonte
De que maneira as VIEWS,, devem views.sqlser editadas? Além disso, como recriá-los?
SherylHohman
@SherylHohman Altere DEFINER = olduser@oldhostpara DEFINER = newuser@newhost, cat views.sql | mysql <DB>recria as visualizações.
x-yuri