Modificar DEFINER en muchas vistas

25

Tengo problemas para hacer una copia de seguridad de mis bases de datos después de una actualización. He estado hurgando en mi sistema tratando de descubrir por qué. Una consulta que ejecuté devolvió este resultado.

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

Después de investigar un poco, parece que el definidor de estas vistas es una antigua cuenta de desarrollador que se ha purgado del sistema. Las bases de datos y las vistas con este problema se usan con poca frecuencia, y la mayoría se mantienen con fines de archivo.

Hay alrededor de 40 vistas con un definidor que ya no existe. ¿Hay una manera fácil de cambiar el definidor a una cuenta diferente en todo a la vez? ¿Hay alguna manera de hacer que mysqldump simplemente descargue todas las vistas en un archivo para poder editar ese archivo y recrear las vistas?

Zoredache
fuente
para mí, acabo de agregar la cuenta que falta a la base de datos y el error desapareció.
user1794918

Respuestas:

13

Cree un archivo de texto con todas las definiciones de vista:

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

Edita AllMyViews.sql desde allí. Luego, suelte las vistas

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

Después de editar AllMyViews.sql, vuelva a cargarlos

mysql -uusername -ppassword -A < AllMyViews.sql

Darle una oportunidad !!!

RolandoMySQLDBA
fuente
+1 como una excelente alternativa si la vista_definición de información_esquema no aparece pero SHOW CREATE VIEW funciona bien.
Derek Downey
Si bien en teoría me gustaba más la solución de DTest, algo en mi sistema me impedía funcionar. Básicamente, utilicé lo anterior para volcar las declaraciones show create en un archivo, y tuve que editarlas manualmente un poco y luego ejecutarlas.
Zoredache
SHOW CREATE VIEW no funciona cuando el usuario definitivo no existe: arroja el mismo error que mysqldump:The user specified as a definer ('abc'@'1.2.3.4') does not exist
Marki555
@ Marki555 Entonces, debe crear ese usuario temporalmente. ejecutar CREATE USER 'abc'@'1.2.3.4';. Vuelva a intentarlo.
RolandoMySQLDBA
Acabo de notar que la Vista usa algún procedimiento almacenado y que el mensaje de error se relaciona con el definidor de ese procedimiento, no se ve a sí mismo
Marki555
25

Puede usar ALTER VIEW junto con el esquema de información . Usted mencionó descargarlo en un archivo de texto, así que quizás algo como esto:

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

Mezcle esto con la línea de comando mysql (suponiendo * nix, no familiarizado con windows):

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

Nota al margen: no puede modificar las entradas de información_esquema directamente . Nota 2: Esto funciona solo para una base de datos a la vez, si deja WHERE table_schema necesita insertar comandos USE entre cada uno.

Derek Downey
fuente
Me gusta esto porque parece un poco menos complicado y más conciso que el mío. +1 !!! (Me olvidé de ALTER VIEW)
RolandoMySQLDBA
¿Alguna idea de por qué el campo view_definition estaría vacío? SELECT table_name,view_definition FROM information_schema.views WHERE table_schema='cittmp'; vuelve| Staff | |
Zoredache
De la discusión en el chat, parece que es un problema de permiso con el super privilegio. bugs.mysql.com/bug.php?id=39733
Derek Downey
¡Solución perfecta! +1
Pablo Martinez
Al menos en RedHat, si está enviando a un archivo, debe escapar de los ticks posteriores, por ejemploecho "SELECT CONCAT("ALTER DEFINER=\`youruser\`@\`host\` VIEW...
clav
3

Automatizando la solución de Derek, esto cambiará DEFINER root@localhosty se configurará SQL SECURITY INVOKER(¡asegúrese de que lo desee primero!) En todas las vistas en todas las bases de datos:

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

ADVERTENCIA: asegúrese de haber realizado una copia de seguridad completa de mysql (por ejemplo, deteniendo mysqld y haciendo una copia de seguridad de todos los archivos en / var / lib / mysql) antes de ejecutarlo, por si acaso ... Funcionó para mí, pero YMMV .

También debe verificar todas sus tablas / vistas con:

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'

ya no debería quejarse de definidores inválidos en las vistas.

Matija Nalis
fuente
Descaradamente agregó esto a mis fragmentos. ¡Gracias!
stefgosselin
3

Exporte todas las vistas de la base de datos <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

o:

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(cambie el definidor) y vuelva a crearlos:

cat views.sql | mysql <DB>

Especifique -uy -pcambie si es necesario.

x-yuri
fuente
¿De qué manera deberían views.sqleditarse las VIEWS ? Además, ¿cómo recrearlos?
SherylHohman
@SherylHohman Cambiar DEFINER = olduser@oldhosta DEFINER = newuser@newhost, cat views.sql | mysql <DB>recrea las vistas.
x-yuri