问题描述
当主从复制采用 binlog 的行模式时,如果从库启用 slow_query_log、log_slow_replica_statements 且从库重放 CREATE TABLE、DROP TABLE 时因特殊情况(比如被从库其他 SQL 占用 MDL 锁)执行耗时较长,会被从库记录到慢日志(slow log),而 ALTER TABLE 却不会被记录到慢日志。
ALTER TABLE 等管理语句是否会记录到慢日志,受参数 slow_query_log、log_slow_admin_statements 控制。
本文基于 MySQL 8.0.30 版本。
复现步骤
1. 搭建主从复制
主(master)、从(replica)my.cnf 中启用 binlog 的行模式:
binlog_format=ROW # 行模式
2. 从库动态设置配置参数
set global long_query_time=0.0001;
# 当然,除了这种方法,还有另一种方法:
# 主库执行DROP TABLE db1.tbl 语句之前,在从库先用事务阻塞住 DROP TABLE db1.tbl 的重放(会处于 Waiting for table metadata lock 状态):
# begin; select count(*) from db1.tbl for update;
# 等待几秒后(大于long_query_time的配置即可),再 commit
set global slow_query_log=on;
set global log_slow_replica_statements=on;
mysql> show variables like '%slow%';
+-----------------------------+----------------------------------------------------------+
| Variable_name | Value |
+-----------------------------+----------------------------------------------------------+
| log_slow_admin_statements | OFF |
| log_slow_extra | OFF |
| log_slow_replica_statements | ON |
| log_slow_slave_statements | ON |
| slow_launch_time | 2 |
| slow_query_log | ON |
| slow_query_log_file | /home/wslu/work/mysql/mysql80-data/s1-slave1/vm-slow.log |
+-----------------------------+----------------------------------------------------------+
7 rows in set (0.01 sec)
3. 主库执行 SQL 语句
CREATE TABLE db1.tbl(a int, b int);
DROP TABLE db1.tbl;
4. 查看从库慢日志
查看从库slow_query_log_file
参数指定的慢日志文件,其中出现 DROP TABLE 语句:
# Time: 2023-11-30T09:36:32.202303+08:00
# User@Host: skip-grants user[] @ [] Id: 41
# Query_time: 0.060373 Lock_time: 0.000143 Rows_sent: 0 Rows_examined: 0
SET timestamp=1701308185;
CREATE TABLE `tbl` (
`my_row_id` bigint unsigned NOT NULL AUTO_INCREMENT /*!80023 INVISIBLE */,
`a` int DEFAULT NULL,
`b` int DEFAULT NULL,
PRIMARY KEY (`my_row_id`)
);
# Time: 2023-11-30T09:36:37.768072+08:00
# User@Host: skip-grants user[] @ [] Id: 41
# Query_time: 0.025328 Lock_time: 0.000089 Rows_sent: 0 Rows_examined: 0
SET timestamp=1701308197;
DROP TAB