Haruskah saya membuat cadangan dan memulihkan basis data `mysql`?

15

Dalam proses menciptakan solusi otomatis untuk membuat cadangan dan memulihkan seluruh server MySQL , saya telah menemukan mysqldatabase yang tampaknya berisi akun pengguna, izin, metadata, hal semacam itu. Haruskah basis data ini didukung? Akankah mencadangkan dan mencoba mengembalikannya merusak?

Aku punya waktu Googling untuk "mysql mencadangkan database mysql" seperti yang dapat Anda bayangkan.

Daniel Beardsley
sumber
3
Untuk melakukan pengembalian penuh, Anda harus mencadangkan semuanya kecuali database "information_schema".
John Gardeniers

Jawaban:

16

Berikut ini sesuatu yang menarik untuk dipertimbangkan: Mencadangkan mysqlbasis data sangat membatasi Anda karena Anda hanya dapat mengembalikan basis data tersebut ke versi mysql yang sama dengan tempat Anda menjalankan pencadangan. Inilah alasannya:

Berikut ini adalah mysql.user dari MySQL 5.0.45

mysql> desc mysql.user;
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field                 | Type                              | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host                  | char(60)                          | NO   | PRI |         |       |
| User                  | char(16)                          | NO   | PRI |         |       |
| Password              | char(41)                          | NO   |     |         |       |
| Select_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Delete_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Create_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Drop_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Reload_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Shutdown_priv         | enum('N','Y')                     | NO   |     | N       |       |
| Process_priv          | enum('N','Y')                     | NO   |     | N       |       |
| File_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Grant_priv            | enum('N','Y')                     | NO   |     | N       |       |
| References_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Index_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Alter_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Show_db_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Super_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Create_tmp_table_priv | enum('N','Y')                     | NO   |     | N       |       |
| Lock_tables_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Execute_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Repl_slave_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Repl_client_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Create_view_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Show_view_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Create_routine_priv   | enum('N','Y')                     | NO   |     | N       |       |
| Alter_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |
| Create_user_priv      | enum('N','Y')                     | NO   |     | N       |       |
| ssl_type              | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |
| ssl_cipher            | blob                              | NO   |     |         |       |
| x509_issuer           | blob                              | NO   |     |         |       |
| x509_subject          | blob                              | NO   |     |         |       |
| max_questions         | int(11) unsigned                  | NO   |     | 0       |       |
| max_updates           | int(11) unsigned                  | NO   |     | 0       |       |
| max_connections       | int(11) unsigned                  | NO   |     | 0       |       |
| max_user_connections  | int(11) unsigned                  | NO   |     | 0       |       |
+-----------------------+-----------------------------------+------+-----+---------+-------+
37 rows in set (0.01 sec)

Berikut ini adalah mysql.user dari MySQL 5.1.32

mysql> desc mysql.user;
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field                 | Type                              | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host                  | char(60)                          | NO   | PRI |         |       |
| User                  | char(16)                          | NO   | PRI |         |       |
| Password              | char(41)                          | NO   |     |         |       |
| Select_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Delete_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Create_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Drop_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Reload_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Shutdown_priv         | enum('N','Y')                     | NO   |     | N       |       |
| Process_priv          | enum('N','Y')                     | NO   |     | N       |       |
| File_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Grant_priv            | enum('N','Y')                     | NO   |     | N       |       |
| References_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Index_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Alter_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Show_db_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Super_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Create_tmp_table_priv | enum('N','Y')                     | NO   |     | N       |       |
| Lock_tables_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Execute_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Repl_slave_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Repl_client_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Create_view_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Show_view_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Create_routine_priv   | enum('N','Y')                     | NO   |     | N       |       |
| Alter_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |
| Create_user_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Event_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Trigger_priv          | enum('N','Y')                     | NO   |     | N       |       |
| ssl_type              | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |
| ssl_cipher            | blob                              | NO   |     | NULL    |       |
| x509_issuer           | blob                              | NO   |     | NULL    |       |
| x509_subject          | blob                              | NO   |     | NULL    |       |
| max_questions         | int(11) unsigned                  | NO   |     | 0       |       |
| max_updates           | int(11) unsigned                  | NO   |     | 0       |       |
| max_connections       | int(11) unsigned                  | NO   |     | 0       |       |
| max_user_connections  | int(11) unsigned                  | NO   |     | 0       |       |
+-----------------------+-----------------------------------+------+-----+---------+-------+
39 rows in set (0.00 sec)

