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数据库索引面试题(程序员基础技能)
May 31 MySQL
MySQL系列之十四 MySQL的高可用实现
Jul 02 MySQL
Mysql8.0递归查询的简单用法示例
Aug 04 MySQL
MySQL千万级数据表的优化实战记录
Aug 04 MySQL
SQL IDENTITY_INSERT作用案例详解
Aug 23 MySQL
MySQL的全局锁和表级锁的具体使用
Aug 23 MySQL
MySQL数据库索引的最左匹配原则
Nov 20 MySQL
浅谈mysql哪些情况会导致索引失效
Nov 20 MySQL
详解MySql中InnoDB存储引擎中的各种锁
Feb 12 MySQL
MySQL 计算连续登录天数
May 11 MySQL
mysql中关键词exists的用法实例详解
Jun 10 MySQL
MySQL新手入门进阶语句汇总
Sep 23 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递归删除目录下的文件但保留的实例分享
2014/05/10 PHP
PHP中把数据库查询结果输出为json格式简单实例
2015/04/09 PHP
php生成4位数字验证码的实现代码
2015/11/23 PHP
在html页面中包含共享页面的方法
2008/10/24 Javascript
封装了一个js图片轮换效果的函数
2011/09/28 Javascript
js解析与序列化json数据(三)json的解析探讨
2013/02/01 Javascript
jquery图片放大功能简单实现
2013/08/01 Javascript
jQuery动态创建html元素的常用方法汇总
2014/09/05 Javascript
a标签的href与onclick事件的区别详解
2014/11/12 Javascript
js实现简单锁屏功能实例
2015/05/27 Javascript
jQuery实现图片走马灯效果的原理分析
2016/01/16 Javascript
javascript每日必学之基础入门
2016/02/16 Javascript
bootstrap 模态框(modal)实现水平垂直居中显示
2017/01/23 Javascript
Vue 拦截器对token过期处理方法
2018/01/23 Javascript
JS返回页面时自动回滚到历史浏览位置
2018/09/26 Javascript
javascript对HTML字符转义与反转义
2018/12/13 Javascript
微信小程序云开发之使用云数据库
2019/05/17 Javascript
微信小程序 Storage更新详解
2019/07/16 Javascript
Node.js 在本地生成日志文件的方法
2020/02/07 Javascript
Python全局变量用法实例分析
2016/07/19 Python
numpy.linspace 生成等差数组的方法
2018/07/02 Python
Python常用模块sys,os,time,random功能与用法实例分析
2020/01/07 Python
tensorflow中tf.slice和tf.gather切片函数的使用
2020/01/19 Python
Python计算信息熵实例
2020/06/18 Python
selenium切换标签页解决get超时问题的完整代码
2020/08/30 Python
GANT葡萄牙官方商店:拥有美国运动服传统的生活方式品牌
2018/10/18 全球购物
OLEDBConnection和SQLConnection有什么区别
2013/05/31 面试题
会走路的树教学反思
2014/02/20 职场文书
《落花生》教学反思
2014/02/25 职场文书
销售总经理岗位职责
2014/03/15 职场文书
家长对孩子的评语
2014/04/18 职场文书
高一新生军训方案
2014/05/12 职场文书
八项规定对照检查材料
2014/08/31 职场文书
小学国庆节活动方案策划书
2014/09/16 职场文书
话题作文之关于呼唤
2019/11/29 职场文书
Python实现视频自动打码的示例代码
2022/04/08 Python