MySQL慢查询中的commit慢和binlog中慢事务有什么区别

网友投稿 418 2023-07-04

MySQL慢查询中的commit慢和binlog中慢事务有什么区别

MySQL慢查询中的commit慢和binlog中慢事务有什么区别

一、问题来源

在分析性能问题的时候慢查询和binlog慢事务是常用的手段。最近在分析一个慢查询的,发现其中包含了大量的commit语句慢,但是在分析binlog慢事务的时候不能完成匹配。比如这段时间commit的语句可能有1000个,但是慢事务可能只有100个,这个差得也太多了,那么为什么会出现这种现象呢?

二、各自的判定方式

慢事务 对于一个显示提交的(insert)事务通常如下:

GTID_LOG_EVENT和XID_EVENT是命令‘COMMIT’发起的时间。第一个发起"INSERT"命令的时间是QUERY_EVENT。MAP_EVENT/WRITE_ROWS_EVENT是每个‘Insert’命令发起的时间。

因此我们通常通过XID_EVENT的时间减去QUERY_EVENT的时间就得到了一个慢事务时间, 当然如果是自动提交的则不能这么计算 ,因为各个event都是语句发起的时间。

commit 慢的可能性

我们知道commit慢最可能的地方在binlog的刷盘或者等待半同步从库ACK,但是binlog中XID EVENT的时间却不包含这部分时间,也就是说binlog慢事务和慢查询中的commit记录的不是一个时间段。

简要说明

如果我们以如下事务为例,进行简要说明

begin;insert into it values(10);commit; -- insert语句执行 -> QUERY_EVENT时间(T1) -- insert语句执行完成,判定insert语句是否为慢查询(T2) -- commit语句执行 -> GTID_LOG_EVENT和XID_EVENT时间(T3) flush fsync -----> 传输binlog (sync_binlog=1) <---- 等待ACK (rpl_semi_sync_master_wait_point=AFTER_SYNC) commit-- commit语句执行完成,判定commit语句是否为慢查询(T4)登录后复制

判定insert语句是否慢的标准是T2-T1(-锁时间)判定commit语句是否慢的标准是T4-T3判定慢事务的标准是T3-T1

因此慢事务的判定和慢查询中commit慢的判定几乎没有什么交集,因此出现这种情况也是正常的,下面来证明。

三、证明

主库:半同步超时时间为999999999。从库:设置sync_relay_log=1,并且断点设置在MYSQL_BIN_LOG::flush_and_sync函数上,本函数是从库每次event写到relay log后受到 sync_relay_log=1 的影响必须要落盘的判定函数。

这样人为在断点处等待一下就显著的拉长了commit的时间,同时也证明半同步慢会影响commit慢,如下:

begin;select now(); -T1insert into it values(10);select sleep(10);select now(); -T2commit; (断点在从库生效卡主ack) -T3select now(); -T4结果mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> select now(); -T1+---------------------+| now() |+---------------------+| 2022-06-12 22:20:43 |+---------------------+1 row in set (0.00 sec)mysql> insert into it values(10);Query OK, 1 row affected (0.10 sec)mysql> select sleep(10);+-----------+| sleep(10) |+-----------+| 0 |+-----------+1 row in set (10.01 sec)mysql> select now(); -T2 AND T3+---------------------+| now() |+---------------------+| 2022-06-12 22:20:54 |+---------------------+1 row in set (0.00 sec)mysql> commit; Query OK, 0 rows affected (21.64 sec)mysql> select now(); -T4+---------------------+| now() |+---------------------+| 2022-06-12 22:21:15 |+---------------------+1 row in set (0.00 sec)登录后复制

我们来分析一下慢查询和binlog,这里加入了sleep(10)拖长了事务commit时间,因为insert太快了。

binlog慢事务 22:20:54(T2) - 22:20:43(T1) = 11秒左右(我们加入了sleep(10))

# at 12221#220612 22:20:54 server id 613306 end_log_pos 12286 CRC32 0x3e019332 GTID last_committed=40 sequence_number=41 rbr_only=yes/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;SET @@SESSION.GTID_NEXT= '00320cc8-39f9-11ec-b5ba-000c2929706d:41'/*!*/;# at 12286#220612 22:20:43 server id 613306 end_log_pos 12360 CRC32 0x8dcde193 Query thread_id=43 exec_time=1 error_code=0SET TIMESTAMP=1655043643/*!*/;BEGIN/*!*/;# at 12360#220612 22:20:43 server id 613306 end_log_pos 12409 CRC32 0x0db68582 Rows_query# insert into it values(10)# at 12409#220612 22:20:43 server id 613306 end_log_pos 12456 CRC32 0x363a48c7 Table_map: `mysemi`.`it` mapped to number 124# at 12456#220612 22:20:43 server id 613306 end_log_pos 12496 CRC32 0xd44e43f3 Write_rows: table id 124 flags: STMT_END_F### INSERT INTO `mysemi`.`it`### SET### @1=10 /* INT meta=0 nullable=1 is_null=0 */# at 12496#220612 22:20:54 server id 613306 end_log_pos 12527 CRC32 0x4d8d2c64 Xid = 547COMMIT/*!*/;登录后复制

慢查询中的commit慢 22:21:15(T4) - 22:20:54(T3) = 21秒

# Time: 2022-06-12T22:21:15.746223Z# User@Host: root[root] @ localhost [] Id: 43# Schema: mysemi Last_errno: 0 Killed: 0# Query_time: 21.641090 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 Rows_affected: 0# Bytes_sent: 11SET timestamp=1655043675;commit;登录后复制

这里很显然了慢查询记录的commit慢明显不包含在慢事务中。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:mysql怎么创建哈希索引
下一篇:MySQL中union和unionall区别是什么
相关文章