web-dev-qa-db-fra.com

Comment puis-je exporter les privilèges de MySQL puis les importer sur un nouveau serveur?

Je sais comment exporter/importer les bases de données en utilisant mysqldump & c'est bien mais comment puis-je obtenir les privilèges dans le nouveau serveur.

Pour des points supplémentaires, il y a déjà quelques bases de données existantes sur la nouvelle, comment importer les anciens privilèges des serveurs sans nuquer le couple existant de ceux-ci.

Ancien serveur: 5.0.67-communauté

Nouveau serveur: 5.0.51a-24 + lenny1

EDIT: J'ai un vidage de la base de données 'mysql' de l'ancien serveur et je veux maintenant savoir la bonne façon de fusionner avec la base de données 'mysql' sur le nouveau serveur.

J'ai essayé une importation directe à l'aide de phpMyAdmin et je me suis retrouvé avec une erreur concernant un doublon (celui que j'ai déjà migré manuellement).

Quelqu'un a-t-il eu une manière élégante de fusionner les deux bases de données 'mysql'?

90
Gareth

Ne jouez pas avec la base de données mysql. Il se passe bien plus que la table des utilisateurs. Votre meilleur pari est la commande " SHOW GRANTS FOR". J'ai beaucoup d'alias et de fonctions de maintenance CLI dans mon .bashrc (en fait mes .bash_aliases que je source dans mon .bashrc). Cette fonction:

mygrants()
{
  mysql -B -N $@ -e "SELECT DISTINCT CONCAT(
    'SHOW GRANTS FOR \'', user, '\'@\'', Host, '\';'
    ) AS query FROM mysql.user" | \
  mysql $@ | \
  sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
}

La première commande mysql utilise SQL pour générer du SQL valide qui est dirigé vers la deuxième commande mysql. La sortie est ensuite dirigée vers sed pour ajouter de jolis commentaires.

Le $ @ dans la commande vous permettra de l'appeler comme: mygrants --Host = prod-db1 --user = admin --password = secret

Vous pouvez utiliser votre trousse d'outils Unix complète sur ceci comme ceci:

mygrants --Host=prod-db1 --user=admin --password=secret | grep Rails_admin | mysql --Host=staging-db1 --user=admin --password=secret

C'est LA bonne façon de déplacer les utilisateurs. Votre ACL MySQL est modifiée avec du SQL pur.

171
Bruno Bronosky

Il existe deux méthodes pour extraire des subventions SQL à partir d'une instance MySQL

MÉTHODE # 1

Vous pouvez utiliser pt-show-grant de Percona Toolkit

MYSQL_CONN="-uroot -ppassword"
pt-show-grants ${MYSQL_CONN} > MySQLUserGrants.sql

MÉTHODE # 2

Vous pouvez émuler pt-show-grants avec ce qui suit

MYSQL_CONN="-uroot -ppassword"
mysql ${MYSQL_CONN} --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',Host,''';') FROM mysql.user WHERE user<>''" | mysql ${MYSQL_CONN} --skip-column-names -A | sed 's/$/;/g' > MySQLUserGrants.sql

L'une ou l'autre méthode produira un vidage SQL pur des subventions MySQL. Il ne reste plus qu'à exécuter le script sur un nouveau serveur:

mysql -uroot -p -A < MySQLUserGrants.sql

Essaie !!!

48
RolandoMySQLDBA

La réponse de Richard Bronosky m'a été extrêmement utile. Merci beaucoup!!!

Voici une petite variation qui m'a été utile. Il est utile pour transférer des utilisateurs, par exemple entre deux installations Ubuntu exécutant phpmyadmin. Il suffit de vider les privilèges pour tous les utilisateurs à l'exception de root, phpmyadmin et debian-sys-maint. Le code est alors

