第11章:建立一条能够被业务查询证明的异步复制
复制教程常以SHOW REPLICA STATUS中两个Yes结束。那说明线程处于某种运行状态,却没有证明业务数据已经到达,也没有证明初始化方式正确。本书从空实例建立GTID复制,在表结构和交易写入之后再核对完整账本,让通道状态与业务结果形成同一个可检查的过程。
账户与网络先就绪
源创建专用复制账户,授予REPLICATION SLAVE权限。账户只用于读取复制流,不承担应用写入。源和副本位于任务私有bridge网络,通过source别名连接,没有对外发布端口。公开教学口令与GET_SOURCE_PUBLIC_KEY只适合这个隔离环境,生产应使用受控凭据和经过验证的TLS配置。
副本配置源主机、复制账户、自动定位和重连间隔,启动通道,再开启super_read_only。只读限制使应用式写入不能偷偷修改副本;复制线程具有特殊执行路径,仍能应用源变化。实际机制应以当前版本文档为准,不要把普通客户端能否写入与复制是否能应用混成同一个权限问题。
为什么在建业务表之前复制
源和副本此时都没有ledger业务库,所以复制可以从源的事务历史开始建立,不需要先处理大规模数据装载。随后建库建表、写入初始订单与填充表,副本都通过同一复制通道取得。这个选择降低了教学复杂度,却不等于现有生产大库可以忽略初始备份。
若要给已有源增加副本,需要一致初始数据及与之匹配的坐标或GTID集合。先随便导出,再猜一个当前水位,会在导出期间形成缺失或重复范围。第五章的一致快照为这种需求提供概念基础,但本书没有将那条恢复路径直接用于生产副本初始化,因此不能把实验结果推广成完整迁移方案。
建立成功包含三步
第一步是通道启动且没有立即出错。第二步是等待源指定GTID集合在副本执行,确保验证查询的时间点足够晚。第三步是源与副本state完全相同,包括全部订单行、余额与分录校验。只有第三步直接回答了本书关心的业务结果。
如果等待超时,应查看连接、认证、源日志保留和应用错误,而不是反复执行START REPLICA掩盖原因。如果业务摘要不一致,即使线程仍在运行也应中止后续切换实验。将失败留在首次出现的位置,能保存更准确的诊断信息,避免错误被之后的新订单冲淡。
复制状态需要解释条件
接收线程可能已连接,却没有新事件;应用线程可能在运行,却被一个大事务拖住。Seconds_Behind_Source的数值也依赖连接、事件时间和应用进度等条件,不能独自解释为所有业务请求的新鲜度。网络中断时某些观测不代表一个可靠的实时延迟上界。
本书不依靠单个延迟秒数做断言,而是安排一个具体订单,观察它何时在副本出现,以及对应GTID是否执行。生产可以用业务心跳、水位与应用查询共同监控,但心跳也只是某条路径的代表。跨库或并行复制时,还应确认所选择的水位确实覆盖需要一致读取的事务范围。
只读是正常状态,不是故障
副本开启super_read_only后,普通业务写入应被拒绝。这个状态防止意外漂移,也为之后的提升提供明确前置条件。读服务仍可能正常工作,不能把连接成功理解成可承接写服务。客户端路由应知道实例角色,避免写请求随机落到副本后由应用盲目重试到其他地址。
拥有管理权限的账户可以改变角色,因此权限管理和控制面同样重要。本书用root执行管理编排,订单写入与只读负例使用仅有账本增删改查权限的ledger_app,并记录SHOW GRANTS,避免管理员绕过read_only掩盖角色错误。生产需要把复制管理、备份读取、应用写入和审计权限分离,并演练凭据轮换后复制是否仍可恢复连接。
复制保护与备份保护叠加
有了可用副本,我们仍保留独立快照和日志归档。因为副本会同步合法错误,归档可能帮助历史恢复;副本提供较新的在线状态,又可能缩短主机故障后的服务恢复时间。两条路径相互补充,但各自都有验收条件。下一章将主动暂停应用,观察“源已提交”和“副本已可读”之间的空隙如何出现并消失。