主从结构不一致复制问题验证

2023年 8月 15日 62.0k 0

背景说明:

在一次断网测试过程中,在主库发起了DDL操作,备库丢失该DDL,导致主从表结构不一致,接下来的测试竟然都正常,表结构不一致,不影响复制进程,感觉比较奇怪,在这之前都是认为主从表结构不一致会导致复制异常,为了弄明白这个问题,进行了问题复现验证。

测试环境

MySQL社区版 8.0.25binlog_format=row

复现过程:

1、初始化8.0.25版本的两个实例,并且建立了主从复制关系,过程略

主机IP 端口 角色
10.0.0.70 3309 master
10.0.0.58 3309 slave

2、在58:3309中检查复制关系,确认正常

mysql> show slave status \G*************************** 1. row ***************************               Slave_IO_State: Waiting for master to send event                  Master_Host: 10.0.0.70                  Master_User: repl                  Master_Port: 3309                Connect_Retry: 60              Master_Log_File: mysql-bin.000002          Read_Master_Log_Pos: 1094               Relay_Log_File: mysql-relay-bin.000003                Relay_Log_Pos: 442        Relay_Master_Log_File: mysql-bin.000002             Slave_IO_Running: Yes            Slave_SQL_Running: Yes              Replicate_Do_DB:           Replicate_Ignore_DB:   ...1 row in set, 1 warning (0.01 sec)

3、在70:3309中创建test库,并且创建测试表t_diff

mysql> create database test;Query OK, 1 row affected (0.00 sec)mysql> use testDatabase changedmysql> create table t_diff(id int primary key auto_increment, a varchar(10), b varchar(10), c varchar(10), d varchar(10));Query OK, 0 rows affected (0.01 sec)mysql>

4、在70:3309中,往t_diff中插入4条测试数据

mysql> insert into t_diff values(1, 'a1', 'b1', 'c1', 'd1'),(2, 'a2', 'b2', 'c2', 'd2'),(3, 'a3', 'b3', 'c3', 'd3'),(4, 'a4', 'b4', 'c4', 'd4');Query OK, 4 rows affected (0.01 sec)Records: 4  Duplicates: 0  Warnings: 0mysql>

5、模拟主从表结构不一致,在58:3309中,在t_diff中删除d列

mysql> alter table t_diff drop column d;Query OK, 0 rows affected (0.02 sec)Records: 0  Duplicates: 0  Warnings: 0mysql> 

6、在70:3309中,往t_diff中更新一条记录,并且查看表中数据

mysql> update t_diff set a='a14', d='d14' where id=4;Query OK, 1 row affected (0.00 sec)Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from t_diff;+----+------+------+------+------+| id | a    | b    | c    | d    |+----+------+------+------+------+|  1 | a1   | b1   | c1   | d1   ||  2 | a2   | b2   | c2   | d2   ||  3 | a3   | b3   | c3   | d3   ||  4 | a14  | b4   | c4   | d14  |+----+------+------+------+------+4 rows in set (0.00 sec)mysql> select @@report_host;+---------------+| @@report_host |+---------------+| 10.0.0.70 |+---------------+1 row in set (0.00 sec)mysql>

7、在58:3309中,查看复制状态正常

mysql> show slave status \G*************************** 1. row ***************************               Slave_IO_State: Waiting for master to send event                  Master_Host: 10.230.183.70                  Master_User: repl                  Master_Port: 3309                Connect_Retry: 60              Master_Log_File: mysql-bin.000002          Read_Master_Log_Pos: 3658               Relay_Log_File: mysql-relay-bin.000003                Relay_Log_Pos: 3006        Relay_Master_Log_File: mysql-bin.000002             Slave_IO_Running: Yes            Slave_SQL_Running: Yes              Replicate_Do_DB:           Replicate_Ignore_DB:  ...mysql> 

8、在58:3309中,查看表数据条数正确