mygrants()
{
mysql -B -N $@ -e "SELECT DISTINCT CONCAT(
'SHOW GRANTS FOR ''', user, '''@''', Host, ''';'
) AS query FROM mysql.user WHERE user NOT IN ('root','phpmyadmin','debian-sys-maint')"  | \
mysql $@ | \
sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
}
15
rmldj

Ou, utilisez percona-toolkit (ancien maatkit) et utilisez pt-show-grants (ou mk-show-grants) Dans ce but. Pas besoin de scripts encombrants et/ou de procédures stockées.

7
MrkiMile

Vous pouvez mysqldumper la base de données 'mysql' et l'importer dans la nouvelle; un flush_privileges ou un redémarrage sera nécessaire et vous voudrez certainement sauvegarder d'abord la base de données mysq existante.

Pour éviter de supprimer vos privilèges existants, assurez-vous d'ajouter plutôt que de remplacer des lignes dans les tables de privilèges (db, columns_priv, Host, func, etc.).

5
nedm

Que diriez-vous d'un PHP script? :)

Affichez la source sur ce script et vous aurez tous les privilèges répertoriés:

//connect
mysql_select_db("mysql", mysql_connect("localhost","root",""));

//create grants select statements
$rs = mysql_query("SELECT DISTINCT CONCAT('SHOW GRANTS FOR ''', user, '''@''', Host, ''';') AS query FROM user");

//iterate through grants
while ($row=mysql_fetch_array($rs)) {
    //run grant query
    $rs2 = mysql_query($row['query']);
    //iterate through results
    while($row2 = mysql_fetch_array($rs2)){
        //print results
        echo $row2[0] . ";\n\n";
    }
}
4
Ibrahim Lawal

Vous pouvez également le faire en tant que procédure stockée:

CREATE PROCEDURE spShowGrants()
    READS SQL DATA
    COMMENT 'Show GRANT statements for users'
BEGIN
    DECLARE v VARCHAR(64) CHARACTER SET utf8;
    DECLARE c CURSOR FOR
    SELECT DISTINCT CONCAT(
        'SHOW GRANTS FOR ', user, '@', Host, ';'
    ) AS query FROM mysql.user;
    DECLARE EXIT HANDLER FOR NOT FOUND BEGIN END;  
    OPEN c;
    WHILE TRUE DO
        FETCH c INTO v;
        SET @v = v;
        PREPARE stmt FROM @v;
        EXECUTE stmt;
    END WHILE;
    CLOSE c;
END

et appelez-le avec

$ mysql -p -e "CALL spShowGrants" mysql

dirigez ensuite la sortie via la commande Richards sed pour obtenir une sauvegarde des privilèges.

4
Lenny

Bien qu'il semble que la réponse de @Richard Bronosky soit la bonne, je suis tombé sur cette question après avoir essayé de migrer un ensemble de bases de données d'un serveur à un autre et la solution était beaucoup plus simple:

server1$ mysqldump -u root -p --all-databases > dbdump.sql

server2$ mysql -u root -p < dbdump.sql

À ce stade, toutes mes données étaient visibles si je me connectais en tant que root, le mysql.user table contenait tout ce que j'attendais, mais je n'ai pas pu me connecter en tant que n'importe quel autre utilisateur et j'ai trouvé cette question en supposant que je devrais ré-émettre les instructions GRANT.

Cependant, il s'avère que le serveur mysql devait simplement être redémarré pour les privilèges mis à jour dans le mysql.* tableaux pour prendre effet:

server2$ Sudo restart mysql

J'espère que cela aide quelqu'un d'autre à réaliser ce qui devrait être une tâche simple!

3
Tom

créez un fichier de script Shell avec le code suivant:

echo "SELECT DISTINCT CONCAT (\"show grants for '\", user, \"'@'\", Host, \"';\") AS query FROM mysql.user; " >   script.sql    
echo "*** You will be asked to enter the root password twice ******"    
mysql -u root -p  < script.sql > output.sql ;    
cat output.sql | grep show > output1.sql  ; rm output.sql -f ; 
mysql -u root -p  < output1.sql > output.sql ;
clear
echo "-----Exported Grants-----"    
cat  output.sql ; rm  output.sql   output1.sql -f    
echo "-------------------------"
rm  script.sql -f

**** puis exécutez-le sur le shell comme ceci: il vous sera demandé d'entrer deux fois le mot de passe root et ensuite le GRANTS SQL s'affichera à l'écran. ****

2
Rony

One-liner fait à peu près la même chose que le génial pt-show-grants:

mysql --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',Host,''';') FROM mysql.user WHERE user<>''" | mysql --skip-column-names -A | sed 's/$/;/g'

Basé uniquement sur les outils Unix, aucun logiciel supplémentaire n'est requis.

Exécutez à partir d'un shell bash, en supposant que vous disposez d'un .my.cnf où le mot de passe de votre mysql root l'utilisateur peut être lu.

0
sjas