最后, 如果你有更好的解决方案, 欢迎讨论交流.
技术分享 | 两个单机 MySQL 该如何校验数据一致性业务有两个 MySQL 集群是通过 MQ 进行同步的,昨晚 MQ 出现异常 , 报了很多主键冲突,想请 dba 帮忙校验一下两个集群的数据是否一致 。
当接到这个需求的时候并没当回事,隐约有点印象 pt-table-checksum 能通过 dsn 实现 MySQL 的数据校验 , 所以当时就应承下来了 。不曾想,啪啪打脸 , 回想起来真是草率了 。
本文参考的是 pt-table-checksum 的校验逻辑,基于数据块去遍历每个表,然后比对 checksum 的值判断该块是否一致,本文主要是想聊聊我在实现数据校验脚本过程中遇到的问题以及解决思路,希望对大家有帮助 。
利用线上的配置文件搭建一套主从环境 。
这个用例将通过 dsn 方式连接从库 。
这个用例将通过 dsn 方式连接从库,但是会将从库的复制链路 stop 掉,并清空复制信息 。
熟悉 pt-table-checksum 的朋友应该都知道,该工具是基于主键(非空唯一键)进行扫描数据行,其实这个逻辑针对整型单列主键实现起来很简单 , 但是如果是联合主键且是字符型,好像就没那么简单了,有兴趣的可以思考一下 。下面我先说一下大致的逻辑:
第一步:判断 _min_rowid 是否为空 , 为空就取该表的第一行,并记作 _min_rowid。
第二步:根据 _min_rowid 作为条件进行扫描该表 , 取下一个数据块的数据,记录数据块的最后一行数据的主键值,记录 checksum 的值,并记下 _min_rowid。
第三步:判断_min_rowid是否为空 , 非空重复第二步 , 为空退出检查 。
通过上述三个步骤可以看到 , 如果是单列整型的主键 , 实现起来很简单,但是问题来了,业务的表的主键五花八门,有的是联合主键,有的是字符型的联合主键,还有整型+字符型的联合主键,那么上述的实现方式显然是有问题的 。所以实现起来需要多考虑几个问题:
鉴于存在上述两个问题,可以参考如下实现逻辑:
假如有这么一个联合主键字段 primary key(a,b,c) 都是整型,该如何编写遍历 sql 呢?起初我的想法很简单 , 具体如下:
至此在编写校验脚本过程遇到的两个问题就算告一段落了 , 剩下的就是各种逻辑处理了,不过多赘述,有兴趣的可以自行阅读脚本文件 。
本着最低程度影响业务,所以取消加锁逻辑 。但是又要保证该数据块的数据一致性,如果这个数据块是个热数据 , 当前正在变更,那么校验的时候难免会不一致 。所以只能通过多次校验实现,默认是校验20次,其中有一次校验结果是一致,就认为是一致的,如果前5次校验过程中 , 这个数据块的数据没有变化,也视为不一致(可能是因为延迟,也可能是真的不一致) 。
pt-table-checksum 不校验表结构 , 改写时添加表结构的校验 。
可以基于表的并行校验 , 可由用户指定并行数 , 但是脚本有个安全机制 , 如果用户指定的并行数大于当前 cpu 空闲核心数,就会按当前(空闲核心数-1)作为并行数 。
添加网络监控,由用户指定网络上限百分比,当网卡流量超过这个百分比就暂停任务,等待网卡流量低于阈值才会继续任务 。这个主要是出于对于中间件(mycat)的场景或者分布式数据库(tidb)的场景 。
支持定时任务功能,用户可以使用这个功能规避业务高峰,仅在业务低峰进行数据校验 。
不仅限于主从节点的校验,只要目标对象支持 MySQL 的标准 SQL 语法就能做数据校验 。
推荐阅读
- 新颖的毕业设计网站,毕业设计网站制作
- 关于什么叫正版印度舞蹈视频的信息
- 在电商平台如何变更收货人,收货人如何更改收货地址
- 快手直播签约设置不了,快手直播不签约怎么提成的?
- python截屏函数 python pil截图
- 小程序开发用哪个,小程序开发哪个平台好
- 解谜游戏阴阳先生,阴阳先生的奇闻异事
- u盘装系统系统是什么格式,u盘装系统好用
- php7数据类型 php常用数据类型的语法格式