{{ it.name }}
{{ it.text }}
一、测试dsn
利用线上的配置文件搭建一套主从环境。
搭建步骤略
本例使用 mysql 5.7.26 进行测试
本例使用 percona-toolkit-3.2.1 进行测试1、校验主从数据一致性
这个用例将通过 dsn 方式连接从库。
Checking if all tables can be checksummed ...
Starting checksum ...
TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE
01-13T17:48:20 0 0 0 0 1 0 0.377 dbatest1.dbatest
可以看到测试通过,能正常做校验。
2、校验非主从数据一致性
这个用例将通过 dsn 方式连接从库,但是会将从库的复制链路 stop 掉,并清空复制信息。
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
mysql> reset slave all;
Query OK, 0 rows affected (0.01 sec)
mysql>
二、开发工具遇到的问题
1、解决复杂的联合主键问题
(1)查询索引失效,或者查询报错问题
熟悉 pt-table-checksum 的朋友应该都知道,该工具是基于主键(非空唯一键)进行扫描数据行,其实这个逻辑针对整型单列主键实现起来很简单,但是如果是联合主键且是字符型,好像就没那么简单了,有兴趣的可以思考一下。下面我先说一下大致的逻辑:
第一步:判断 _min_rowid 是否为空,为空就取该表的第一行,并记作 _min_rowid 。
if [ -z "${_min_rowid}" ]
then #拿出当前表的最小行id, 每次拿数据的起始行
_min_rowid="$(${mysql_comm} -NBe "select min(pk) from table")"
fi
第二步:根据 _min_rowid 作为条件进行扫描该表,取下一个数据块的数据,记录数据块的最后一行数据的主键值,记录 checksum 的值,并记下 _min_rowid 。select * from table where pk > ${_min_rowid} limit checksize #计算这个块的checksum值
_min_rowid="$(${mysql_comm} -NBe "select max(pk) from (select pk from table where pk > ${_min_rowid} order by pk limit checksize)a")" #记录下一个最小行pk值
第三步:判断 _min_rowid 是否为空,非空重复第二步,为空退出检查。if [ -z "${_min_rowid}" ]
then
break
else
continue
fi
通过上述三个步骤可以看到,如果是单列整型的主键,实现起来很简单,但是问题来了,业务的表的主键五花八门,有的是联合主键,有的是字符型的联合主键,还有整型+字符型的联合主键,那么上述的实现方式显然是有问题的。所以实现起来需要多考虑几个问题:
需要考虑主键是否是联合主键。
需要考虑主键字段的数据类型是否是整型或字符型。
获取主键字段列表,放在数组里
根据主键字段名获取字段的数据类型,放在关联数组里
根据字段的数据类型,如果是字符型就需要做特殊处理(2)如何界定每个数据块的左区间的边界
假如有这么一个联合主键字段 primary key(a,b,c) 都是整型,该如何编写遍历 sql 呢?起初我的想法很简单,具体如下:_min_rowid=(xxx,yyy,zzz)
select * from where 1 = 1 and a >= xxx and b >= yyy and c > zzz order by a,b,c limit checksize
乍一看好像逻辑没问题,但是实际跑脚本的时候发现这个逻辑不能完全扫完全表,后来经过多次测试校验,得出下面的逻辑 sql
_min_rowid=(xxx,yyy,zzz)
select * from where 1 = 1 and ((a > xxx) or (a = xxx and b > yyy) or (a = xxx and b = yyy and c > zzz)) order by a,b,c limit checksize
至此在编写校验脚本过程遇到的两个问题就算告一段落了,剩下的就是各种逻辑处理了,不过多赘述,有兴趣的可以自行阅读脚本文件。
三、数据校验工具做了哪些改动
1、取消 for update
2、支持表结构校验
3、支持基于表的并行校验
4、支持网络监控
5、支持定时任务功能
6、支持任意两个节点的校验
7、添加超时机制及自杀机制
四、数据校验工具使用介绍
1、校验逻辑
基于主键以一个块遍历数据表,比对 checksum 的值,块的大小可通过参数指定。
(1)获取该表的第一个数据块的查询 SQL 。
(2)将两个目标节点的数据块的 checksum 的值,记录到临时文件,file1 file2。
(3)比对 file1 file2 是否一致。不一致 : 重复(2)的操作,至多连续 20 次,还不一致会将该 SQL 记录到 table 目录一致 : 跳到
(4)file1 为空 : 表示该表遍历完成,直接跳到
(5)(4)获取该表的下一个数据块的查询 SQL 。(5)检查通过就跳到(7),检查不通过调到(6)。
(6)读取 table 目录校验不通过的 SQL 进行再次校验。本次校验通过也视为数据一致如果校验不通过,会将不一致的部分记录到diff目录
(7)该表校验任务结束。
2、功能介绍
检查随意两个几点的数据一致性支持表结构的校验支持并发检查,基于表的并发支持指定时间,可以规避业务高峰期支持网络监控,如果网络超过阈值可以暂停校验不支持无主键(非空唯一键)的表不支持联合主键达到四个字段及以上的表