预置条件
A:数据库 Mysql01
B:数据库 Mysql02
通过 DTS 中的“数据同步”实现 Mysql01 到 Mysql02 的数据及数据结构的修改(DML+DDL)的同步。
此处 DTS 上的操作步骤不再详述.
实验步骤
1、数据表tbuser,在两个数据库环境中结构相同,但数据的初始状态如下:
Mysql01中
id |
user_name |
age |
1001 |
user1 |
10 |
1002 |
user2 |
20 |
Mysql02中
id |
user_name |
age |
1001 |
user1 |
10 |
1003 |
user3 |
30 |
2、向 Mysql01 的 tbuser 中插入一条数据:
insertinto tbuser(id,user_name,age)values('1004','user4','40');
此时 Mysql01 中的 binlog :
### INSERTINTO `db01`.`tbuser` ### SET### @1=1004### @2='user4'### @3=40
结束后,我们到 Mysql02 中查看数据,发现多了一条相同的数据。
3、更新 Mysql01 中的tbuser:
update tbuser set user_name='user3'where id =1002;
此时 Mysql01 中的 binlog 为:
### UPDATE `db01`.`tbuser` ### WHERE### @1=1002### @2='user3'### @3='30'
此时去 Mysql02中查看数据,结果如下:
select*from tbuser;
id |
user_name |
age |
1001 |
user1 |
10 |
1003 |
user3 |
30 |
1004 |
user4 |
40 |
也就是在 Mysql02 中没有任何的数据改变,这说明在进行更新操作时,只会更新 id 存在于 Mysql02 中的数据。那么如果我们换成条件更新呢?
在刚刚的基础上,我们继续在 Mysql01 中进行以下 sql 操作:
update tbuser set user_name='user3-01'where user_name ='user3';
此时,Mysql01 中数据为:
id |
user_name |
age |
1001 |
user1 |
10 |
1002 |
user3-01 |
30 |
Mysql02 中的数据为:
id |
user_name |
age |
1001 |
user1 |
10 |
1003 |
user3 |
30 |
1004 |
user4 |
40 |
4、操作两张表中都有的数据 1004
先将 Mysql02 中的数据进行更新:
update tbuser set age='45'where id =1004;
再进行 Mysql01 中的数据更新:
update tbuser set user_name='user4-01'where user_name ='user4';
也就是,我们在进行源库更新时,不采用主键为条件的更新,同时更新的目标字段与第一次在目标库更新的字段不同,那么此时目标库 Mysql02 中的数据会时如何呢?结果如下:
id |
user_name |
age |
1001 |
user1 |
10 |
1003 |
user3 |
30 |
1004 |
user4-01 |
40 |
可以看出,目标库的age又被更新成了 “40”,原因都在 binlog 中,我们可以查看 Mysql01 中的更新:
### UPDATE `db01`.`tbuser` ### WHERE### @1=1004### @2='user4-01'### @3='40'
可见 binlog 中记录的过程都是将表中每个字段都记录下来的,这也就是为什么目标库 Mysql02 中的age也被更新的原因。所以我们在使用DMS进行数据追踪和备份时,发现导出的 sql 都是包含了所有的字段,而不是只有你做了更新的字段的原因。
总结
由此可知当在更新同步时,是通过根据源库的主键 id 进行的目标数据库的更新。后续实现 delete操作,效果相同。同理可推断出,当在源库进行 insert 操作时,要想后续实现这些数据对应的 update 和 delete 操作,那么定然是将源库带 id 的 insert sql进行目标库插入,也就是必须保证源库的主键 id 和目标库的主键 id 相同(具体可见上面的 binlog)。