mysql修改从库会影响复制_mysql row format下主库端大批量修改数据造成从库复制延时问题...

实验版本:5.7.31-log

mysql中的每张表都需要创建索引,并且因为防止索引B+树 page split的原因,通常规范都创建 AUTO_INCREMENT的自增型主键。

如果表上没有主键或者选择性很高的索引,在 binlog_format= ROW 时,主库端大批量修改表中的数据在从库端会有大批量行的events回放,这种情况下如果表上没有主键或索引,每个行的操作都会变成table scan,会造成主从复制延时问题。这也是每张表都需要创建主键的另外一种原因。

--默认的slave_rows_search_algorithms

mysql> select @@global.slave_rows_search_algorithms;

+---------------------------------------+

| @@global.slave_rows_search_algorithms |

+---------------------------------------+

| TABLE_SCAN,INDEX_SCAN |

+---------------------------------------+

1 row in set (0.00 sec)

mysql>

--表结构,没有主键和索引

mysql> show create table tb01;

+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+

| Table | Create Table |

+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+

| tb01 | CREATE TABLE tb01 (

id int(11) DEFAULT NULL,

name varchar(30) DEFAULT NULL,

addr varchar(30) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |

+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

mysql>

--表中有100万行数据

mysql> select count() from tb01;

+----------+

| count() |

+----------+

| 1000000 |

+----------+

1 row in set (0.19 sec)

mysql>

--主库端删除数据

mysql> delete from tb01;

Query OK, 1000000 rows affected (2.01 sec)

mysql>

--从库马上开始延时

mysql> show slave status\G

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.56.57

Master_User: repl

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: binlog.000028

Read_Master_Log_Pos: 28901411

Relay_Log_File: mysql5702-relay-bin.000010

Relay_Log_Pos: 401

Relay_Master_Log_File: binlog.000028

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Replicate_Do_DB:

Replicate_Ignore_DB:

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

Last_Errno: 0

Last_Error:

Skip_Counter: 0

Exec_Master_Log_Pos: 194

Relay_Log_Space: 28901913

Until_Condition: None

Until_Log_File:

Until_Log_Pos: 0

Master_SSL_Allowed: No

Master_SSL_CA_File:

Master_SSL_CA_Path:

Master_SSL_Cert:

Master_SSL_Cipher:

Master_SSL_Key:

Seconds_Behind_Master: 427

Master_SSL_Verify_Server_Cert: No

Last_IO_Errno: 0

Last_IO_Error:

Last_SQL_Errno: 0

Last_SQL_Error:

Replicate_Ignore_Server_Ids:

Master_Server_Id: 1

Master_UUID: 54c4ff93-0adf-11eb-b3bd-0800270418e5

Master_Info_File: /usr/local/my3306/master.info

SQL_Delay: 0

SQL_Remaining_Delay: NULL

Slave_SQL_Running_State: Reading event from the relay log

Master_Retry_Count: 86400

Master_Bind:

Last_IO_Error_Timestamp:

Last_SQL_Error_Timestamp:

Master_SSL_Crl:

Master_SSL_Crlpath:

Retrieved_Gtid_Set: 54c4ff93-0adf-11eb-b3bd-0800270418e5:61-1000065

Executed_Gtid_Set:

Auto_Position: 0

Replicate_Rewrite_DB:

Channel_Name:

Master_TLS_Version:

1 row in set (0.00 sec)

mysql>

--通过mysqlbinlog翻译对应的relaylog mysql5702-relay-bin.000010

[mysql@mysql5702 my3306]$ /usr/local/mysql/bin/mysqlbinlog -vv --base64-output=DECODE-ROWS /usr/local/my3306/mysql5702-relay-bin.000010 > relaylog_results.sql

看到relaylog中

b586b8ef894b0d40c634a499194d1a72.png

在row format下,生成了1000000个DELETE语句:

39fc6397b6227b888b7e020ec276e166.png

[mysql@mysql5702 my3306]$ cat relaylog_results.sql | grep DELETE | wc -l

1000000

[mysql@mysql5702 my3306]$

===============================表上有主键========================

--添加主键

mysql> alter table tb01 add primary key pk_tb01 (id);

Query OK, 0 rows affected (2.69 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql>

--主库端删除数据

mysql> delete from tb01;

Query OK, 999999 rows affected (1.93 sec)

从库端瞬间完成同步,同步正常

===============================表上有索引========================

--添加索引

mysql> alter table tb01 add index idx_tb01 (name);

Query OK, 0 rows affected (1.81 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql>

--主库端删除数据

mysql> delete from tb01;

Query OK, 999999 rows affected (7.52 sec)

mysql>

从库端也可以很快完成同步,同步正常。

结论:在默认的slave_rows_search_algorithms下,如果大批量update/delete master上的数据,表上一定要有主键或选择性高的索引,否则会立马导致从库复制延时并且很难追上。这也是mysql的表上都要建主键的另外一个原因。

注:slave_rows_search_algorithms 除了 TABLE_SCAN和INDEX_SCAN,还有一种 HASH_SCAN,但并不稳定,所以通常都不会配置 HASH_SCAN。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值