Supprimer la clause DEFINER des vidages MySQL

114

J'ai un vidage MySQL d'une de mes bases de données. Il contient des clauses DEFINER qui ressemblent à,

"DEFINER=`root`@`localhost`" 

À savoir, ces clauses DEFINER se trouvent sur mes instructions CREATE VIEW et CREATE PROCEDURE. Existe-t-il un moyen de supprimer ces clauses DEFINER de mon fichier de vidage?

Voie rapide
la source
Un bogue a été signalé il y a des années, mais il semble abandonné: bugs.mysql.com/bug.php?id=24680
1234ru

Réponses:

109

Je ne pense pas qu'il existe un moyen d'ignorer l'ajout de DEFINERs au vidage. Mais il existe des moyens de les supprimer après la création du fichier de vidage.

  1. Ouvrez le fichier de vidage dans un éditeur de texte et remplacez toutes les occurrences de DEFINER=root@localhostpar une chaîne vide ""

  2. Modifiez le vidage (ou dirigez la sortie) en utilisant perl:

    perl -p -i.bak -e "s/DEFINER=\`\w.*\`@\`\d[0-3].*[0-3]\`//g" mydatabase.sql
  3. Dirigez la sortie à travers sed:

    mysqldump ... | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > triggers_backup.sql
Abhay
la source
1
@FastTrack, veuillez supprimer la chaîne entière.
Abhay
3
Je suggère de mentionner qu'au lieu de supprimer le DEFINER, il peut être réglé sur CURRENT_USER comme ça: sed -E 's/DEFINER=[^ ]+@ [^] + /DEFINER=CURRENT_USER/g' dump.sql > new_dump.sqlIl a l'avantage de conserver les restrictions / contrôle d'accès.
4thfloorstudios
27
La sedcommande ne supprime pas la clause DEFINER des procédures et des fonctions. Voici la version améliorée qui gère les vues, les déclencheurs, les procédures et les fonctions: sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*PROCEDURE/PROCEDURE/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*FUNCTION/FUNCTION/'
Vladimir Strugatsky
4
Pour info --- bien que ce n'était pas le cas au moment de cette réponse, MySQL> 5.6 est maintenant livré avec un mysqldump (1) qui prend en charge "--skip-definer" en option: dev.mysql.com/doc/refman /5.7/en/…
Kevin_Kinsey
4
Non, ce n'est pas mysqldump, mais mysql p ump qui a --skip-definer.
Xdg
70

Vous pouvez supprimer en utilisant SED

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

Sous MacOS:

sed -i '' 's/DEFINER=[^*]*\*/\*/g' mydump.sql
Ricardo Martins
la source
Que se passe-t-il ici sous MacOS pour être différent?
Alex
1
La page de manuel de sed sur mac dit ceci: -i extension"Modifiez les fichiers sur place, enregistrez les sauvegardes avec l'extension spécifiée. Si une extension de longueur nulle est donnée, aucune sauvegarde ne sera enregistrée. Il n'est pas recommandé de donner une extension de longueur nulle lorsque les fichiers d'édition sur place, car vous risquez une corruption ou un contenu partiel dans des situations où l'espace disque est épuisé, etc. "
Tchad le
Ravi de savoir ça, @Chad. J'utilise sed comme ça sous mac depuis plus de 5 ans maintenant. Je n'ai jamais eu de problèmes d'espace ou de fichiers corrompus. Mais bien sûr, c'est quelque chose à considérer. Merci de clarifier.
Ricardo Martins le
Je n'ai jamais rencontré ces problèmes sur Mac non plus. Je pensais juste que je clarifierais puisque @Alex a demandé :)
Tchad
57

Depuis la version 5.7.8 de mysql, vous pouvez utiliser l' --skip-defineroption avec mysqlpump, par exemple:

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

Voir le manuel mysql mis à jour sur http://dev.mysql.com/doc/refman/5.7/en/mysqlpump.html#option_mysqlpump_skip-definer

maxhb
la source
8
Pour quiconque se demande quelle est la différence entre mysqldumpet mysqlpump- voici la question connexe: dba.stackexchange.com/questions/118846/mysqldump-vs-mysqlpump
Scadge
J'ai installé phpMyAdmin et MySQL Workbench. Comment exécuter cette commande sous Windows?
posfan12
(après quelques tests: -1) Il utilise information_schema.user, et ce n'est pas toujours lisible pour tous les utilisateurs
bato3
17

