# sync-diff-inspector 的原理

__*sync-diff-inspector 原理*__
__*sync-diff-inspector 架构*__

![right](./student-guide/diagram/SyncDiffInspectorPI_aa_001_20220701.png)
-------------------------------------------------------------
第一步:首先进行表结构校验,只保留上下游都有的索引。根据表的统计信息,以索引作为范围,由多个线程（Worker）并行将表按照索引的顺序划分成若干块（chunk）。某些索引包含的列并不是 unique 属性的,可能会有大量的行拥有相同的索引值,这样 chunk 会划分的不均匀。Sync-diff-inspector 在选择索引时,会优先选择 primary key 或者 unique 的索引,其次是选择重复率最低的索引。
（比如:每张表默认的 chunkSize 为 50000 行,每张表最多划分出 10000 个 chunk）

第二步:通过 chunk channel 将 两端的 chunk 读取到负责比较和生成修改 SQL 的 Worker 准备进行并行对比。 

第三步:在数据同步过程中,一般只会出现少量的数据不一致,基于这个假定,当校验过程中,发现某个 chunk 在上下游的 checksum 不一致,可以通过二分法将原来的 chunk 划分成大小接近的两个子 chunk,对子 chunk 进行 checksum 对比,进一步缩小不一致行的可能范围。这个优化的好处在于,checksum 对比所消耗的时间和内存资源远小于逐行进行数据比对的消耗,通过 checksum 对比不断的缩小不一致行的可能范围,可以减少需要进行逐行对比的数据行,加快对比速度,减少内存损耗。并且由于每次计算 checksum 都相当于遍历一次二分后的子 chunk,理论上不考虑多次额外消耗,二分检验的开销相当于只对原 chunk 多做两次 checksum。

第四步:对于上下游的 checksum 不一致的 chunk,开始进行逐行检验。

第五步:对于不一样的行生成修复 SQL。

第六步:Diff 进程每十秒钟会记录一次断点信息,当校验程序在某个时刻发生异常退出的时候,再次运行 Sync-diff-inspector 会从最近保存的断点处继续进行校验。如果在下一次运行时,Sync-diff-inspector 的配置文件发生改变,那么 Sync-diff-inspector 会抛弃断点信息,重新进行校验。
