Eliminar la cláusula DEFINER de MySQL Dumps


114

Tengo un volcado de MySQL de una de mis bases de datos. En él, hay cláusulas DEFINER que se parecen a,

"DEFINER=`root`@`localhost`" 

Es decir, estas cláusulas DEFINER están en mis declaraciones CREATE VIEW y CREATE PROCEDURE. ¿Hay alguna forma de eliminar estas cláusulas DEFINER de mi archivo de volcado?


Se informó de un error hace años, pero parece abandonado: bugs.mysql.com/bug.php?id=24680
1234ru

Respuestas:


109

No creo que haya una manera de ignorar la adición de DEFINERs al volcado. Pero hay formas de eliminarlos después de crear el archivo de volcado.

  1. Abra el archivo de volcado en un editor de texto y reemplace todas las apariciones de DEFINER=root@localhostcon una cadena vacía ""

  2. Edite el volcado (o canalice la salida) usando perl:

    perl -p -i.bak -e "s/DEFINER=\`\w.*\`@\`\d[0-3].*[0-3]\`//g" mydatabase.sql
  3. Canalice la salida a través de sed:

    mysqldump ... | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > triggers_backup.sql

1
@FastTrack, elimine toda la cadena.
Abhay

3
Sugiero mencionar que en lugar de eliminar el DEFINER, se puede configurar en CURRENT_USER así: sed -E 's/DEFINER=[^ ]+@ [^] + /DEFINER=CURRENT_USER/g' dump.sql > new_dump.sqlTiene la ventaja de mantener restricciones / control de acceso.
4thfloorstudios

27
El sedcomando no elimina la cláusula DEFINER de los procedimientos y funciones. Aquí está la versión mejorada que maneja vistas, disparadores, procedimientos y funciones: sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*PROCEDURE/PROCEDURE/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*FUNCTION/FUNCTION/'
Vladimir Strugatsky

4
FYI --- aunque no era el caso en el momento de esta respuesta, MySQL> 5.6 ahora se envía con un mysqldump (1) que admite "--skip-definer" como una opción: dev.mysql.com/doc/refman /5.7/en/…
Kevin_Kinsey

4
No, no es mysqldump, sino mysql p ump quien tiene --skip-definer.
Xdg

70

Puedes eliminar usando SED

sed -i 's/DEFINER=[^*]*\*/\*/g' mydump.sql

En MacOS:

sed -i '' 's/DEFINER=[^*]*\*/\*/g' mydump.sql

¿Qué está pasando aquí en MacOS para ser diferente?
Alex

1
La página de manual de sed en mac dice lo siguiente: -i extension"Edite archivos en el lugar, guardando copias de seguridad con la extensión especificada. Si se proporciona una extensión de longitud cero, no se guardará ninguna copia de seguridad. No se recomienda dar una extensión de longitud cero cuando archivos de edición in situ, ya que corre el riesgo de corrupción o contenido parcial en situaciones en las que se agota el espacio en disco, etc. "
Chad

Es bueno saber eso, @Chad. Estoy usando sed como este en mac durante más de 5 años. Nunca tuve problemas con el espacio o archivos corruptos. Pero claro, es algo a considerar. Gracias por aclararlo.
Ricardo Martins

Tampoco me he encontrado con esos problemas en Mac. Solo pensé en aclarar ya que @Alex preguntó :)
Chad

57

Desde la versión 5.7.8 de mysql puede usar la --skip-defineropción con mysqlpump, por ejemplo:

mysqlpump --skip-definer -h localhost -u user -p yourdatabase

Consulte el manual actualizado de mysql en http://dev.mysql.com/doc/refman/5.7/en/mysqlpump.html#option_mysqlpump_skip-definer


8
Para quien se pregunte cuál es la diferencia entre mysqldumpy mysqlpump- aquí está la pregunta relacionada: dba.stackexchange.com/questions/118846/mysqldump-vs-mysqlpump
Scadge

Tengo phpMyAdmin y MySQL Workbench instalados. ¿Cómo ejecuto este comando en Windows?
posfan12