Berikut ini adalah mysql.user dari MySQL 5.5.12

mysql> desc mysql.user;
+------------------------+-----------------------------------+------+-----+---------+-------+
| Field                  | Type                              | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+---------+-------+
| Host                   | char(60)                          | NO   | PRI |         |       |
| User                   | char(16)                          | NO   | PRI |         |       |
| Password               | char(41)                          | NO   |     |         |       |
| Select_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Delete_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Create_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Drop_priv              | enum('N','Y')                     | NO   |     | N       |       |
| Reload_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Shutdown_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Process_priv           | enum('N','Y')                     | NO   |     | N       |       |
| File_priv              | enum('N','Y')                     | NO   |     | N       |       |
| Grant_priv             | enum('N','Y')                     | NO   |     | N       |       |
| References_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Index_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Alter_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Show_db_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Super_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Create_tmp_table_priv  | enum('N','Y')                     | NO   |     | N       |       |
| Lock_tables_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Execute_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Repl_slave_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Repl_client_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Create_view_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Show_view_priv         | enum('N','Y')                     | NO   |     | N       |       |
| Create_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |
| Alter_routine_priv     | enum('N','Y')                     | NO   |     | N       |       |
| Create_user_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Event_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Trigger_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Create_tablespace_priv | enum('N','Y')                     | NO   |     | N       |       |
| ssl_type               | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |
| ssl_cipher             | blob                              | NO   |     | NULL    |       |
| x509_issuer            | blob                              | NO   |     | NULL    |       |
| x509_subject           | blob                              | NO   |     | NULL    |       |
| max_questions          | int(11) unsigned                  | NO   |     | 0       |       |
| max_updates            | int(11) unsigned                  | NO   |     | 0       |       |
| max_connections        | int(11) unsigned                  | NO   |     | 0       |       |
| max_user_connections   | int(11) unsigned                  | NO   |     | 0       |       |
| plugin                 | char(64)                          | YES  |     |         |       |
| authentication_string  | text                              | YES  |     | NULL    |       |
+------------------------+-----------------------------------+------+-----+---------+-------+
42 rows in set (0.01 sec)

Jika Anda mencoba mengembalikan mysql.user ke versi MySQL yang tidak dimaksudkan untuknya, itu akan menghasilkan masalah izin acak. Cara untuk mencadangkan izin pengguna mysql dalam cara versi-agnostik adalah dengan membuang hibah pengguna dalam SQL. Dengan begitu, hibah pengguna sepenuhnya portabel. Ada dua cara untuk mencapai ini:

OPSI # 1: Menggunakan MAATKIT

mk-show-grants akan menghasilkan SQL yang dibutuhkan apa pun contoh mysql yang Anda sambungkan. (Perlu diingat bahwa MAATKIT sedang dimigrasi ke Percona Toolkit. Alat ini kemungkinan besar akan disebut pt-show-grants).

OPSI # 2: Script dumping dari SQL GRANTS

Saya telah menulis emulasi saya sendiri dari mk-show-grants. Itu akan meninggalkan pengguna anonim. Ini terlihat seperti ini:

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

Menggunakan salah satu dari opsi ini akan membuat cadangan yang lebih stabil dari hibah pengguna.

PADA CATATAN TERPISAH

Sekarang jika Anda menggunakan opsi log-output ini

[mysqld]
log-output=TABLE

