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 07 MySQL
MySQL sql_mode的使用详解
May 08 MySQL
MySQL 存储过程的优缺点分析
May 20 MySQL
mysql获取指定时间段中所有日期或月份的语句(不设存储过程,不加表)
Jun 18 MySQL
详细聊聊MySQL中慢SQL优化的方向
Aug 30 MySQL
MySQL利用UNION连接2个查询排序失效详解
Nov 20 MySQL
VS2019连接MySQL数据库的过程及常见问题总结
Nov 27 MySQL
防止web项目中的SQL注入
Dec 06 MySQL
面试提问mysql一张表到底能存多少数据
Mar 13 MySQL
MySQL Server层四个日志的实现
Mar 31 MySQL
CentOS MySql8 远程连接实战
Apr 19 MySQL
MySQL GTID复制的具体使用
May 20 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随机数生成代码与使用实例分析
2011/04/08 PHP
PHP cdata 处理(详细介绍)
2013/07/05 PHP
thinkphp特殊标签用法概述
2014/11/24 PHP
PHP随手笔记整理之PHP脚本和JAVA连接mysql数据库
2015/11/25 PHP
PHP+AJAX 投票器功能
2017/11/11 PHP
jQuery Validation插件remote验证方式的Bug解决
2010/07/01 Javascript
详解jQuery插件开发中的extend方法
2013/11/19 Javascript
IE8下Jquery获取select选中的值post到后台报错问题
2014/07/02 Javascript
Node.js插件的正确编写方式
2014/08/03 Javascript
Javascript 读取操作Sql中的Xml字段
2014/10/09 Javascript
jQuery简单实现禁用右键菜单
2015/03/10 Javascript
js实现汉字排序的方法
2015/07/23 Javascript
浏览器兼容性问题大汇总
2015/12/17 Javascript
如何清除IE10+ input X 文本框的叉叉和密码输入框的眼睛图标
2016/12/21 Javascript
详解处理bootstrap4不支持远程静态框问题
2018/07/20 Javascript
js动态获取时间的方法分析
2019/08/02 Javascript
原生js实现点击轮播切换图片
2020/02/11 Javascript
微信小程序如何加载数据库真实数据的实现
2020/03/04 Javascript
Vue scoped及deep使用方法解析
2020/08/01 Javascript
Node.js web 应用如何封装到Docker容器中
2020/09/01 Javascript
Python ZipFile模块详解
2013/11/01 Python
python实现颜色空间转换程序(Tkinter)
2015/12/31 Python
Python中使用platform模块获取系统信息的用法教程
2016/07/08 Python
python 调用win32pai 操作cmd的方法
2017/05/28 Python
Anaconda2 5.2.0安装使用图文教程
2018/09/19 Python
python通过配置文件共享全局变量的实例
2019/01/11 Python
CentOS 7如何实现定时执行python脚本
2020/06/24 Python
matplotlib事件处理基础(事件绑定、事件属性)
2021/02/03 Python
家庭户外服装:Hawkshead
2017/11/02 全球购物
Under Armour西班牙官网:美国知名的高端功能性运动品牌
2018/12/12 全球购物
简历中求职的个人自我评价
2013/12/03 职场文书
物业总经理岗位职责
2014/02/28 职场文书
食品采购员岗位职责
2014/04/14 职场文书
付款委托书范本
2014/10/05 职场文书
校长新学期致辞
2015/07/30 职场文书
处理canvas绘制图片模糊问题
2022/05/11 Javascript