1.什么是errant
在主从复制中,会在主库上写入数据,接着从库复制主库写入的数据。
如果直接在从库上写入数据,从库中数据就会与主库不一致,出现 errant。
errant 问题,主从数据不一致,需要及时发现和治理。
如何判断 是否出现errant 呢?
看起来比较简单,就是判断 从库 gtid 是否比主库gtid多,如果是,则判定为errant。
但会有一种场景,如果先获取主库gtid,再获取从库gtid,由于这两个操作之间有时间差,从库会从主库复制数据,就会出现 从库的gtid 比主库的gtid多,出现误判。
调整获取主库、从库gtid的顺序,会避免这个问题。
在 Orchestrator中,会周期探测主库和从库,探测的先后顺序很难控制。
errant 的判断是如何实现的呢?
2.Orchestrator 判断errant
在 Orchestrator中,判断errant 时,是先将从库gitd中,主库相关的gtid去掉,然后再判断从库的gtid 是否比主库的git的多。
这样就避免了先后顺序问题。
如果是多层级联结构,会将所有上层主库的gtid去掉。
在代码中,计算errant分为两步。
第一步,每个实例会定义一个AncestryUUID。
-
如果实例是master,
AncestryUUID = master server uuid
-
如果实例是slave,
AncestryUUID = 「其上层 master的 AncestryUUID」 + 「slave 自身的 server uuid」
例如,
如果一个实例是级联中的最底层的从库,那么其AncestryUUID 就会包括所有上层主库的 server uuid。
例如,
A -- B -- C
则C的AncestryUUID 会 包括 A和B的 server uuid。
每个实例计算完AncestryUUID后。
第二步,作差。
将从库的Executed Gtid Set 中,把上层主库的相关的Executed Gtid Set 都去掉
(上层主库通过AncestryUUID 和自身 server uuid 判断得到)。
接着,从库自身的Executed Gtid Set 与 其主库的Executed Gtid Set 作差,结果就是errant。
作差使用的方式是:
select gtid_subtract(?, ?)
第一个参数是 从库的 gtid,第二个参数是 主库的gtid。
返回结果就是gtid errant。
另外,如果实例是co-master,
AncestryUUID = 「其上层 master的 server uuid」 + 「master 自身的 server uuid」
。
并且,作差之前,在去掉主库gtid时,也会去掉自身的uuid(因为 co-master,自身也会写入数据)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现