slave_rows_search_algorithms对主从的影响

2024年 6月 7日 71.6k 0

实验前提

一个主从复制的环境 :主库A、从库B   ROW格式binlog的主备同步

主库A
测试表字段为 id ,a,b,c。 id是主键,a,b,c类型为int,测试表中预插入了一些数据。

create table table_t(id int primary key,a int ,b int ,c int);

mysql> select * from table_t;
+----+------+------+------+
| id | b | c | a |
+----+------+------+------+
| 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 2 |
+----+------+------+------+

场景一

主从的slave_rows_search_algorithms参数值均为

slave_rows_search_algorithms | TABLE_SCAN,INDEX_SCAN

从库上做了一个ddl alter table table_t modify a int after c;


从库B如下操作
mysql> alter table table_t modify a int after c;
Query OK, 0 rows affected (0.07 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> select * from table_t;
+----+------+------+------+
| id | b | c | a |
+----+------+------+------+
| 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 2 |
+----+------+------+------+
2 rows in set (0.00 sec)

这时在主库上执行 update table_t set b=999 where a=1;

mysql> update table_t set b=999 where a=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from table_t;
+----+------+------+------+
| id | a | b | c |
+----+------+------+------+
| 1 | 1 | 999 | 1 |
| 2 | 2 | 2 | 2 |
+----+------+------+------+
2 rows in set (0.00 sec)

请问:在从库上 select * from table_t 结果是啥,或者说从库上id=1 这行 a,b,c分别变成了啥?

从库结果如下:

mysql> select * from table_t;
+----+------+------+------+
| id | b | c | a |
+----+------+------+------+
| 1 | 1 | 999 | 1 |
| 2 | 2 | 2 | 2 |
+----+------+------+------+
2 rows in set (0.00 sec)

结论:

解析binlog

发现binlog记录的内容并没有列信息。

解析
主库
### UPDATE `test`.`table_t`
### WHERE
### @1=1
### @2=1
### @3=1
### @4=1
### SET
### @1=1
### @2=1
### @3=999
### @4=1

从库
### UPDATE `test`.`table_t`
### WHERE
### @1=1
### @2=1
### @3=1
### @4=1
### SET
### @1=1
### @2=1
### @3=999
### @4=1

binlog回放的原则 就是按顺序去修改 按主键去匹配.

场景二

主从的slave_rows_search_algorithms参数值均为

slave_rows_search_algorithms | TABLE_SCAN,INDEX_SCAN

在从库上执行:update table_t set a=null where id=2;
在主库上执行:update table_t set b=9999 where a=2;

请问:在从库上 select * from ta结果是啥,或者说从库上id=3 这行 a,b,c分别变成了啥?

主库

mysql> select * from table_t;
+----+------+------+------+
| id | a | b | c |
+----+------+------+------+
| 1 | 1 | 999 | 1 |
| 2 | 2 | 9999 | 2 |
+----+------+------+------+
2 rows in set (0.00 sec)

从库

mysql> select * from table_t;
+----+------+------+------+
| id | b | c | a |
+----+------+------+------+
| 1 | 1 | 999 | 1 |
| 2 | 2 | 9999 | 2 |
+----+------+------+------+
2 rows in set (0.00 sec)

结果和场景一一样

场景三

slave_rows_search_algorithms 设置成hash_Scan

主从初始值

mysql> select * from table_t;
+----+------+------+------+
| id | b | c | a |
+----+------+------+------+
| 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 2 |
+----+------+------+------+

在从库上执行: update table_t set a=null where id=2;
在主库上执行: update table_t set b=9999 where a=2;

mysql从库> select * from table_t ;
+----+------+------+------+
| id | a | b | c |
+----+------+------+------+
| 1 | 1 | 1 | 1 |
| 2 | NULL | 2 | 2 |
+----+------+------+------+
2 rows in set (0.00 sec)

mysql主库> select * from table_t;
+----+------+------+------+
| id | a | b | c |
+----+------+------+------+
| 1 | 1 | 1 | 1 |
| 2 | 2 | 9999 | 2 |
+----+------+------+------+
2 rows in set (0.00 sec)

主从报错

Last_SQL_Error: Could not execute Update_rows event on table test.table_t; Can't find record in 'table_t', Error_code: 1032;
Can't find record in 'table_t', Error_code: 1032;
handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000001, end_log_pos 1159

结论

只设置

slave_rows_search_algorithms 设置成hash_Scan 时,从库在回放binlog时会采用哈希扫描的方式来查找需要更新的数据行。结果就是没有找到需要修改的值对应行。

场景四

在mysql8.0中,该参数默认值为

slave_rows_search_algorithms | INDEX_SCAN,HASH_SCAN

再次进行场景三的实验

从库结果如下

mysql> select * from table_t;
+----+------+------+------+
| id | a | b | c |
+----+------+------+------+
| 1 | 1 | 1 | 1 |
| 2 | 2 | 9999 | 2 |
+----+------+------+------+

结论

说明binlog回放更新的时候,再次使用到了主键匹配。

相关文章

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

发布评论