MySQL Cluster 集群环境的备份包括了逻辑备份和物理备份,在工作中我们主要以物理备份为主,但仅仅掌握如何备份远远不够,我们还有必要掌握如何利用备份好的信息进行数据恢复。这一小节我们就来学习如何利于物理备份好的数据信息进行数据恢复。
我们先回顾一下之前讲解的几个重点内容:
- MySQL Cluster 集群环境中的数据是以分布式的方式分散存储在多个数据节点上的;
- MySQL Cluster 集群环境的物理备份是通过在管理节点的 ndb_mgm 控制台上执行 start backup 命令的方式来进行的;
- 利用 start backup 命令备份好的数据,会分别存储在每个数据节点的 BACKUP 目录下。
这 3 个重点内容,在进行数据恢复之前你一定要牢记心中。那么如何来进行数据恢复呢?
其实 MySQL Cluster 提供了专门的数据恢复工具 ndb_restore。通过这个工具,我们可以将利用 start backup 目录备份好的数据进行恢复处理,还可以实现部分表、部分数据库的恢复,以及全部数据的恢复。
接下来,我们来演示一下如何用 ndb_restore 工具进行数据恢复(注意,ndb_restore 工具是使用在MySQL Cluster 集群环境的数据节点上)。
模拟测试数据
在演示数据恢复前,我们先模拟些测试数据,在 testdb 数据库下创建一张 t1 表并插入一些样例数据。
mysql> create database testdb; Query OK, 1 row affected (0.03 sec) mysql> use testdb; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> create table t1 (id int,name char(10)) engine=ndb; Query OK, 0 rows affected (0.16 sec) mysql> insert into t1 values(1,'a'),(2,'b'),(3,'c'); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from t1; +------+------+ | id | name | +------+------+ | 1 | a | | 3 | c | | 2 | b | +------+------+ 3 rows in set (0.00 sec)
然后对现有的数据做一个备份。
ndb_mgm> start backup 1; Waiting for completed, this may take several minutes Node 2: Backup 1 started from node 1 Node 2: Backup 1 started from node 1 completed StartGCP: 80383 StopGCP: 80386 #Records: 2071 #LogRecords: 0 Data: 52708 bytes Log: 0 bytes
在备份作业完成后,再将表 testdb.t1 删除掉。
mysql> drop table testdb.t1; Query OK, 0 rows affected (0.07 sec)
接下来,我们利用刚才备份好的数据进行恢复。
进行数据恢复
在做数据恢复之前,有一点大家要格外注意的是:因为ndb_restore 在进行数据恢复时,要连接 mysqld服务,但是目前没有空闲的 mysqld 服务,在执行 ndb_restore 时会报如下的错误:
[mysql@mysql06 BACKUP-1]$ ndb_restore -n 2 -b 1 -r -m --backup_path=/mysql/mydata/BACKUP/BACKUP-1/ Nodeid = 2 Backup Id = 1 backup path = /mysql/mydata/BACKUP/BACKUP-1/ 2022-03-27 09:10:19 [restore_metadata] Read meta data file header Opening file '/mysql/mydata/BACKUP/BACKUP-1/BACKUP-1.2.ctl' File size 21920 bytes Backup version in files: ndb-6.3.11 ndb version: mysql-5.7.36 ndb-7.6.20 2022-03-27 09:10:19 [restore_metadata] Load content Start GCP of Backup: 79709 Stop GCP of Backup: 79712 2022-03-27 09:10:19 [restore_metadata] Get number of Tables 2022-03-27 09:10:19 [restore_metadata] Validate Footer Configuration error: Error: Could not alloc node id at 192.168.1.3 port 1186: Connection done from wrong host ip 192.168.1.6. Failed to initialize consumers
所以我们需要对管理节点的配置文件稍作更改,添加一个空闲的 mysqld 服务,也就是在 config.ini 中添加一个空的[mysqld]段。具体如下所示:
[mysql@mysql03 mysql]$ more config.ini [ndbd default] NoOfReplicas=2 DataMemory=200M [ndb_mgmd] hostname=192.168.1.3 datadir=/mysql/mydata [ndbd] hostname=192.168.1.6 datadir=/mysql/mydata [ndbd] hostname=192.168.1.7 datadir=/mysql/mydata [mysqld] hostname=192.168.1.4 [mysqld] hostname=192.168.1.5 [mysqld]
在修改好 config.ini 配置文件后,我们可以将管理节点的服务重启,或者执行 reload 命令使其配置信息生效。如下命令所示:[mysql@mysql03 ~]$ ndb_mgmd -f /usr/local/mysql/config.ini --reload
然后我们要确保在 ndb_mgm 控制台上可以查看到空闲的 mysqld 服务。
ndb_mgm> show; Cluster Configuration [ndbd(NDB)] 2 node(s) id=2 @192.168.1.6 (mysql-5.7.36 ndb-7.6.20, Nodegroup: 0, *) id=3 @192.168.1.7 (mysql-5.7.36 ndb-7.6.20, Nodegroup: 0) [ndb_mgmd(MGM)] 1 node(s) id=1 @192.168.1.3 (mysql-5.7.36 ndb-7.6.20) [mysqld(API)] 3 node(s) id=4 @192.168.1.4 (mysql-5.7.36 ndb-7.6.20) id=5 @192.168.1.5 (mysql-5.7.36 ndb-7.6.20) id=6 (not connected, accepting connect from any host)
这时,我们就可以进行数据恢复了。首先在第一个数据节点(mysql06)上执行 restore 命令进行数据恢复操作。
[mysql@mysql06 BACKUP]$ ndb_restore -n 2 -b 1 -r -m --backup_path=/mysql/mydata/BACKUP/BACKUP-1/ --include-tables=testdb.t1
我们对上面执行的命令进行一个解读:
- -n 表示是对哪个数据节点进行恢复,后面的 2 指的是数据节点的 nodeid 值。
- -b 表示是利用哪个备份信息来进行数据恢复,后面的 1 指的是 backup-id。
- -r 表示进行数据内容的恢复。
- -m 表示进行对象结构的恢复。
- --backup_path 表示备份信息存放的目录。
- --include-tables 表示只对哪个表对象进行恢复。
然后会输出一些日志信息。
Nodeid = 2 Backup Id = 1 backup path = /mysql/mydata/BACKUP/BACKUP-1/ Including tables: testdb.t1 2022-03-27 09:30:12 [restore_metadata] Read meta data file header Opening file '/mysql/mydata/BACKUP/BACKUP-1/BACKUP-1.2.ctl' File size 23124 bytes Backup version in files: ndb-6.3.11 ndb version: mysql-5.7.36 ndb-7.6.20 2022-03-27 09:30:12 [restore_metadata] Load content Start GCP of Backup: 80383 Stop GCP of Backup: 80386 2022-03-27 09:30:12 [restore_metadata] Get number of Tables 2022-03-27 09:30:12 [restore_metadata] Validate Footer Connected to ndb!! 2022-03-27 09:30:13 [restore_metadata] Restore objects (tablespaces, ..) 2022-03-27 09:30:13 [restore_metadata] Restoring tables Successfully restored table `testdb/def/t1` Successfully restored table event REPL$testdb/t1 2022-03-27 09:30:13 [restore_metadata] Save foreign key info Create foreign keys Create foreign keys done 2022-03-27 09:30:13 [restore_data] Start restoring table data 2022-03-27 09:30:13 [restore_data] Read data file header Opening file '/mysql/mydata/BACKUP/BACKUP-1/BACKUP-1-0.2.Data' File size 27192 bytes 2022-03-27 09:30:13 [restore_data] Restore fragments _____________________________________________________ Processing data in table: mysql/def/NDB$BLOB_7_3(8) fragment 0 Skipping fragment _____________________________________________________ Processing data in table: mysql/def/ndb_index_stat_sample(5) fragment 0 Skipping fragment _____________________________________________________ Processing data in table: sys/def/NDB$EVENTS_0(3) fragment 0 Skipping fragment _____________________________________________________ Processing data in table: mysql/def/ndb_apply_status(9) fragment 0 Skipping fragment _____________________________________________________ Processing data in table: testdb/def/t1(11) fragment 0 _____________________________________________________ Processing data in table: mysql/def/ndb_index_stat_head(4) fragment 0 Skipping fragment _____________________________________________________ Processing data in table: testdb/def/tt1(10) fragment 0 Skipping fragment _____________________________________________________ Processing data in table: sys/def/SYSTAB_0(2) fragment 0 Skipping fragment _____________________________________________________ Processing data in table: mysql/def/ndb_schema(7) fragment 0 Skipping fragment 2022-03-27 09:30:13 [restore_log] Read log file header Opening file '/mysql/mydata/BACKUP/BACKUP-1/BACKUP-1.2.log' File size 52 bytes 2022-03-27 09:30:13 [restore_log] Restore log entries Restored 2 tuples and 0 log entries
我们可以对这个日志信息进行自行解读,只要没有报错信息输出,就说明这个数据节点的数据恢复成功了。然后我们现在查看一下 testdb.t1 表的数据是否已恢复。
mysql> select * from testdb.t1; +------+------+ | id | name | +------+------+ | 3 | c | | 2 | b | +------+------+ 2 rows in set (0.00 sec)
我们可以看到,当前恢复完成的表 t1 只要两条数据,那么就说明 id=1 的那条数据是存放在第二个数据节点(mysql07)上的。接下来我们再继续进行数据恢复。
登录到第二个数据节点(mysql07)上执行ndb_restore 命令,如下所示:
[mysql@mysql07 BACKUP]$ ndb_restore -n 3 -b 1 -r --backup_path=/mysql/mydata/BACKUP/BACKUP-1/ --include-tables=testdb.t1
你可以看到,在 mysql07 节点上执行的 ndb_restore 命令和在 mysql06 节点上执行的 ndb_restore 命令有一些区别, 少了一个 -m 的参数,为什么呢?
我们刚才讲到,-m 参数指的是对象结构的恢复,因为在 mysql06 上已经恢复了表结构,所以在mysql07 上就不再需要表结构恢复了,还有 -n 参数变为了3,即 mysql07 的 nodeid 值是 3。然后同样会有一些日志信息的输出。
Nodeid = 3 Backup Id = 1 backup path = /mysql/mydata/BACKUP/BACKUP-1/ Including tables: testdb.t1 2022-03-27 09:31:26 [restore_metadata] Read meta data file header Opening file '/mysql/mydata/BACKUP/BACKUP-1/BACKUP-1.3.ctl' File size 23124 bytes Backup version in files: ndb-6.3.11 ndb version: mysql-5.7.36 ndb-7.6.20 2022-03-27 09:31:26 [restore_metadata] Load content Start GCP of Backup: 80383 Stop GCP of Backup: 80386 2022-03-27 09:31:26 [restore_metadata] Get number of Tables 2022-03-27 09:31:26 [restore_metadata] Validate Footer Connected to ndb!! 2022-03-27 09:31:27 [restore_metadata] Restore objects (tablespaces, ..) 2022-03-27 09:31:27 [restore_metadata] Restoring tables 2022-03-27 09:31:27 [restore_metadata] Save foreign key info 2022-03-27 09:31:27 [restore_data] Start restoring table data 2022-03-27 09:31:27 [restore_data] Read data file header Opening file '/mysql/mydata/BACKUP/BACKUP-1/BACKUP-1-0.3.Data' File size 26116 bytes 2022-03-27 09:31:27 [restore_data] Restore fragments _____________________________________________________ Processing data in table: mysql/def/NDB$BLOB_7_3(8) fragment 1 Skipping fragment _____________________________________________________ Processing data in table: mysql/def/ndb_index_stat_sample(5) fragment 1 Skipping fragment _____________________________________________________ Processing data in table: sys/def/NDB$EVENTS_0(3) fragment 1 Skipping fragment _____________________________________________________ Processing data in table: mysql/def/ndb_apply_status(9) fragment 1 Skipping fragment _____________________________________________________ Processing data in table: testdb/def/t1(11) fragment 1 _____________________________________________________ Processing data in table: mysql/def/ndb_index_stat_head(4) fragment 1 Skipping fragment _____________________________________________________ Processing data in table: testdb/def/tt1(10) fragment 1 Skipping fragment _____________________________________________________ Processing data in table: sys/def/SYSTAB_0(2) fragment 1 Skipping fragment _____________________________________________________ Processing data in table: mysql/def/ndb_schema(7) fragment 1 Skipping fragment 2022-03-27 09:31:27 [restore_log] Read log file header Opening file '/mysql/mydata/BACKUP/BACKUP-1/BACKUP-1.3.log' File size 52 bytes 2022-03-27 09:31:27 [restore_log] Restore log entries Restored 1 tuples and 0 log entries
这时,我再回到 SQL 节点上查看下表 testdb.t1 表的数据恢复情况。
mysql> select * from testdb.t1; +------+------+ | id | name | +------+------+ | 1 | a | | 3 | c | | 2 | b | +------+------+ 3 rows in set (0.00 sec)
发现,testdb1 表中的数据就全部被恢复出来了。
以上就是 MySQL Cluster 集群环境中数据恢复的方法演示。在工作中,我们除了像上面演示的一样,对部分表数据进行恢复,还可以对全部数据库下的数据进行恢复。
不过你要注意,恢复全部数据前,需要清理现有数据,即需要在每个数据节点上执行 ndbd --initial 操作,进行初始化。其他的操作和上面演示的没有什么区别,在这里就不进行演示了。
这一小节的内容就讲到这里,最后我们来总结一下在数据恢复时可能容易出错的地方:
- 恢复前,需要修改管理节点的配置文件,添加空闲的 [mysqld] 段,并使其生效;
- 在数据恢复时,只有在第一个数据节点上执行的恢复命令需要加 -m 参数,其他数据节点上不需要加;
- 恢复全部数据前,需要对每个数据节点进行初始化操作。
总的来说,我们要多多练习 MySQL Cluster 集群环境的备份恢复操作,只有操作多了之后,才能对可能遇到的错误了然于心,在工作中才能做到得心应手。