Sao lưu / Khôi phục người dùng / Mật khẩu / Đặc quyền


16

Tôi đang chuyển từ máy chủ này sang máy chủ khác và tôi muốn sao lưu tất cả cơ sở dữ liệu + người dùng / đặc quyền / mật khẩu từ Máy chủ MySQL của mình. Tôi tìm thấy để sao lưu cơ sở dữ liệu bằng cách sử dụng mysqldump, nhưng tôi không thể tìm ra cách sao lưu tất cả người dùng và các đặc quyền đã cho. Có cách nào để đạt được điều này hay tôi phải thiết lập cái này mới trên máy chủ mới?


Bạn có đang di chuyển dữ liệu sang một máy chủ khác chạy cùng phiên bản MySQL không?
RolandoMySQLDBA

Câu trả lời:


16

Cơ sở dữ liệu 'mysql' chứa người dùng / đặc quyền / mật khẩu. Vì vậy, hãy kết xuất cơ sở dữ liệu mysql cùng với các cơ sở dữ liệu khác

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

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

Các bảng cơ sở dữ liệu mysql chứa thông tin cấp

người sử dụng: Tài khoản người dùng, đặc quyền toàn cầu, và các cột không đặc quyền khác.

db: Đặc quyền cấp cơ sở dữ liệu.

frames_priv: Đặc quyền cấp bảng.

Cột_priv: Đặc quyền cấp cột.

procs_priv: Thủ tục lưu trữ và đặc quyền chức năng.

Sau khi khôi phục kiểm tra chéo với

select Host, user, password from user ;

SHOW GRANTS FOR 'user'@'localhost';

7
Chú ý. Nếu bạn sẽ tải cái này vào phiên bản mới hơn của MySQL, kết xuất mysql.usercó thể thất bại do thay đổi lược đồ.
Rick James

1
@RickJames: chúng ta nên làm gì nếu muốn chuyển sang phiên bản mới hơn và khôi phục người dùng?
brunoqc

1
mysql_upgradelà một kịch bản để chăm sóc các thay đổi lược đồ. Nhưng nó hy vọng bạn sẽ chỉ thực hiện một thay đổi lớn tại một thời điểm và tại chỗ, không tải lại. Nghiên cứu nó. (Xin lỗi, tôi không có kinh nghiệm trong lĩnh vực nâng cấp.)
Rick James

1
Sau khi khôi phục, bạn có thể / cũng sẽ cần flush privileges;trên mysql mới. Giống như mysql -u root -p -e'flush privileges;' Điều này có thể / cũng sẽ đặt mật khẩu mysql gốc của bạn trên máy chủ mới của bạn thành mật khẩu gốc từ máy chủ cũ của bạn, vì vậy hãy chắc chắn rằng bạn biết đó là gì.
meesern

0

Kịch bản PHP này được lấy cảm hứng từ nhu cầu thực hiện giống như câu hỏi ban đầu trong đó các máy chủ được đề cập đang chạy phiên bản khác nhau của MariaDB. Vì là PHP nên nó hoạt động trên mọi nền tảng hỗ trợ PHP (phiên bản 7.3 trở lên).

<?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);}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.