MySQL慢日志slow_log为何会出现Prepare与Binlog Dump

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介: 尝试分析MySQL慢日志slow_log为何会出现Prepare与Binlog Dump

MySQL慢日志为何会出现Prepare与Binlog Dump

问题现象

某客户的RDS数据库的某个时间段(时间点),慢日志记录出现大量的Prepare操作以及零星的Binlog Dump操作,如下图:

Prepare:
1.jpg

Binlog dump:
2.jpg

问题分析

慢日志中出现Prepare分析

MySQL预处理语句

Prepare是MySQL的预处理命令,其在MySQL server实现了请求的预处理,当我们使用MySQL shell client的时候,可以通过如下方式进行请求:

mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> SET @a = 3;
mysql> SET @b = 4;
mysql> EXECUTE stmt1 USING @a, @b;
+------------+
| hypotenuse |
+------------+
|          5 |
+------------+

当我们在开发应用程序时,在代码中使用时,可以通过如下方式请求(下图为JAVA代码):

String selectSql = "select * from alitest where a = ? or b = ?";
PreparedStatement pretest =  conn.prepareStatement(selectSql);
pretest.setInt(1, 1);
pretest.setInt(2, 2);
ResultSet res = pretest.executeQuery();

注意:在使用JAVA时,由于预处理既可以在客户端实现也可以在SERVER侧实现,要使程序使用SERVER侧的预处理,需要在建连时打开:useServerPrepStmts=true,即:jdbc:mysql://XXX.XXX.XXX.XXX:3306/alitest?useServerPrepStmts=true

MySQL对预处理请求进行Prepare的函数

从/mysql-5.6.24/sql/sql_prepare.cc源码文件中,可以找到进行Prepare的函数:Prepared_statement::prepare()。它的主要作用是 Parse statement text, validate the statement, and prepare it for execution。

MySQL记录慢日志的函数

从/mysql-5.6.24sql/sql_parse.cc源码文件中,可以找到进行慢日志记录的函数:log_slow_statement(THD *thd),它的主要作用是Check whether we need to write the current statement to the slow query log。

复现问题

慢日志中出现Prepare,是否是因为Prepared_statement::prepare()函数处理请求过慢超过long_query_time导致?为了验证这个猜测,模拟Prepared_statement::prepare()函数处理慢的情况,人工的通过GDB对Prepared_statement::prepare()设置断点,增加其执行时间,然后通过MySQL shell client 与JAVA代码分别请求,查看慢日志的记录情况。

设置断点

(gdb) b Prepared_statement::prepare
Breakpoint 1 at 0x7d821e: file /opt/mysql-5.6.24/sql/sql_prepare.cc, line 3358.

MySQL shell client 执行如下命令

mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';

(命令阻塞......)

命令阻塞后,等待超过long_query_time的时间,然后在GDB中执行continue继续运行命令,PREPARE命令执行完成后,查看慢日志如下:

*************************** 15. row ***************************
    start_time: 2020-08-22 18:34:45
     user_host: root[root] @ localhost []
    query_time: 00:04:56
     lock_time: 00:00:00
     rows_sent: 0
 rows_examined: 0
            db:
last_insert_id: 0
     insert_id: 0
     server_id: 2003306
      sql_text: PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'
     thread_id: 171

从慢日志的记录来看,这不是我们想要的结果。

JAVA执行Prepare请求:

调用JAVA代码(请记住连接时启用useServerPrepStmts),执行Prepare操作,请求阻塞后,等待超过long_query_time的时间,然后在GDB中执行continue继续运行命令,JAVA代码执行完成后,查看慢日志如下:

************************* 7. row ***************************
    start_time: 2020-08-22 18:57:45
     user_host: dtstest[dtstest] @  [115.216.4.201]
    query_time: 00:00:09
     lock_time: 00:00:00
     rows_sent: 0
 rows_examined: 0
            db: alitest
last_insert_id: 0
     insert_id: 0
     server_id: 2003306
      sql_text: Prepare
     thread_id: 163

可以看到,Prepare命令被记录到了慢日志中。

慢日志中出现Binlog dump分析

MySQL的Binlog dump命令

当我们搭建MySQL的从库时,需要从主库获取binlog文件,而Binlog dump(或者Binlog dump gtid)命令就是用来该功能的。MySQL中有2个关于Binlog dump的函数,分别是com_binlog_dump()与com_binlog_dump_gtid(),后者主要应用于开启了GTID的复制。可以在/mysql-5.6.24/sql/rpl_master.cc中找到它们。根据之前的猜测,慢日志中出现Binlog dump(或者Binlog dump GTID)是否是因为对应的函数处理慢导致?

复现问题

设置断点

(gdb) b com_binlog_dump
Breakpoint 3 at 0xa12318: file /opt/mysql-5.6.24/sql/rpl_master.cc, line 739.

