背景:
111<->112 双A模式
111->112_canal:111 同步数据至112
-
主站点:true
-
支持ddl同步: 关闭
-
跳过ddl异常: 开启
112->111_canal:112同步数据至111
-
主站点:flase
-
支持ddl同步: 开启
-
跳过ddl异常: 开启
在以上的背景下
疑问一:数据的增删查改都没问题,但是当在111上 执行create table/Truncate 这类DDL语句后,不会同步到112上,反之在112上执行可以同步至111,因为支持ddl同步这个参数的原因
解决办法:
待续
疑问二:当表没有主键约束时,在非主站点上执行insert会重复插入一条如:
-
非主站点上执行:
-
mysql> insert into test3 values(5);
-
Query OK, 1 row affected (0.01 sec)
-
-
mysql> select * from test3;
-
+------+
-
| id |
-
+------+
-
| 4 |
-
| 5 |
-
| 5 |
-
+------+
-
3 rows in set (0.00 sec)
-
-
主站点上:
-
mysql> select * from test3;
-
+------+
-
| id |
-
+------+
-
| 4 |
-
| 5 |
-
+------+
-
2 rows in set (0.00 sec)
同步至主站点了,但是非主站点会再插入一遍
原因:otter设计的单向回环
思路:最终一致性
适用场景: A地和B地数据不对等,比如A地为主,写入量比较高,B地有少量的数据写入
单向回环流程:(比如图中以HZ为trusted source站点)
-
us->hz同步的数据,会再次进入hz->us队列,形成一次单向回环
-
hz->us同步的数据,不会进入us->hz队列(回环终止,保证不进入死循环)
解决办法:设计表都带上自增主键
疑问三:如果两边同时插入一条数据,自增id怎么办?
-
mysql> select * from admin;
-
+----+---------+
-
| id | role_id |
-
+----+---------+
-
| 8 | 77 |
-
| 9 | 777 |
-
| 11 | 99 |
-
| 12 | 999 |
-
| 16 | 888 | ---可以看到,主站点丢失,未插入!
-
+----+---------+
-
5 rows in set (0.00 sec)
在github上《otter数据库入库算法》部分看到这样一段话:合并算法执行后,单pk主键只有一条记录,减少并行load算法的复杂性(比如batch合并,并行/串行等处理)
因为并发插入之间的时间间隔非常短,短于同步之间的延迟,在主副站点分别插入后是同一条pk建,并且副站点后插入,那么副站点是最新副本集也就是trust 点,副站点数据覆盖主站点数据,《otter数据一致性》详解!
解决办法:参考官方双a的做法,设置步长和起始值
-
修改两台的步长
-
mysql> show global variables like '%auto_increment_increment%';
-
+--------------------------+-------+
-
| Variable_name | Value |
-
+--------------------------+-------+
-
| auto_increment_increment | 2 |
-
+--------------------------+-------+
-
-
mysql> show global variables like '%auto_increment_increment%';
-
+--------------------------+-------+
-
| Variable_name | Value |
-
+--------------------------+-------+
-
| auto_increment_increment | 1 |
-
+--------------------------+-------+
-
-
再次测试
-
[root@DB-22 dbaadmin]# python test.py
()
()
all over Mon Jul 31 17:54:10 2017
[root@DB-22 dbaadmin]# python test.py
()
()
all over Mon Jul 31 17:54:21 2017
-
mysql> select * from admin;
+----+---------+
| id | role_id |
+----+---------+
| 28 | 111 |
+----+---------+
1 row in set (0.00 sec)
mysql> select * from admin;
+----+---------+
| id | role_id |
+----+---------+
| 28 | 111 |
| 29 | 888 |
| 30 | 88 |
+----+---------+
3 rows in set (0.00 sec)
mysql> select * from admin;
+----+---------+
| id | role_id |
+----+---------+
| 28 | 111 |
| 29 | 888 |
| 30 | 88 |
| 31 | 888 |
| 32 | 88 |
+----+---------+
5 rows in set (0.00 sec)