Copia de seguridad / Restaurar usuarios / Contraseñas / Privilegios

16

Me estoy mudando de un servidor a otro y quiero hacer una copia de seguridad de todas las bases de datos + usuarios / privilegios / contraseñas de mi servidor MySQL. Encontré hacer una copia de seguridad de una base de datos usando mysqldump, pero no puedo entender, cómo hacer una copia de seguridad de todos los usuarios y los privilegios otorgados. ¿Hay alguna manera de lograr esto o tengo que configurar esto recientemente en el nuevo servidor?

Nidhoegger
fuente
¿Está moviendo los datos a otro servidor que ejecute la misma versión de MySQL?
RolandoMySQLDBA

Respuestas:

16

La base de datos 'mysql' contiene usuarios / privilegios / contraseñas. Así que tome el volcado de la base de datos mysql junto con otras bases de datos

mysqldump [options] --all-databases > all_databases_dump.sql

mysqldump -u root -p mysql user > user_table_dump.sql

Estas tablas de base de datos mysql contienen información de concesión

usuario: cuentas de usuario, privilegios globales y otras columnas sin privilegios.

db: privilegios a nivel de base de datos.

tables_priv: privilegios a nivel de tabla.

columnas_priv: privilegios a nivel de columna.

procs_priv: procedimiento almacenado y privilegios de función.

Después de restaurar la verificación cruzada con

select Host, user, password from user ;

SHOW GRANTS FOR 'user'@'localhost';
Koustuv Chatterjee
fuente
77
Precaución. Si va a cargar esto en una versión más nueva de MySQL, el volcado de mysql.userpuede fallar debido a cambios en el esquema.
Rick James
1
@ RickJames: ¿qué debemos hacer si queremos migrar a una versión más nueva y restaurar a los usuarios?
brunoqc
1
mysql_upgradees un script para encargarse de los cambios de esquema. Pero espera que realice un cambio importante a la vez, y en el lugar, no recargue. Investigarlo. (Lo siento, no tengo experiencia en el área de actualizaciones.)
Rick James
1
Después de la restauración, es posible que también necesite flush privileges;en el nuevo mysql. Like mysql -u root -p -e'flush privileges;' This también puede / establecerá su contraseña de root mysql en su nuevo servidor para que sea la contraseña de root de su antiguo servidor, así que asegúrese de saber cuál es.
Meesern
0

Este script PHP se inspiró en la necesidad de hacer lo mismo que la pregunta original donde los servidores en cuestión ejecutaban versiones diferentes de MariaDB. Como es PHP, debería funcionar en cualquier plataforma que admita PHP (versión 7.3 o superior).

<?php
ini_set('display_errors','1');
ini_set('display_startup_errors','1');
error_reporting(E_ALL);

//
// You will want to modify the 4 variables below for your environment
//

$dbuser       = 'root';                   // DB user with authority to SHOW GRANTS from mysql.user
$dbpassword   = 'blahblah';               // password for the DB user
$useroutfile  = '/temp/Users.sql';        // where to write the user file that may be imported on new server
$grantoutfile = '/temp/Grants.sql';       // where to write the grant file that may be imported on new server
$ignore_users = ['root','replication_user'];  // array of users that should NOT be exported

//
// There really should not be any reason to modify anything below this comment 
// but please do browse through it and understand what is being done
//

$dsn = 'mysql:host=localhost;charset=utf8mb4';
$opt = [PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION ,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC       ,
        PDO::ATTR_EMULATE_PREPARES   => true                   ,
       ];
try {

    $ourdb = new PDO ($dsn,$dbuser,$dbpassword,$opt);

} catch (PDOException $e) {

    error_log($e);  // log the error so it may be looked at later if necessary
    echo 'Could not connect to the SQL server';
    exit;
}  // end of the try/catch block

$notuser = implode(',',array_map('add_quotes',$ignore_users));

//
// We got connected to the database so now let's make sure we can open the
// output files for writing - note that using mode w will overwrite any
// existing files so we'll always start off cleanly
//

$userout = fopen($useroutfile,'w');

if ($userout === false) {  // could not open the output file for writing for some reason

    error_log('Could not open the output file for writing (' . $useroutfile . ')');
    exit;

}  // end of if we could not open the output file for writing

$grantout = fopen($grantoutfile,'w');

if ($grantout === false) {  // could not open the output file for writing for some reason

    error_log('Could not open the output file for writing (' . $grantout . ')');
    exit;

}  // end of if we could not open the output file for writing

$Query = $ourdb->query("
    SELECT CONCAT('SHOW GRANTS FOR ''', user, '''@''', host, ''';') AS query 
           FROM mysql.user 
           WHERE user NOT IN(" . implode(',',array_map('add_quotes',$ignore_users)) . ")
");
$users = $Query->fetchAll(PDO::FETCH_COLUMN);

foreach ($users as $GrantQ) {  // go through each of the users found

    $UserQ  = $ourdb->query("$GrantQ");  // retrieve the grants for a user
    $grants = $UserQ->fetchAll(PDO::FETCH_COLUMN);

    foreach ($grants as $grant) {  // go through each of the grants found for this user

        if (stripos($grant,'IDENTIFIED BY PASSWORD') === false) {

            fwrite($grantout,$grant . ';' . PHP_EOL);  // write the command to actually do the grant

        } else {

            fwrite($userout,$grant . ';' . PHP_EOL);  // write the command to actually do the grant
}
        }  // end of foreach through the grants found

}  // end of foreach through the queries to show the grants for each user

fwrite($userout ,'FLUSH PRIVILEGES;' . PHP_EOL);  // make sure SQL knows about the new users and privileges
fwrite($grantout,'FLUSH PRIVILEGES;' . PHP_EOL);  // make sure SQL knows about the new users and privileges
fclose($userout);   // close our output file
fclose($grantout);  // close our output file
echo 'The grants for ' . count($users) . ' users were written to ' . $useroutfile . PHP_EOL;

function add_quotes($str) {return sprintf("'%s'", $str);}
Dave
fuente