web-dev-qa-db-fra.com

Comment changer en bloc les déclencheurs MySQL DEFINER

J'ai travaillé sur notre serveur de développement interne et créé des déclencheurs MySQL sur notre serveur MySQL 5.6.13. Le problème que j'ai maintenant, c’est que les déclencheurs (environ 200 au total) ont été créés avec le nom DEFINER = root @ % sur le serveur interne.

Maintenant, je veux passer au serveur de production en direct. Cependant, sur notre serveur live, nous ne permettons pas cet accès à l'utilisateur root. Par conséquent, comment puis-je modifier en bloc tous mes déclencheurs, de sorte qu'il se lise DEFINER = root @ localhost

17
neildt

Une façon de le faire:

1) Vider les définitions de déclencheur dans un fichier

# mysqldump -uroot -p --triggers --add-drop-trigger --no-create-info \
      --no-data --no-create-db --skip-opt test > /tmp/triggers.sql

2) Ouvrez le fichier triggers.sql dans votre éditeur favori et utilisez la fonction Find and Replace pour modifier DEFINERs. Enregistrer le fichier mis à jour.

3) Recréer les déclencheurs à partir du fichier

# mysql < triggers.sql
48
peterm

Sans utiliser l'option --add-drop-trigger:

currentUserDefiner='root'
currentHostDefiner='localhost'
newUserDefiner='user'
newHostDefiner='localhost'
db='myDb'
mysqldump -u root --triggers --no-create-info --no-data --no-create-db --skip-opt $db \
| Perl -0777 -pe 's/(\n\/\*.+?50003 TRIGGER `([^`]+)`)/\nDROP TRIGGER \2;\1/g' \
| Perl -0777 -pe 's/(DEFINER[^`]+)'$currentUserDefiner'(`@`)'$currentHostDefiner'/\1'$newUserDefiner'\2'$newHostDefiner'/gi' \
> out.sql
mysql -u root < out.sql
4
Xorax

La réponse acceptée ne fonctionnait pas pour moi car la plupart de mes clients sont hébergés sur des serveurs avec la version 5.5 et je ne peux rien y faire, et la fonction --add-drop-trigger a été ajoutée dans la version 5.6

Après avoir frappé ma tête à ce sujet, je viens juste d'entrer dans phpMyAdmin qui expose le définisseur sur la page d'édition du déclencheur et j'ai simplement édité le définisseur pour les quelque 20 déclencheurs erronés - phpMyAdmin supprimera et recréera le déclencheur avec le nouveau définisseur. .

Une autre option que j'ai trouvée était de faire un mysqldump complet, d'éditer le fichier résultant, de l'utiliser pour créer une nouvelle base de données, puis d'utiliser un outil tel que Navicat pour effectuer une synchronisation de la structure avec la base d'origine en sélectionnant uniquement les déclencheurs souhaités dans la liste de comparaison résultante. . Ce processus était beaucoup plus long pour moi car je n'avais qu'à éditer 20 déclencheurs, mais si je devais mettre à jour des centaines de déclencheurs, cela serait plus rapide.

1
Craig Jacobs

Je sais que c'est un ancien post, mais peut-être peut-il aider quelqu'un.

J'utilise cette requête SQL pour générer une commande DROP et une commande CREATE:

SELECT CONCAT("DROP TRIGGER ", trigger_name, ";", " CREATE TRIGGER ", TRIGGER_NAME, " AFTER ", EVENT_MANIPULATION, " ON ", EVENT_OBJECT_SCHEMA, ".", EVENT_OBJECT_TABLE, " FOR EACH ROW ", ACTION_STATEMENT, ";") AS sqlCommand FROM information_schema.triggers WHERE EVENT_OBJECT_SCHEMA = "yourdatabase";

J'utilise cela dans mon application lorsque je prends la base de données de production sur ma machine de développement et que je l'utilise avec un foreach sur toutes les commandes et que je recrée les déclencheurs automatiquement. Cela me donne la possibilité de l’automatiser.

Exemple en PHP/Laravel:

    $this->info('DROP and CREATE TRIGGERS');
    $pdo = DB::connection()->getPdo();
    $sql = 'SELECT CONCAT("DROP TRIGGER ", trigger_name, ";", " CREATE TRIGGER ", TRIGGER_NAME, " AFTER ", EVENT_MANIPULATION, " ON ", EVENT_OBJECT_SCHEMA, ".", EVENT_OBJECT_TABLE, " FOR EACH ROW ", ACTION_STATEMENT, ";") AS sqlCommand FROM information_schema.triggers WHERE EVENT_OBJECT_SCHEMA = "mydatabase";';
    $stmt = $pdo->prepare($sql, [PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true]);
    $stmt->execute();
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $stmt->closeCursor();

    foreach($result as $rs){
        $pdo = DB::unprepared($rs['sqlCommand']);
        break;
    }

Astuce: je dois le faire avec pdo à cause du problème de requête de tampon mysql, décrit ici

La même chose que je fais pour mes vues (vous pouvez utiliser ici ALTER TABLE):

    $pdo = DB::connection()->getPdo();
    $sql = 'SELECT CONCAT("ALTER DEFINER=`Homestead` VIEW ", table_name," AS ", view_definition,";") AS sqlCommand FROM  information_schema.views WHERE table_schema="mydatabase";';
    $stmt = $pdo->prepare($sql, [PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true]);
    $stmt->execute();
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $stmt->closeCursor();
    $this->info('View definer changed');

    foreach($result as $rs){
        $pdo = DB::unprepared($rs['sqlCommand']);
    }

J'espère que ça aide.

1
ndberg

Une autre approche consiste à utiliser cet utilitaire Java. Notez qu'il s'agit d'un travail en cours, car la version 1.0 actuelle efface certaines variables du serveur. newdef

1
user3092412

Une autre variante du thème utilisant une option de MySQL Workbench consiste à vider toute la base de données avec "mysqldump", à ouvrir le dump dans un éditeur capable, à remplacer le fichier par "DEFINER" souhaité, puis à l'importer avec MyQSL Workbench avec l'option "Structure de vidage". (v6.2) sélectionné sur l'écran d'importation.

0
Damon