database mysql akan mengisi log lambat (jika diaktifkan) sebagai tabel mysql dalam skema mysql daripada file teks. Jadi, melakukan backup fisik akan mencakup log berbasis tabel mysql tersebut. Percayalah, itu tidak sebanding dengan ruang disk jika log umum dan log kueri lambat diaktifkan dan menumpuk di skema mysql. Tetap gunakan Opsi Dump MySQL Grants.

UPDATE 2011-09-19 15:54 EDT

Ada satu faktor yang sangat penting dalam menjaga cadangan izin MySQL melalui SQL Grants:

Setiap pengguna keluar dengan kata sandi mereka dalam beberapa format MD5 yang dimodifikasi. Untuk mysql 4.0 dan kembali, ini adalah string heksadesimal 16 karakter. Untuk mysql 4.1+, ini adalah 41 karakter (Tanda bintang diikuti oleh string heksadesimal 40 karakter).

Sebelum Anda mengembalikan dump SQL Grants, periksa file dump SQL Grants untuk kata sandi heksadesimal 16 karakter. Jika Anda melihat satu saja, Anda harus menambahkan yang berikut ini ke /etc/my.cnf (atau my.ini untuk Windows) di server mysql yang akan Anda kembalikan ke:

[mysqld]
old_password=1

The old_password direktif memungkinkan 16-char dan 41-char password untuk hidup berdampingan dan benar mengotentikasi dalam contoh menjalankan mysql yang sama. Kata sandi apa pun yang dibuat akan terdiri dari 16 karakter.

Restart MySQL tidak diperlukan. Jalankan saja ini:

SET GLOBAL old_password = 1;
RolandoMySQLDBA
sumber
+1 untuk jawaban yang lengkap.
Mircea Vutcovici
1
Saya akan lebih baik mengeja SHOW GRANTSgenerasi SQL menggunakan QUOTE(), seperti ini:SELECT CONCAT('SHOW GRANTS FOR ',QUOTE(user),'@',QUOTE(host),';') FROM mysql.user WHERE user<>'';
kostix
11

Ya, Anda pasti ingin membuat cadangan mysqlbasis data - ini merupakan bagian integral dari layanan Anda. Meskipun Anda dapat merekonstruksi kontennya dari informasi lain, kesulitan untuk melakukannya adalah penghalang jika Anda mencoba kembali ke layanan dengan cepat.

womble
sumber
1
+1 Jika Anda tidak membuat cadangan database mysql kemungkinan memiliki sistem yang rusak setelah melakukan pengembalian sangat tinggi. Pernah ke sana, melakukan itu, mendapat bekas luka mental untuk membuktikannya.
John Gardeniers
6

Anda dapat mengembalikan database mysql di antara versi, setidaknya versi yang cukup baru. Ada alat yang disebut mysql_upgradetermasuk dalam versi baru MySQL yang akan memutakhirkan tabel sistem untuk Anda.

http://dev.mysql.com/doc/refman/5.0/id/mysql-upgrade.html

HampusLi
sumber
Ini sangat benar. Saya telah melihat kasus di mana beberapa orang menggunakan ini dan memutakhirkannya dengan sempurna. Saya telah melihat orang lain membantainya. Dari sudut pandang saya sebagai DBA MySQL. Saya kehilangan kepercayaan pada metode itu. Karena jawaban Anda mencerminkan keyakinan yang kuat dalam penggunaannya, Anda harus berasal dari kelompok pertama. +1 untuk kepercayaan seperti itu di mysql_upgrade.
RolandoMySQLDBA
Ketika saya mengimpor versi 5.6 saya ke 8.0, itu borked server.
PHPst
5

Selama Anda mengembalikan ke versi mysql yang serupa, Anda dapat memulihkan dari database mysql dari cadangan. Jika Anda ragu, buat perbedaan antara skema database mysql (yang dari cadangan dan yang dari server mysql baru).

Mircea Vutcovici
sumber
+1 untuk menjadi yang pertama dalam menyebutkan memulihkan mysql ke versi yang sama dengan yang Anda buat cadangannya.
RolandoMySQLDBA