J'ai utilisé ces idées pour supprimer la clause DEFINER de ma propre sortie mysqldump, mais j'ai adopté une approche plus simple:

Supprimez simplement le !avant le code et DEFINER, et le reste du commentaire devient un commentaire normal.

Exemple:

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

est rendu impuissant, aussi peu que faire cela.

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

Cependant, l'expression rationnelle la plus simple consiste à supprimer le! et les chiffres

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

Cela supprime !#### DEFINERet remplace par DEFINER ... vous pouvez également supprimer DEFINER, cela n'a pas vraiment d'importance - une fois le "!" est parti

SitesBySequoia.com
la source
16

Selon les recommandations de l'autre, voici un exemple de la façon de supprimer le DEFINER du vidage, une fois le vidage terminé:

mysqldump -u user --password='password' -h localhost database | grep -v "50013 DEFINER" > dump.sql
Jonathan
la source
4
Pour les triggers, les lignes ressemblent à / *! 50003 CREATE * / / *! 50017 DEFINER = user@ localhost* / / *! 50003 trigger my_triggername AVANT INSERER SUR ma_table POUR CHAQUE RANG .... * / ;; et grep -vabandonnera ces lignes entièrement. (bien que 50017! = 50013)
Kenney
13

Comme d'autres l'ont mentionné, supprimer le définisseur avec n'importe quel type d'expression régulière n'est pas trop complexe. Mais les autres exemples ont dépouillé les définitions de vue pour moi.

C'est l'expression régulière qui a fonctionné pour moi:

sed -e 's/DEFINER=[^ ]* / /'
Lajos Veres
la source
Et plus vite ^^ Merci
Kevin Labécot
1
Ne fonctionne pas avec les déclencheurs - supprime également les fichiers */. MySQL 5.6.31.
Franc Drobnič
10

Pour une solution automatisée, vous pouvez regarder mysqlmigrate. C'est un wrapper Bash mysqldumpqui vous permet de migrer des bases de données et d'ignorer les instructions DEFINER. Exemple:

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

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

Sinon, oui, une commande comme le souligne Abhay est nécessaire:

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

Une autre option sur OSX pour supprimer les définisseurs dans le fichier:

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

Vous devriez regarder la réponse ici: /dba/9249/how-do-i-change-the-definer-of-a-view-in-mysql/29079#29079

Le meilleur moyen à mon avis de résoudre ce problème, n'est pas d'ajouter une analyse supplémentaire de chaîne avec sed ou grep ou tout autre, mais mysqldump est capable de générer un bon vidage en ajoutant --single-transaction

José Nobile
la source
Pourquoi voter contre? Pourquoi cette réponse n'est-elle pas considérée comme utile?
Jose Nobile
1
Votre réponse a encore besoin d'environ 90 votes positifs pour obtenir la position qu'elle mérite. You have mine :)
Patrick van Bergen
4

Un moyen rapide de le faire est de diriger la sortie de mysqldump via sed pour supprimer les DEFINERinstructions encapsulées dans des commentaires conditionnels. J'utilise ceci pour supprimer DEFINERdes CREATE TRIGGERdéclarations, mais vous pouvez modifier le numéro de version du commentaire de condition dans l'expression régulière en fonction de vos besoins.

mysqldump -u user --password='password' -h localhost database | \
  sed 's/\/\*!50017 DEFINER=`.*`@`.*`\*\///' 
Paul Dixon
la source
1
Une instruction sed un peu plus lisible: sed "s / DEFINER (. *?) FUNCTION / FUNCTION /"
reustmd
4

Je ne sais pas si cela aide mais j'utilise SQLyog Community Edition, disponible sur: -

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

Lors du vidage de SQL ou de la copie dans une autre base de données, il vous permet d'ignorer DEFINER

Il est gratuit et fournit les fonctionnalités de base dont beaucoup de gens ont besoin

Il existe également une version payante disponible sur: -

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

À votre santé

