MySQL InnoDB Cluster 是 MySQL 的高可用性解决方案。它提供自动故障转移并保证零数据丢失 ( RPO=0)。
RPO:恢复点目标描述在中断期间丢失的数据量超过业务连续性计划的最大允许容差之前可能经过的时间间隔。
示例:我们的业务架构需要 RPO=2 分钟。这意味着如果出现故障,可能会丢失 2 分钟的数据。
然而,我们最近在欧洲看到了这一点,整个数据中心可能会瞬间“消失”……因此制定灾难恢复计划也很重要。
一种解决方案是拥有一个跨越多个区域的 InnoDB 集群(组复制)。但是,由于跨区域的高延迟,这通常不可行。
另一种解决方案是一个区域中的 InnoDB Cluster,将异步复制到另一个区域以进行 DR。使用异步复制意味着不可能保证RPO>0源和副本之间的零数据丢失(使用异步复制),但这对于灾难恢复来说通常已经足够了,因为它通常以秒为单位。
让我们看看如何创建这样的 DR 解决方案。此处说明的解决方案基于MySQL 8.0.23。
准备生产环境
mysql-node1> CREATE USER 'repl'@'%' IDENTIFIED BY 'password' REQUIRE SSL;
mysql-node1> GRANT REPLICATION SLAVE, BACKUP_ADMIN, CLONE_ADMIN ON 。TO 'repl'@'%';
mysql-node1> GRANT SELECT ON performance_schema.* TO 'repl'@'%';
复制
这些语句必须输入到主要成员上。
请注意一些权限,CLONE_ADMIN使用精彩的CLONE Plugin很重要。通常,当使用异步复制时,最后一个权限 ( SELECT ON performance_schema.*) 不是必需的,但我们稍后会看到为什么它在我们的案例中非常重要。
准备异步副本
在我们将用作 DR 的服务器上安装 MySQL 后,我们需要准备它作为异步副本:
mysql-replica> SET PERSIST_ONLY gtid_mode=on;
mysql-replica> SET PERSIST_ONLY 强制执行_gtid_consistency=true;
mysql-replica> 重启;
mysql-replica> 安装插件克隆 SONAME 'mysql_clone.so';
mysql-replica> SET GLOBAL clone_valid_donor_list='mysql-node1:3306';
mysql-replica> CLONE INSTANCE FROM repl@"mysql-node1":3306 IDENTIFIED BY 'password';
mysql-replica> SET PERSIST server_id=round(uuid_short()/1000000000);
复制
mysql-node1 是生产 MySQL InnoDB Cluster 的主要成员。
server_id 必须是唯一的,你可以使用任何你想要的值,在这个例子中我使用一个随机生成的 uuid_short()
异步连接故障转移
在从 InnoDB 集群使用异步复制时通过 MySQL Router使用异步复制不再是必需的!
现在最好的解决方案是使用异步连接故障转移机制。
- https://dev.mysql.com/doc/refman/8.0/en/replication-asynchronous-connection-failover.html
- https://mysqlhighavailability.com/automatic-asynchronous-replication-connection-failover/
这就是我们现在将部署的内容。首先要做的是从生产 MySQL InnoDB Cluster 中检索 Group Replication UUID:
mysql-nodeX> sql 显示全局变量,如 'group_replication_group_name'\G ******************** 1. 行 **************************** ** 变量名:group_replication_group_name 值:b2b2b6de-9ad7-11eb-88a0-020017018a7b
复制
在未来用作 DR 的异步副本上,我们可以设置自动异步故障转移:
mysql-replica> SELECT asynchronous_connection_failover_add_managed("async_from_idc",
"GroupReplication", "b2b2b6de-9ad7-11eb-88a0-020017018a7b",
"mysql-node1", 3306, "", 80, 60);
复制
对此 UDF 的调用将返回以下文本:
UDF asynchronous_connection_failover_add_managed() 执行成功。
复制
设置和启动异步复制通道
我们现在准备设置异步复制通道并启动它:
mysql-replica> 将复制源更改为 source_host='mysql-node1', source_port=3306, source_user='repl', source_password='password', source_auto_position=1, source_ssl=1, source_retry_count=3, source_connect_retry=10, source_connection_auto_failover=1 FOR CHANNEL 'async_from_idc';
复制
async_from_idc 只是一个名称,可以使用任何您想要的名称,但必须与异步连接故障转移中定义的相同。
我们可以开始复制:
mysql-replica> 启动通道“async_from_idc”的副本;
复制
现在,如果生产 MySQL InnoDB Cluster 提升一个新的 Primary 节点,异步副本也会自动更改其源!\o/
如果您需要将 DR 站点用于生产,在停止并重置异步复制通道后,一旦提升,就很容易将其“升级”到 InnoDB Cluster。
不支持设置从一个 MySQL InnoDB 集群到另一个 MySQL InnoDB 集群的异步复制通道,目前无法使用。
可观察性
也可以使用performance_schema表格来验证设置:
mysql-replica> select * from performance_schema.replication_asynchronous_connection_failover_managed\G
************************************ 1. 行 ************ *****************
CHANNEL_NAME:async_from_idc
MANAGED_NAME:b2b2b6de-9ad7-11eb-88a0-020017018a7b
MANAGED_TYPE:组复制
配置:{“Primary_weight”:80,“Secondary_weight”:60}
复制
mysql-replica> select * from performance_schema.replication_asynchronous_connection_failover\G
************************************ 1. 行 ************ *****************
CHANNEL_NAME:async_from_idc
主机:mysql-node1
端口:3306
NETWORK_NAMESPACE:
重量:80
MANAGED_NAME:b2b2b6de-9ad7-11eb-88a0-020017018a7b
************************************ 2. 行 ************ *****************
CHANNEL_NAME:async_from_idc
主机:mysql-node2
端口:3306
NETWORK_NAMESPACE:
重量:60
MANAGED_NAME:b2b2b6de-9ad7-11eb-88a0-020017018a7b
************************************* 3. 行 ************ ******************
CHANNEL_NAME:async_from_idc
主机:mysql-node3
端口:3306
NETWORK_NAMESPACE:
重量:60
MANAGED_NAME:b2b2b6de-9ad7-11eb-88a0-020017018a7b
复制
故障排除
如果还记得我在本文开头写的内容,那么复制用户的权限非常重要。如果不允许用户从performance_schema表中选择,将在错误日志中看到以下错误并且故障转移不会成功:
IO 线程无法检测源是否属于通道“async_from_idc”的源(主机:mysql-node1 端口:3306 network_namespace:)上的组多数。
复制
不要忘记,在 MySQL 8.0 中,现在也可以从performance_schema.error_log表中访问错误日志!