mysql> select * from test.t_diff;+----+------+------+------+| id | a    | b    | c    |+----+------+------+------+|  1 | a1   | b1   | c1   ||  2 | a2   | b2   | c2   ||  3 | a3   | b3   | c3   ||  4 | a14  | b4   | c4   |+----+------+------+------+4 rows in set (0.00 sec)mysql> select @@report_host;+---------------+| @@report_host |+---------------+| 10.0.0.58 |+---------------+1 row in set (0.00 sec)mysql> 

9、为了查明主从执行的具体SQL,解析70:3309中最后更新的binlog信息

[root@0I /data/mysql/log]# /data/software/mysql-8.0.25-linux-glibc2.12-x86_64/bin/mysqlbinlog -vvv --base64-output=decode-rows mysql-bin.000003 | tail -n 23# at 1097#220302  9:52:15 server id 6  end_log_pos 1165  Update_rows: table id 129 flags: STMT_END_F### UPDATE `test`.`t_diff`### WHERE###   @1=4 /* INT meta=0 nullable=0 is_null=0 */###   @2='a4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @3='b4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @4='c4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @5='d4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */### SET###   @1=4 /* INT meta=0 nullable=0 is_null=0 */###   @2='a14' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @3='b4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @4='c4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @5='d14' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */# at 1165#220302  9:52:15 server id 6  end_log_pos 1192  Xid = 160COMMIT/*!*/;SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;DELIMITER ;# End of log file/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;[root@0I /data/mysql/log]#

10、解析58:3309中最后插入的binlog信息

[root:/data/mysql/log]# /data/software/mysql-8.0.25-linux-glibc2.12-x86_64/bin/mysqlbinlog -vvv --base64-output=decode-rows mysql-bin.000003 | tail -n 21# at 1098#220302  9:52:15 server id 6  end_log_pos 1159  Update_rows: table id 126 flags: STMT_END_F### UPDATE `test`.`t_diff`### WHERE###   @1=4 /* INT meta=0 nullable=0 is_null=0 */###   @2='a4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @3='b4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @4='c4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */### SET###   @1=4 /* INT meta=0 nullable=0 is_null=0 */###   @2='a14' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @3='b4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @4='c4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */# at 1159#220302  9:52:15 server id 6  end_log_pos 1186  Xid = 51COMMIT/*!*/;SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;DELIMITER ;# End of log file/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;[root:/data/mysql/log]#

11、解析58:3309中最后的relaylog信息

[root:/data/mysql/log]# /data/software/mysql-8.0.25-linux-glibc2.[root@pod5-hb-c3-test-31 /data/mysql/log]# /data/software/mysql-8.0.25-linux-glibc2.12-x86_64/bin/mysqlbinlog -vvv --base64-output=decode-rows mysql-relay-bin.000006 | tail -n 22#220302  9:52:15 server id 6  end_log_pos 1165  Update_rows: table id 129 flags: STMT_END_F### UPDATE `test`.`t_diff`### WHERE###   @1=4 /* INT meta=0 nullable=0 is_null=0 */###   @2='a4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @3='b4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @4='c4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @5='d4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */### SET###   @1=4 /* INT meta=0 nullable=0 is_null=0 */###   @2='a14' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @3='b4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @4='c4' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */###   @5='d14' /* VARSTRING(40) meta=40 nullable=1 is_null=0 */# at 1286#220302  9:52:15 server id 6  end_log_pos 1192  Xid = 160COMMIT/*!*/;SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;DELIMITER ;# End of log file/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;[root:/data/mysql/log]#

12、从上面三个日志文件解析可以得知,主库的binlog记录完整数据,从库的relay log记录完整数据,而到了从库的binlog,就只有前4个字段了,此处获得如下几个疑问?

  • 1.主库、从库字段不一致,为什么可以正常同步数据
  • 2.从库应用relaylog的时候,是否跳过了字段名称检查

现象解答

经过多方资料查找与咨询,最终在官方资料中找到答案,一定条件下复制结构的主、从库中表结构允许不一致,即主库相比从库多了字段、少了字段,都不影响同步,甚至在部分场景下,数据类型不一致都是可以正常同步的

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论