Kopia zapasowa / przywracanie użytkowników / haseł / uprawnień

16

Przechodzę z jednego serwera na drugi i chcę wykonać kopię zapasową wszystkich baz danych + użytkowników / uprawnień / haseł z mojego serwera MySQL. Znalazłem kopię zapasową bazy danych przy użyciu mysqldump, ale nie mogę zrozumieć, jak wykonać kopię zapasową wszystkich użytkowników i przyznanych uprawnień. Czy istnieje sposób, aby to osiągnąć, czy też muszę to skonfigurować na nowym serwerze?

Nidhoegger
źródło
Czy przenosisz dane na inny serwer z tą samą wersją MySQL?
RolandoMySQLDBA

Odpowiedzi:

16

Baza danych „mysql” zawiera użytkowników / uprawnienia / hasła. Zrób zrzut bazy danych mysql wraz z innymi bazami danych

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

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

Te tabele bazy danych mysql zawierają informacje o grantach

użytkownik: konta użytkowników, uprawnienia globalne i inne kolumny inne niż uprawnienia.

db: uprawnienia na poziomie bazy danych.

tables_priv: uprawnienia na poziomie tabeli.

column_priv: uprawnienia na poziomie kolumny.

procs_priv: Procedury składowane i uprawnienia funkcji.

Po przywróceniu sprawdź krzyż z

select Host, user, password from user ;

SHOW GRANTS FOR 'user'@'localhost';
Koustuv Chatterjee
źródło
7
Uwaga. Jeśli będziesz ładować to do nowszej wersji MySQL, zrzut mysql.usermoże się nie powieść z powodu zmian schematu.
Rick James
1
@RickJames: co powinniśmy zrobić, jeśli chcemy przeprowadzić migrację do nowszej wersji i przywrócić użytkowników?
brunoqc
1
mysql_upgradeto skrypt, który zajmuje się zmianami schematu. Ale oczekuje się, że dokonasz tylko jednej ważnej zmiany na raz i na miejscu, a nie przeładowywania. Zbadaj to. (Przepraszam, nie mam doświadczenia w zakresie aktualizacji.)
Rick James
1
Po przywróceniu możesz / będziesz także potrzebować flush privileges;nowego mysql. Podobnie jak mysql -u root -p -e'flush privileges;' To może / spowoduje również ustawienie hasła root mysql na nowym serwerze jako hasła roota ze starego serwera, więc upewnij się, że wiesz, co to jest.
meesern
0

Ten skrypt PHP został zainspirowany potrzebą zrobienia tego samego, co oryginalne pytanie, na których serwerach działała inna wersja MariaDB. Ponieważ jest to PHP, powinno działać na każdej platformie obsługującej PHP (wersja 7.3 lub wyższa).

<?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
źródło