VPN 中断后的 MySQL 复制:先读两个阶段
路径中断不等于事务丢失。分别读取接收端与应用端,再核对源端还保留了哪些内容。
VPN 一断,复制监控就变红,人的第一反应是重置位置。正是这个反应,把一次网络中断变成了数据问题。中断的路径并不能说明副本收到了什么、应用了什么,而这是两个阶段、两种状态。动手改动之前,先把两者分开读。
两个阶段,两个独立答案
常规的异步副本做两件事。接收端连接源端,拉取事件并在本地写入中继日志。应用端读取该日志,在副本上执行事件。路径一断,接收端立即停下,而应用端仍在把磁盘上已有的积压处理完。因此一次中断会带来两个不同的问题:连接是否恢复,以及积压的工作是否已应用?把两者当成一个问题,就会把两种状态平均成一个误导性的答案。
接收端恢复,只说明路径通了。它没有说明应用端落后多少,也没有说明断开期间是否遇到了错误。
用正确的语句读通道
在 MySQL 8.4 中,SHOW REPLICA STATUS 为每个已配置的通道返回一行,所以要读你关心的那个通道,而不是列表里的第一行。Replica_IO_Running 区分已连接的接收端与正在连接或已停止的接收端,Replica_SQL_Running 描述应用端。还要一起读旁边的错误列,因为重连后立刻失败的接收端会留下一条任何状态标志都不会显示的消息。旧版本使用不同的列名,所以不要只改命令名就来翻译旧配方。
也要检查源端身份和已配置的过滤条件。指向错误源端、或过滤范围比你以为更窄的副本,会一边报告健康,一边复制着你并不预期的内容。
为什么零延迟的数字会说谎
延迟值把最后一条已应用事件的时间戳与当前时间相比较。当接收端停了一小时,应用端可能把积压处理完,走到已接收内容的末尾,此时数字就掉到零,尽管副本仍比源端晚一小时。这个指标衡量的是应用端的队列,而不是副本的时效。
改为把已执行的事务与源端现有的内容作比较。这种比较在接收端卡住时依然成立。
真正决定恢复窗口的是保留期
要追上,源端必须仍保留副本所需的事务。一旦这些事务被清理,副本就取不到,再怎么重连也改变不了。
使用 GTID 自动定位时,失败是明确的:副本请求源端已不再保留的历史,并拒绝继续。此时的选择是:从仍有这些事件的源端取回缺失部分,或从备份重建再让它追上。跳过缺口不是追上,它会留下一个数据悄悄不完整的副本。请把预期中断时长与源端的二进制日志保留期、变更速率作比较来规划窗口,因为这三个数字决定了这次中断究竟能不能恢复。
验证是否追上,而不是看指示灯的颜色
恢复路径,包括名称解析与传输安全,然后观察现有通道是否按其自身策略重连。在介入之前给它一个确定的间隔,并记录该间隔两端接收与应用的进度。重新启动的通道和已经最新的通道,是两个不同的结论。
确认应用端已到达源端的当前位置,而不仅仅是旧积压的末尾。还要确认应用端没有待处理的错误,因为一个失败事件就会让进度停住,而接收端仍继续报告已连接。然后记录证据:通道名、两个阶段的状态、已执行的位置和时间。绿色指示灯是主张,位置才是事实。