数据库增量写入做SQL热点合并的细节问题

背景

数据迁移同步领域,做热点合并可以大大提升效率。本文对实现写入 SQL 热点合并中的细节做一些记录和备忘。

何为热点合并

相同 pk 上的 DML 在同步的时候,其实可以合并成一条变更,对于同步来说,我们保证最终一致性即可。下面的例子可以方便理解。多个 update 事件,我们只要保留最终结果即可,delete 事件以前的变更,其实可以都忽略。

1
2
3
4
5
6
7
8
9
10
11
12
13
## case 1
## 合并后等价为insert into t1(id,name1,name2) values(1,'wanshao11','wanshao22');
insert into t1(id,name1,name2) values(1,'wanshao1','wanshao2');
update t1 set name1='wanshao11' where id=1;
update t1 set name2='wanshao22' where id=1;

## case 2
## 合并后等价为delete from t1 where id=1;
insert into t1(id,name1,name2) values(1,'wanshao1','wanshao2');
update t1 set name1='wanshao11' where id=1;
update t1 set name2='wanshao22' where id=1;
delete from t1 where id=1;

合并规则

针对一个有序的变更序列,实现热点合并,可以遵循以下规则:

  • 针对 INSERT/UPDATE,从第一条事件开始,依次合并所有 update 的列的值,序列靠后的事件中的列值覆盖前面的
  • 针对一批事件中包含 DELETE 的,把pk 不冲突的 DELETE 提取出来单独执行。pk 不冲突,意味着这个 delete 关联的 pk 在这批数据中不存在任何这个 pk 上的变更。
  • 针对存在 pk 冲突的 DELETE 事件,在这个 delete 事件变更前的相同 pk 上的操作可以全部忽略