START transaction;
delete from xxx where id=xxx;
replace into xxx (id) values (xxx);
replace into xxx (id) values(xx3232);
delete from xxx where id=xx2;
replace into xxx (id) values (xx2);
replace into xxx (id) values(3333232);
....
commit
就是穿插着delete和replace。然后好几个sql一起再执行一下commit。
gravity的同步基本上就是:
replace into xxx (id) values(1),(2),(3),(4);
并且是auto commit的
为什么已经要replace into 了,还要先执行下 delete?
→ 出于 “幂等性/可冲入行(idempotent/reentrant)” 考虑(but there are no ways to make update idempotent) → DM idempotent, tidb-binlog idempotent
→ 幂等的优势:后续日志完备条件下,可任意时间点重放。
→ 幂等定义,简而言之,update 不是密等的。
For a mathematical example,
adding 1 changes the results, but multiplying by 1 is idempotent.
When you add 1 to a number and then add 1 again, you get different results.
If you multiply a number by 1 and multiply by 1 again, you do get the same result.
为什么不能多个 values 拼一起,用auto commit提交?
→ a. 为什么不能多个 values 拼一起?
→ related explanation
syncers: # sync 处理单元的运行配置参数
global:
......
# 设置为 true,DM 会在不增加延迟的情况下,尽可能地将上游对同一条数据的多次操作压缩成一次操作。
# 如 INSERT INTO tb(a,b) VALUES(1,1); UPDATE tb SET b=11 WHERE a=1; 会被压缩成 INSERT INTO tb(a,b) VALUES(1,11); 其中 a 为主键
# 如 UPDATE tb SET b=1 WHERE a=1; UPDATE tb(a,b) SET b=2 WHERE a=1; 会被压缩成 UPDATE tb(a,b) SET b=2 WHERE a=1; 其中 a 为主键
# 如 DELETE FROM tb WHERE a=1; INSERT INTO tb(a,b) VALUES(1,1); 会被压缩成 REPLACE INTO tb(a,b) VALUES(1,1); 其中 a 为主键
compact: false
# 设置为 true,DM 会尽可能地将多条同类型的语句合并到一条语句中,生成一条带多行数据的 SQL 语句。
# 如 INSERT INTO tb(a,b) VALUES(1,1); INSERT INTO tb(a,b) VALUES(2,2); 会变成 INSERT INTO tb(a,b) VALUES(1,1),(2,2);
# 如 UPDATE tb SET b=11 WHERE a=1; UPDATE tb(a,b) set b=22 WHERE a=2; 会变成 INSERT INTO tb(a,b) VALUES(1,11),(2,22) ON DUPLICATE KEY UPDATE a=VALUES(a), b=VALUES(b); 其中 a 为主键
# 如 DELETE FROM tb WHERE a=1; DELETE FROM tb WHERE a=2 会变成 DELETE FROM tb WHERE (a) IN (1),(2);其中 a 为主键
multiple-rows: false
–>b. 为什么不能用auto commit提交?
综上,为了把 delete + replace 控制在同一事务内,不能 auto commit。
CREATE TABLE t (a INT PRIMARY KEY, b INT);
INSERT INTO t VALUES (1, 1);
INSERT INTO t VALUES (2, 2);
BEGIN;
UPDATE t SET a = 3 WHERE a = 1;
UPDATE t SET a = 1 WHERE a = 2;
UPDATE t SET a = 2 WHERE a = 3;
COMMIT;