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


Posted in MySQL onJune 16, 2022

常见原因总结,特殊情况除外。

一、问题来源

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

二、各自的判定方式

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

  • GTID_LOG_EVENT和XID_EVENT是命令‘COMMIT’发起的时间。

  • QUERY_EVENT是第一个‘Insert’命令发起的时间。

  • 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();   -T1
insert into it values(10);
select sleep(10);
select now();   -T2
commit; (断点在从库生效卡主ack) -T3
select 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=0
SET 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 = 547
COMMIT/*!*/;
  • 慢查询中的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: 11
SET timestamp=1655043675;
commit;

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

四、总结

基于如上我们稍微做下总结,并且加上我们常有的认知,总结如下:

  • binlog慢事务中有记录,慢查询没有记录,可能事务中有大量的锁等待信息或者是事务没有及时提交。

  • 慢查询有记录,binlog慢事务中没有记录,可能语句本身为自动事务提交,自动提交的事务无法计算慢事务。

  • 如果确实是DML语句慢(排除加锁时间)导致的慢事务并且为显示(begin;commit)事务才会同时出现在binlog慢事务和慢查询中。

  • 慢查询中出现commit慢和binlog慢事务没有必然的关系,因为记录的时间完全不同。

  • 半同步慢ACK和日志刷盘慢会影响到commit慢,都会记录到慢查询(MGR before commit hook 处理慢也会)。

  • 如果binlog慢事务和某些慢查询中的select语句时间匹配则可能是事务中包含了select语句导致。

当然这只是常见的总结,很多特殊原因不好说,需要pstack等手段确认。

到此这篇关于MySQL慢查询中的commit慢和binlog中慢事务的差异的文章就介绍到这了,更多相关MySQL慢查询commit和binlog慢事务内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!


Tags in this post...

MySQL 相关文章推荐
MySQL锁机制
Apr 05 MySQL
MySQL Shell的介绍以及安装
Apr 24 MySQL
MySQL获取所有分类的前N条记录
May 07 MySQL
Mysql基础知识点汇总
May 26 MySQL
MySQL中的布尔值,怎么存储false或true
Jun 04 MySQL
mysql中between的边界,范围说明
Jun 08 MySQL
浅谈MySQL user权限表
Jun 18 MySQL
MySQL中order by的使用详情
Nov 17 MySQL
彻底解决MySQL使用中文乱码的方法
Jan 22 MySQL
千万级用户系统SQL调优实战分享
Mar 03 MySQL
面试中老生常谈的MySQL问答集锦夯实基础
Mar 13 MySQL
MySQL中一条SQL查询语句是如何执行的
Apr 08 MySQL
MySQL聚簇索引和非聚簇索引的区别详情
关于mysql中string和number的转换问题
Jun 14 #MySQL
mysql实现将字符串字段转为数字排序或比大小
Jun 14 #MySQL
手把手带你彻底卸载MySQL数据库
MYSQL中文乱码问题的解决方案
Jun 14 #MySQL
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
Jun 14 #MySQL
MySql如何将查询的出来的字段进行转换
Jun 14 #MySQL
You might like
PHP 获取客户端真实IP地址多种方法小结
2010/05/15 PHP
Laravel登录失败次数限制的实现方法
2020/08/26 PHP
DWR实现模拟Google搜索效果实现原理及代码
2013/01/30 Javascript
浅析jQuery1.8的几个小变化
2013/12/10 Javascript
Javasipt:操作radio标签详解
2013/12/30 Javascript
JavaScript中的索引数组、关联数组和静态数组、动态数组讲解
2014/11/08 Javascript
浅谈jQuery异步对象(XMLHttpRequest)
2014/11/17 Javascript
自定义Angular指令与jQuery实现的Bootstrap风格数据双向绑定的单选与多选下拉框
2015/12/12 Javascript
Angularjs中如何使用filterFilter函数过滤
2016/02/06 Javascript
Bootstarp风格的toggle效果分享
2016/02/23 Javascript
JavaScript的Ext JS框架中的GridPanel组件使用指南
2016/05/21 Javascript
js与jquery正则验证电子邮箱、手机号、邮政编码的方法
2016/07/04 Javascript
微信小程序加载更多 点击查看更多
2016/11/29 Javascript
微信公众号开发 实现点击返回按钮就返回到聊天界面
2016/12/15 Javascript
详解JavaScript调用栈、尾递归和手动优化
2017/06/03 Javascript
20行js代码实现的贪吃蛇小游戏
2017/06/20 Javascript
使用JS实现气泡跟随鼠标移动的动画效果
2017/09/16 Javascript
妙用缓存调用链实现JS方法的重载
2018/04/30 Javascript
详解webpack打包时排除其中一个css、js文件或单独打包一个css、js文件(两种方法)
2018/10/26 Javascript
浅析微信扫码登录原理(小结)
2018/10/29 Javascript
vue.js仿hover效果的实现方法示例
2019/01/28 Javascript
微信小程序实现的一键连接wifi功能示例
2019/04/24 Javascript
返回上一个url并刷新界面的js代码
2020/09/12 Javascript
解决vue prop传值default属性如何使用,为何不生效的问题
2020/09/21 Javascript
[22:59]VGJ.S vs VG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
解决Python一行输出不显示的问题
2018/12/03 Python
python如何操作mysql
2020/08/17 Python
如何用 Python 制作一个迷宫游戏
2021/02/25 Python
纯CSS3代码实现文字描边
2016/04/25 HTML / CSS
英国最大的体育&时尚零售公司:JD Sports
2017/12/13 全球购物
质检的岗位职责
2013/11/17 职场文书
2014乡镇机关党员个人对照检查材料思想汇报
2014/10/09 职场文书
《狼牙山五壮士》教学反思
2016/02/17 职场文书
pytorch 运行一段时间后出现GPU OOM的问题
2021/06/02 Python
JavaScript组合继承详解
2021/11/07 Javascript
windows10声卡驱动怎么安装?win10声卡驱动安装操作步骤教程
2022/08/05 数码科技