Innodb集群是有多个节点组成的,这些节点的数据是同步的。对于Innodb集群的备份,通常只需要在一个节点上进行备份。当需要恢复时,可以把备份集恢复到集群中的任意一个节点上。下面通过实验说明在同一节点和不同节点上进行恢复的方法。
实验环境
实验的集群是有3个沙箱实例组成的一个InnoDB集群,集群的成员信息如下:
mysql> select MEMBER_ID,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE,MEMBER_ROLE FROM performance_schema.replication_group_members; +--------------------------------------+-------------+-------------+--------------+-------------+ | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | +--------------------------------------+-------------+-------------+--------------+-------------+ | 79db1af9-8c9e-11ec-b19d-fa163ea83c5b | 127.0.0.1 | 3310 | ONLINE | SECONDARY | | 97421a78-8c9e-11ec-b6e3-fa163ea83c5b | 127.0.0.1 | 3320 | ONLINE | SECONDARY | | a292a14a-8c9e-11ec-ba94-fa163ea83c5b | 127.0.0.1 | 3330 | ONLINE | PRIMARY | +--------------------------------------+-------------+-------------+--------------+-------------+ 3 rows in set (0.00 sec)
备份软件使用国产的鼎甲迪备8.0。
同一个节点的恢复
在同一个节点上进行备份和恢复比较简单,例如备份在端口为3310的沙箱实例上进行,恢复也在同一个节点。在恢复过程中可以使用下面的命令启动和停止节点:
/usr/bin/mysqlsh -- dba startSandboxInstance 3310 /usr/bin/mysqlsh -- dba stopSandboxInstance 3310 --password='yaoyuan'
在选择恢复类型时注意不要选择“恢复到指定时间点”,而要选择“恢复到备份状态(最短恢复时间)”,如下图:
也就是只恢复备份集,不前滚二进制日志。这样恢复完成后,端口为3310的沙箱实例的数据落后与另外两个示例,但MySQL组复制的分布恢复特性(Distributed Recovery https://dev.mysql.com/doc/refman/8.0/en/group-replication-distributed-recovery.html ),会对落后的节点自动进行恢复,从而实现集群中所有节点的数据一致。在分布恢复完全之前,检查集群中节点的状态如下:
mysql> select MEMBER_ID,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE FROM performance_schema.replication_group_members; +--------------------------------------+-------------+-------------+--------------+ | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +--------------------------------------+-------------+-------------+--------------+ | 79db1af9-8c9e-11ec-b19d-fa163ea83c5b | 127.0.0.1 | 3310 | RECOVERING | | 97421a78-8c9e-11ec-b6e3-fa163ea83c5b | 127.0.0.1 | 3320 | ONLINE | | a292a14a-8c9e-11ec-ba94-fa163ea83c5b | 127.0.0.1 | 3330 | ONLINE | +--------------------------------------+-------------+-------------+--------------+ 3 rows in set (0.00 sec)
可以看到刚刚恢复的节点的状态是RECOVERING,待分布恢复完成后会变成ONLINE。
由于InnoDB组复制的自动容错特性,对单个节点进行恢复的过程中不需要关闭集群,这样恢复完成后也不需要执行 START GROUP_REPLICATION。
不同节点的恢复
MySQL数据库的恢复是恢复数据目录(datadir),由于InnoDB集群的各个节点之间的数据是自动同步的,因此不同节点之间的数据目录中的内容绝大部分是一致,但需要注意数据目录下的两个文件在不同节点是不同的:一个是auto.cnf文件,另一个是mysqld-auto.cnf。
auto.cnf文件
auto.cnf文件中保存着实例的UUID,不同实例的UUID是不同的,例如端口为3310的沙箱实例的UUID如下:
# cat /root/mysql-sandboxes/3310/sandboxdata/auto.cnf [auto] server-uuid=79db1af9-8c9e-11ec-b19d-fa163ea83c5b
端口为3320的沙箱实例的UUID如下:
# cat /root/mysql-sandboxes/3320/sandboxdata/auto.cnf [auto] server-uuid=97421a78-8c9e-11ec-b6e3-fa163ea83c5b
如果要把3310的备份集恢复到3320,注意要先备份3320的auto.cnf文件。在恢复完成后,启动实例之前恢复3320的auto.cnf文件。如果没有将3320节点中的auto.cnf文件中保存的UUID,再启动时错误日志中会记录到下面的错误提示:
2022-02-15T03:01:35.269051Z 0 [ERROR] [MY-011516] [Repl] Plugin group_replication reported: 'There is already a member with server_uuid 79db1af9-8c9e-11ec-b19d-fa163ea83c5b. The member will now exit the group.' 2022-02-15T03:01:38.426638Z 0 [System] [MY-011504] [Repl] Plugin group_replication reported: 'Group membership changed: This member has left the group.'
如果没有备份auto.cnf文件,也可以手工修改auto.cnf文件,3320的UUID在其他节点中也可以查到:
mysql> select instance_id,mysql_server_uuid from mysql_innodb_cluster_metadata.instances where instance_id=2; +-------------+--------------------------------------+ | instance_id | mysql_server_uuid | +-------------+--------------------------------------+ | 2 | 97421a78-8c9e-11ec-b6e3-fa163ea83c5b | +-------------+--------------------------------------+ 1 row in set (0.00 sec)
mysqld-auto.cnf 文件
mysqld-auto.cnf 文件中以JSON格式保存着持久化参数,不同节点的持久化参数是不同的。这个文件可以先手工备份,在恢复完数据目录后,再恢复这个文件的备份。也可以手工修改这个文件,根据不同的节点进行响应的调整。
总结
单实例的恢复通常有两步,第一步是恢复备份集,第二步是使用二进制日志前滚到指定的时间点。而InnoDB的集群中节点恢复实际上比单实例的恢复要简单,因为不需要执行第二步,恢复的节点的数据同步可以使用其他节点的二进制日志自动完成,这是InnoDB组复制的分布恢复特性(Distributed Recovery)。
由于集群里的节点的数据是自动同步的,只需要在一个节点上进行备份即可。恢复到不同节点时,注意在加入集群前修改auto.cnf文件的对应节点的UUID和mysqld-auto.cnf 文件中的持久化参数。