MySQL 大事务导致其他dml阻塞

Posted 渔夫数据库笔记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL 大事务导致其他dml阻塞相关的知识,希望对你有一定的参考价值。

1.版本信息

mysql 8.0.13

2.问题描述

通过阿里云的 sql 洞察监控到某些时间点,数据库的部分dml操作耗时异常,截图如下:

#从截图中我们看到在差不多的时间点,有的dml语句执行时间异常,有些又正常。

3.问题分析

#先说结论:大事务在刷binlog cache时候阻塞了其他事务刷binlog cache的动作

3.1 根据问题时间点查看活跃事务监控信息

发现一个可以的 update 操作,这个update 是活跃连接中执行时间最长的一个。

当时存在的一些其他活跃的会话:

#这些会话的状态 waiting for handler commit (提交时等待)

 阿里云侧提供了如下信息:

(目前通过后台看是有7个大事务,产生了近7个1G左右的binlog,在刷binlog cache时候阻塞了其他事务)

 

 #阿里云给出的结论是,大事务刷binlog cache到binlog文件的动作,阻塞了其他事务的刷binlog cache操作。跟我们在活跃事务监控中看到的信息对的上

3.2 为什么相同时间点有些dml没有被阻塞?

#其实不是没有被阻塞,而是这些dml开启了显示事务,最后在commit时被阻塞(这个是在sql洞察中观察的比较清楚),如果没有sql洞察功能,也可以通过慢日志定位到执行时间异常的 commit 命令

 

NOTE:write阶段: binlog cache写到binlog file,如果binlog 特别大超过配置的cache size,会用外部文件,copy外部文件写到binlog file 成本也很高
fysnc阶段: binlog file 落盘,落盘要写文件系统journal串行的、数据多了刷盘也耗时
在commit期间,将binlog cache 和 tempfile 的event全部写入到 binlog file,并且是一个事务的event必须是连续的,也就是一个事务的event不能包含其他事务的event,这个期间需要一把mutex锁保护binlog file并发写入;

NOTE:显示的事物,不commit 语句不会刷binlog,不会阻塞,实际执行时间很快。并且显示事务binlog中 commit 命令执行时间记录的是在commit命令开始执行的时候就获取的,而不是在commit命令执行完成的时候获取的。所以如果 10:00:00 执行的commit命令,但是 10:10:00 才执行成功,那么binlog中记录的commit命令执行时间就是 10:00:00

以上是关于MySQL 大事务导致其他dml阻塞的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 大事务导致其他dml阻塞

云原生技术分享 | MySQL锁与事务的并发性

MYSQL学习笔记之事务

MySQL临时文件案例--binlog cache临时文件

MySQL监控

mysql行锁等待异常