启动binlog dump

为了测试方便,直接使用mysqlbinlog程序远程获取binlog:

/bin/mysqlbinlog -hxxx.xxx.xxx.xxx -udtstest -p --read-from-remote-server mysqlbin.000004

(命令阻塞......)

命令阻塞后,等待超过long_query_time的时间,然后在GDB中执行continue继续运行命令,mysqlbinlog命令执行完成后,查看慢日志如下:

************************* 34. row ***************************
    start_time: 2020-08-22 20:57:38
     user_host: dtstest[dtstest] @  [121.196.185.131]
    query_time: 00:00:00
     lock_time: 00:00:00
     rows_sent: 0
 rows_examined: 0
            db:
last_insert_id: 0
     insert_id: 0
     server_id: 2003306
      sql_text: Binlog Dump
     thread_id: 466

可以看到,Binlog Dump命令被记录到了慢日志中。

注意:由于Binlog dump属于admin statement,复现问题时,需要把log_slow_admin_statements设置为ON。慢日志才会记录admin statements。

问题结论

慢日志中出现Binlog dump、Binlog dump GTID、Prepare命令,是由于对应的请求执行超过long_query_time导致。出现这种情况,一般意味着系统负载可能较高,尤其是Prepare等命令的出现,需要引起关注。

后记

如果想要更加方便的复现该问题,可以把long_query_time参数设置为0(这样可以避免通过GDB来手动干预命令的耗时),然后调用JAVA代码以及mysqlbinlog程序进行验证。

相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
8月前
|
SQL 运维 关系型数据库
深入探讨MySQL的二进制日志(binlog)选项
总结而言,对MySQL binlogs深度理解并妥善配置对数据库运维管理至关重要;它不仅关系到系统性能优化也是实现高可靠性架构设计必须考虑因素之一。通过精心规划与周密部署可以使得该机能充分发挥作用而避免潜在风险带来影响。
263 6
|
9月前
|
存储 SQL 关系型数据库
MySQL中binlog、redolog与undolog的不同之处解析
每个都扮演回答回溯与错误修正机构角色: BinLog像历史记载员详细记载每件大大小小事件; RedoLog则像紧急救援队伍遇见突發情況追踪最后活动轨迹尽力补救; UndoLog就类似时间机器可倒带历史让一切归位原始样貌同时兼具平行宇宙观察能让多人同时看见各自期望看见历程而互不干扰.
549 9
|
监控 容灾 算法
阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化
本文探讨了如何高效、经济且可靠地将海外应用与基础设施日志统一采集至阿里云日志服务(SLS),解决全球化业务扩展中的关键挑战。重点介绍了高性能日志采集Agent(iLogtail/LoongCollector)在海外场景的应用,推荐使用LoongCollector以获得更优的稳定性和网络容错能力。同时分析了多种网络接入方案,包括公网直连、全球加速优化、阿里云内网及专线/CEN/VPN接入等,并提供了成本优化策略和多目标发送配置指导,帮助企业构建稳定、低成本、高可用的全球日志系统。
1181 55
|
10月前
|
存储 SQL 关系型数据库
MySQL的Redo Log与Binlog机制对照分析
通过合理的配置和细致的管理,这两种日志机制相互配合,能够有效地提升MySQL数据库的可靠性和稳定性。
342 10
|
SQL 监控 关系型数据库
MySQL日志分析:binlog、redolog、undolog三大日志的深度探讨。
数据库管理其实和写小说一样,需要规划,需要修订,也需要有能力回滚。理解这些日志的作用与优化,就像把握写作工具的使用与运用,为我们的数据库保驾护航。
836 23
|
SQL 运维 关系型数据库
MySQL Binlog 日志查看方法及查看内容解析
本文介绍了 MySQL 的 Binlog(二进制日志)功能及其使用方法。Binlog 记录了数据库的所有数据变更操作,如 INSERT、UPDATE 和 DELETE,对数据恢复、主从复制和审计至关重要。文章详细说明了如何开启 Binlog 功能、查看当前日志文件及内容,并解析了常见的事件类型,包括 Format_desc、Query、Table_map、Write_rows、Update_rows 和 Delete_rows 等,帮助用户掌握数据库变化历史,提升维护和排障能力。
|
存储 SQL 关系型数据库
mysql 的ReLog和BinLog区别
MySQL中的重做日志和二进制日志是确保数据库稳定性和可靠性的关键组件。重做日志主要用于事务的持久性和原子性,通过记录数据页的物理修改信息来恢复未提交的事务;而二进制日志记录SQL语句的逻辑变化,支持数据复制、恢复和审计。两者在写入时机、存储方式及配置参数等方面存在显著差异。
348 6
|
canal 消息中间件 关系型数据库
Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
【9月更文挑战第1天】Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
2302 4
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
1984 2

推荐镜像

更多