itfidds
la source
Plutôt que de simplement signaler comme «inutile», il serait peut-être plus utile de répondre en expliquant pourquoi vous pensez que ce n'est pas utile?
itfidds le
3

Pour moi, cela fonctionne: perl -p -i.bak -e "s/DEFINER=[^ |\s]*//g" yourdump.dmp. Cela a supprimé DEFINER = root @ localhost de mon vidage, à chaque instruction de procédure de création

Rafwell
la source
2

Voici une solution de travail complète pour supprimer les informations DEFINER pour MySQL 5.6.xet Linux. (Testé sur CentOS 6.5).

Habituellement, nous devons remplacer les entrées suivantes de Mysql dump (si prises avec les données et les déclencheurs / routines / fonctions).

/*!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`

Le vidage a été effectué avec la commande mysqldump ci-dessous.

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

Le fichier de vidage requis sans informations DEFINER peut être obtenu avec les trois commandes ci-dessous.

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 le fichier de vidage se trouve dans votre dossier actuel, ignorez [PATH /].

Si les données dans les tables sont très volumineuses, effectuez le vidage dans deux fichiers, dans un fichier de vidage, prenez le vidage avec les données et dans un autre fichier de vidage, prenez le vidage des scripts uniquement (Triggers / Fonctions / Procédures.) Et exécutez les trois ci-dessus. commandes sur le 2ème fichier de vidage (scripts).

Je Bajwa PHD
la source
1

Remplacez tous vos utilisateurs définitifs par CURRENT_USER. Dans mon script gradle qui crée la sauvegarde, mon script de remplacement ressemble à:

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

qui appelle vraiment ANT. Alors vous n'aurez plus à vous en soucier.

Ryan Shillington
la source
1

Sur les machines Linux, vous pouvez utiliser ce one-liner:

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

Vous n'avez qu'à remplacer les chaînes en gras par vos informations d'identification d'utilisateur de base de données et le nom de base de données / modèle similaire.

Plus d'informations ici: http://blog.novoj.net/2014/05/16/recreate-mysql-views-without-definer-one-liner-solution-linux/

Novoj
la source
1

La seule façon de le faire fonctionner sous Windows:

Installez http://gnuwin32.sourceforge.net/ pour avoir sed dans la ligne de commande et ajoutez-le au PATH 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
Artur Kędzior
la source
1

Merci à tous pour les indices. Étant paresseux, j'ai écrit un script nommé: "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
R.Canaro
la source
1

Pour quelque chose comme:

DELIMITER ;;
CREATE DEFINER = `mydb` @` localhost` FONCTION `mafonction` () RETURNS int (11)
commencer
(...)
fin ;;

Essaye ça:

mysqldump --force --routines --opt --user = monutilisateur --databases mydb | sed -e 's / DEFINER = `. *` @ `. *` \ // g'
impactaweb
la source
1
  1. ouvrez votre base de données avec n'importe quel éditeur, j'ai utilisé avec notepad ++,

  2. trouver tout le test DEFINER=root@localhost et le remplacer par rien ( "") IE. supprime-le.

Ensuite, vous pouvez l'importer sur n'importe quel hôte de votre choix.

Lê Công Danh
la source
0

La regex la plus simple qui fonctionne pour moi avec tous les objets est:

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

Notez que quote-namesdoit être TRUE(ce qui est par défaut).

J'espère que dans les versions plus récentes, le commutateur --skip-definerintroduit dans mysqlpump dans la version 5.7 viendra également sur mysqldump.

Franc Drobnič
la source
0

J'ai utilisé le script PowerShell pour supprimer toutes les lignes avec DEFINER:

get-content $ file_in_full_path | select-string -pattern $ line_string_delete -notmatch | Out-File -width 1000000000 -Encoding Default $ file_out_full_path

Alen
la source
0

Rien ne fonctionnait pour moi, donc j'avais besoin d'écrire ma propre regex.

  1. Essayez de vider votre base de données dans un fichier, un fichier catentier et grepuniquement vos déclarations définitives pour les voir.

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

  2. Écrivez votre regex

  3. Dirigez votre vidage dans sed avec cette regex. Par exemple, ma déclaration est:

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

  4. Profit!

Xdg
la source
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
Luiz Rodolfo
la source