作者: TiDBer_jYQINSnf
最近有个任务要把上游的分库分表合并后同步到下游的TiDB,鉴于我司自己个儿的同步工具只能单线程的同步一张表,效率比较低,有时候高峰期会因为同步工具的瓶颈导致延迟。当然也不是我司的同步工具特别菜,是有点水土不服,毕竟之前那个同步工具上下游都是MySQL, MySQL的延迟是肯定比TiDB低的,TiDB的优势就是连接数可以搞很多,每次查询的延迟稍微大一些。所以这个工具就不那么好使了。
决定用DM试试。
用DM有个问题:
我司数据库权限管控比较严格,不能申请LOCK TABLE 权限,这样的话DM的extra-args: “–consistency ” 只能设置为none
用这个选项倒是能先跑起来,但是心里还是没底,到底这样同步数据能不能做到一致呢?会不会在dump开始到sync期间的修改丢掉?找了一通资料也没找到会不会,好在P社的代码都是开源的,那拿出代码看看吧。
下面就跟着这个 extra-args: “–consistency none” 选项走一走,看看到底是怎么处理的。
DM的代码在tiflow里面:
https://github.com/pingcap/tiflow
代码结构也很清晰:
从 DM 的配置文件也大概能看出来,分4个部分,mydumper、loader、syncer、checker
是不是真这样对应的我也没完全读所有代码,我关心的一致性的问题,主要在于备份那一块,我就是去dumpling里面去找找。
dumpling有这么几个函数,主要关注process
忽略里面的failpoint后,代码看起来很清晰。
总的思路就是:对连接设置RR,然后开启事务,先记录binlog的位置,再dump数据,为了安全,会先开启一段时间的安全模式。
安全模式的意思是:
安全模式 (safe mode) 是 DM 在进行增量同步时候的一种运行模式,在安全模式中,DM 增量同步组件在同步 binlog event 时,将把所有
INSERT
和UPDATE
操作强制进行改写后再在下游执行。安全模式的目的是在增量同步过程中,同一条 binlog event 能够在下游被重复同步且保证幂等性,从而确保增量同步能够“安全”进行。
DM 从 checkpoint 恢复数据同步任务后,可能重复执行某些 binlog 事件而导致下述问题:
- 在进行增量同步过程中,执行 DML 的操作和写 checkpoint 的操作并不是同步的;写 checkpoint 的操作和写下游数据的操作也并不能保证原子性。因此,当 DM 异常退出时,checkpoint 可能只记录到退出时刻之前的一个恢复点。
- 当 DM 重启同步任务,并从 checkpoint 重新开始增量数据同步时,checkpoint 之后的部分数据可能已经在异常退出前被处理过了,从而导致部分 SQL 语句重复执行。
- 如果重复执行
INSERT
操作,会导致主键或唯一索引冲突,引发同步中断;如果重复执行UPDATE
操作,会导致不能根据筛选条件找到之前对应的更新记录。在安全模式下,通过改写 SQL 语句,DM 可以解决上述问题。
安全模式通过 SQL 语句改写来保证 binlog event 的幂等性。具体来说,在安全模式下:
INSERT
语句会被改写成REPLACE
语句。UPDATE
语句会被分析,得到该语句涉及的行的主键或唯一索引的值,然后改写成DELETE
+REPLACE
语句 :先根据主键或唯一索引的定位删除对应的行,然后使用REPLACE
语句插入一条最新值的行记录。
REPLACE
操作是 MySQL 特有的数据插入语法。使用REPLACE
语法插入数据时,如果新插入的数据和现有数据存在主键或唯一约束冲突,MySQL 会删除所有冲突的记录,然后再执行插入记录操作,相当于“强制插入”的操作。具体请参考 MySQL 官方文档的 REPLACE。
也就是说即使设置了 extra-args: “–consistency none” ,DM dump的数据也是连续的,可靠的,放心用就行。
另外吐槽:专栏这里贴了代码再加注释真实很难用,还是先在别的记事本里改好再贴过来比较方便。