(después de algunas pruebas: -1) Se usa information_schema.user, y esto no siempre es legible para todos los usuarios
bato3

17

Usé estas ideas para quitar la cláusula DEFINER de mi propia salida de mysqldump, pero tomé un enfoque más simple:

Solo quita el ! antes del código y DEFINER, y el resto del comentario se convertirá en un comentario regular.

Ejemplo:

/*!50017 DEFINER=`user`@`111.22.33.44`*/

se vuelve indefenso, tan poco como hacer esto ..

/* 50017 DEFINER=`user`@`111.22.33.44`*/

Sin embargo, la expresión regular más fácil es eliminar el! y los numeros

mysqldump | /usr/bin/perl -pe 's/\!\d+ DEFINER/DEFINER/' > dumpfile.sql

Eso elimina !#### DEFINERy reemplaza con DEFINER ... también puede eliminar DEFINER, realmente no importa, una vez que aparezca el "!" se ha ido


16

De acuerdo con las recomendaciones del otro, aquí hay un ejemplo de cómo eliminar el DEFINER del volcado, una vez finalizado el volcado:

mysqldump -u user --password='password' -h localhost database | grep -v "50013 DEFINER" > dump.sql

4
Para los disparadores, las líneas se ven así / *! 50003 CREATE * / / *! 50017 DEFINER = user@ localhost* / / *! 50003 trigger my_triggername ANTES DE INSERTAR EN my_table PARA CADA FILA .... * / ;; y grep -veliminará esas líneas por completo. (aunque 50017! = 50013)
Kenney

13

Como otros mencionaron, eliminar el definidor con cualquier tipo de expresión regular no es demasiado complejo. Pero los otros ejemplos me quitaron las definiciones de vista.

Esta es la expresión regular que funcionó para mí:

sed -e 's/DEFINER=[^ ]* / /'

Y más rápido ^^ Gracias
Kevin Labécot

1
No funciona con desencadenantes; también elimina el */. MySQL 5.6.31.
Franc Drobnič

10

Para una solución automatizada, podría mirar mysqlmigrate. Es un envoltorio Bash mysqldumpque le permite migrar bases de datos e ignorar las declaraciones DEFINER. Ejemplo:

$ mysqlmigrate -u root -p pass --ignore-definer from_db to_db

http://thesimplesynthesis.com/post/mysqlmigrate (o GitHub )

De lo contrario, sí, se necesita un comando como el que señala Abhay:

$ mysqldump -u root -ppass the_db | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > the_db.sql

6

Otra opción en OSX para eliminar definidores en el archivo:

sed -i '' 's/DEFINER=`[^`][^`]*`@`[^`][^`]*`//g' file.sql

5

Deberías buscar la respuesta aquí: /dba/9249/how-do-i-change-the-definer-of-a-view-in-mysql/29079#29079

En mi opinión, la mejor manera de abordar este problema es no agregar un análisis adicional de cadena con sed o grep o cualquier otro, en su lugar, mysqldump puede generar un buen volcado agregando --single-transaction


¿Por qué votar en contra? ¿Por qué esta respuesta no se considera útil?
Jose Nobile

1
Su respuesta aún necesita alrededor de 90 votos a favor para obtener el puesto que se merece. Tú tienes el mío :)
Patrick van Bergen

4

Una forma rápida de hacer esto es canalizar la salida de mysqldump a través de sed para eliminar las DEFINERdeclaraciones envueltas en comentarios condicionales. Utilizo esto para eliminar DEFINERde las CREATE TRIGGERdeclaraciones, pero puede modificar el número de versión del comentario de la condición en la expresión regular para que se adapte a sus propósitos.

mysqldump -u user --password='password' -h localhost database | \
  sed 's/\/\*!50017 DEFINER=`.*`@`.*`\*\///' 

1
Una declaración sed un poco más legible: sed "s / DEFINER (. *?) FUNCTION / FUNCTION /"
reustmd

4

No estoy seguro de si ayuda, pero uso SQLyog Community Edition, disponible en: -

https://code.google.com/p/sqlyog/wiki/Downloads

Al descargar sql o copiar a otra base de datos, le permite 'Ignorar DEFINER'

Es gratis y proporciona la funcionalidad básica que mucha gente necesita.

También hay una versión de pago disponible en: -

https://www.webyog.com/product/sqlyog

Salud


En lugar de simplemente marcar como 'no útil', tal vez sería más útil si responde por qué cree que no es útil.
itfidds

3

Para mí, esto funciona: perl -p -i.bak -e "s/DEFINER=[^ |\s]*//g" yourdump.dmp. Esto eliminó DEFINER = root @ localhost de mi volcado, en cada declaración de procedimiento de creación


2

Aquí hay una solución de trabajo completa para eliminar la información DEFINER para MySQL 5.6.xLinux. (Probado enCentOS 6.5 ).

Por lo general, tenemos que reemplazar las siguientes entradas del volcado de Mysql (si se toman junto con los datos y los activadores / rutinas / funciones).

/*!50013 DEFINER=`MYSQLUSER`@`localhost` SQL SECURITY DEFINER */
/*!50013 DEFINER=`MYSQLUSER`@`%` SQL SECURITY DEFINER */
CREATE DEFINER=`MYSQLUSER`@`%` PROCEDURE `PROCEDURENAME`(
CREATE DEFINER=`MYSQLUSER`@`localhost` PROCEDURE `PROCEDURENAME`(
CREATE DEFINER=`MYSQLUSER`@`%` FUNCTION `FUNCTIONNAME`(
CREATE DEFINER=`MYSQLUSER`@`localhost` FUNCTION `FUNCTIONNAME`(
/*!50003 CREATE*/ /*!50017 DEFINER=`MYSQLUSER`@`%`*/ /*!50003 TRIGGER `TRIGGERNAME`
/*!50003 CREATE*/ /*!50017 DEFINER=`MYSQLUSER`@`localhost`*/ /*!50003 TRIGGER `TRIGGERNAME`

El volcado se realizó con el siguiente comando mysqldump.

mysqldump -uMYSQLUSER -pPASSWORD DATABASENAME -R > dbdump.sql

El archivo de volcado requerido sin información de DEFINER se puede obtener con los siguientes tres comandos.

Command-1    
sed -i 's|DEFINER=[^*]*\*|\*|g' [PATH/]dbdump.sql

Command-2
find -name [PATH/]dbdump.sql | xargs perl -pi -e "s/ DEFINER=\`MYSQLUSER\`@\`localhost\`//"

Command-3
find -name [PATH/]dbdump.sql | xargs perl -pi -e "s/ DEFINER=\`MYSQLUSER\`@\`%\`//"

Si el archivo de volcado está en su carpeta actual, ignore [PATH /].

Si los datos en las tablas son muy grandes, realice el volcado en dos archivos, en un archivo de volcado tome el volcado con datos y en otro archivo de volcado tome el volcado solo de los scripts (Disparadores / Funciones / Procedimientos) y ejecute los tres anteriores comandos en el segundo archivo de volcado (scripts).


1

Reemplace todos sus usuarios definidores con CURRENT_USER. En mi script de Gradle que crea la copia de seguridad, mi script de reemplazo se ve así:

ant.replaceregexp(file: "$buildDir/sql/setupDB.sql", match: "`${project.ext.prod_db_username}`@`%`", replace: "CURRENT_USER", byline: true);

que realmente es solo llamar a ANT. Entonces no tendrás que preocuparte por eso.


1

En máquinas Linux, puede usar este resumen:

mysql -uuser -ppwd -A --skip-column-names -e"SELECT CONCAT('SHOW CREATE VIEW ',table_schema,'.',table_name,';') FROM information_schema.tables WHERE engine IS NULL and table_schema like 'mydb%'" | mysql -uuser -ppwd -A --skip-column-names | sed -rn 's/.*?VIEW ([^\s]+?) (AS .*?)\s([^\s]+?)\s([^\s]+?)/DROP VIEW \1;\nCREATE VIEW \1 \2;/p' | mysql -uuser -ppwd -A --skip-column-names

Solo tiene que reemplazar las cadenas en negrita con sus credenciales de usuario de base de datos y el nombre de la base de datos / patrón similar.

Más información aquí: http://blog.novoj.net/2014/05/16/recreate-mysql-views-without-definer-one-liner-solution-linux/


1

La única forma en que podría hacerlo funcionar en Windows:

Instale http://gnuwin32.sourceforge.net/ para tener sed en la línea de comandos y agréguelo a la RUTA de Windows : D: \ programmes \ GetGnuWin32 \ bin;

sed -i "s|DEFINER=`mydbuser`@`%%` SQL SECURITY DEFINER||g" "D:/prod_structure.sql"

sed -i "s|DEFINER=`mydbuser`@`%%`||g" "D:/prod_structure.sql"

mysqldump -P{port} -h{host} -u{user} -p{password} --routines --no-data --lock-tables=false database_prod > D:\prod_structure.sql

1

Gracias a todos por las pistas. Siendo perezoso, escribí un script llamado: "MYsqldump":

DB=$1
HOST=$2
USER=$3
MYSQLDUMP='/usr/bin/mysqldump'
PARAMS="--complete-insert --disable-keys=0 --extended-insert=0 --routines=0 --skip-comments"
DAY=`date +%d`
MONTH=`date +%m`
YEAR=`date +%Y`
FILE=$DB.$DAY-$MONTH-$YEAR.sql

    if (( $# < 3 )) ; then
        echo ""
        echo "usage: MYsqldump <db> <host> <user>"
        echo ""
        exit 1
    fi

    $MYSQLDUMP -h $HOST -u $USER -p  $PARAMS $DB | grep -v '/*!50013 DEFINER' > $FILE

1

Por algo como:

DELIMITER ;;
CREATE DEFINER = `mydb` @` localhost` FUNCIÓN `myfunction` () RETURNS int (11)
empezar
(...)
final ;;

Prueba esto:

mysqldump --force --routines --opt --user = myuser --databases mydb | sed -e 's / DEFINER = `. *` @ `. *` \ // g'

1
  1. abra su base de datos con cualquier editor, usé con notepad ++,

  2. encuentre todo, pruebe eso DEFINER=root@localhost y reemplácelo con nada ( "") IE. bórralo.

Luego, puede importarlo a cualquier host que desee.


0

La expresión regular más simple que me funciona con todos los objetos es:

sed 's/DEFINER=[^ ]*`//' ...

Tenga en cuenta que quote-namestiene que serTRUE (que es de forma predeterminada).

Espero que en las versiones más recientes el conmutador --skip-definerintroducido en mysqlpump en la versión 5.7 también llegue a mysqldump.


0

He usado el script de PowerShell para eliminar todas las líneas con DEFINER :

get-content $ file_in_full_path | select-string -pattern $ line_string_delete -notmatch | Out-File -width 1000000000-Codificación predeterminada $ file_out_full_path


0

Nada funcionaba para mí, así que necesitaba escribir mi propia expresión regular.

  1. Intente volcar su base de datos en un archivo, catun archivo completo y grepsolo sus declaraciones definitorias para verlas.

    cat file.sql | grep -o -E '. {, 60} DEFINER. {, 60}'

  2. Escribe tu expresión regular

  3. Canalice su volcado a sed con esta expresión regular. Por ejemplo, la declaración mía es:

    mysqldump | sed -E 's // *! 500 [0-9] [0-9] DEFINER =. +? * ///' | sed -E 's / DEFINER = ?[^ ]+?? @ ?[^ ]+?? //'

  4. ¡Lucro!


0

remove_definers.bat:

@echo off
(for /f "tokens=1,2*" %%a in (dumpfile.sql) do (
 if "%%b"=="" (echo %%a) else (
  echo %%b | find "DEFINER" > null && echo %%a %%c || echo %%a %%b %%c
 )
)) > dumpfile_nodefiners.sql
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.