当前位置: 主页 > 数据库

数据库commit-景观大数据素材库

发布时间:2023-02-08 22:47   浏览次数:次   作者:佚名

概述

对于支持事务的关系型数据库,事务的完成需要执行commit命令,commit命令用于保存事务操作的相关日志,标记事务完成,保证数据的一致性。 通常commit命令的执行速度非常快,但是commit可能会成为性能瓶颈,影响数据库的整体性能。

案例分析

慢日志分析

136be34314a57ba454d97dfa8ef5d707.png

根据慢日志分析,commit操作平均耗时将近1分钟,不正常。

MySQL 提交机制

为了保证binlog和redolog中事务的一致性,mysql数据库采用了两阶段提交(2pc)机制:

社工库已整理22g数据_数据库commit_景观大数据素材库

准备阶段

Innodb write/sync transaction redo, undolog, binlog 什么都不做。

提交阶段

mysql层write/syncbinlog,innodb write commit to redolog。

从这个机制可以看出commit操作包含了binlog的登陆动作。 这会延长提交操作时间并成为性能瓶颈。 为了优化这个性能问题,mysql5.6引入了group commit机制。

binlog分组提交的基本思想是引入队列机制,保证innodb commit的顺序与binlog入库顺序一致,分组事务,分组内的binlog刷盘动作分配给一个事务达到群投的目的。

binlog提交将提交分为三个阶段,FLUSH阶段、SYNC阶段和COMMIT阶段。 基本流程如下:

FLUSH阶段

数据库commit_景观大数据素材库_社工库已整理22g数据

Hold Lock_log mutex [leader持有,follower等待]

获取队列中的一组binlog(队列中的所有事务)

将 binlog 缓冲区放入 I/O 缓存

通知dump线程转储binlog

同步阶段

释放 Lock_log mutex,hold Lock_sync mutex [leader holds, follower waits]

放一组binlog到磁盘(sync动作,最耗时,假设sync_binlog为1)

COMMIT阶段

数据库commit_景观大数据素材库_社工库已整理22g数据

释放Lock_sync mutex,hold Lock_commit mutex [leader holds, follower waits]

遍历队列中的事务,逐一执行innodb commit

释放 Lock_commit 互斥体

唤醒队列中等待的线程

分组提交就是每次同步一组binlog以提高效率,一组binlog的数量由以下两个参数决定:

binlog_group_commit_sync_delay=N:等待Nμs后,开始事务flush

binlog_group_commit_sync_no_delay_count=N:如果队列中的事务数达到N,忽略binlog_group_commit_sync_delay的设置

数据库参数分析

景观大数据素材库_社工库已整理22g数据_数据库commit

参数名称

参数值

sync_binlog

1个

binlog_group_commit_sync_delay

1个

binlog_group_commit_sync_no_delay_count

1000

景观大数据素材库_社工库已整理22g数据_数据库commit

以上参数为数据库发生故障时的参数设置。 可以看到binlog_group_commit_sync_delay设置为1微秒,即1微秒内同步一组binlog,对于高并发dml操作的IO压力比较大; sync_binlog 参数在组提交机制中。 意思也变了,官方文档如下:

136be34314a57ba454d97dfa8ef5d707.png

当sync_binlog设置为0或1时,将在binlog_group_commit_sync_delay时间后同步一组binlog; 当sync_binlog设置为N(N>1)时,经过binlog_group_commit_sync_delay时间后,将同步N组binlog。

所以整体来说,故障时dml操作比较多,而且由于数据库参数设置为1个subtle sync和一组binlog数据库commit,对IO压力很大,select查询比较多同时,此时IO已经达到限制,最终导致commit被阻塞,事务不能及时释放资源,其他dml操作不能及时获取事务锁,io等资源,从而延长执行时间处理时间。

总结

由于数据库设置为1微秒同步一组binlog,在大并发dml操作时对IO造成很大压力,导致commit阻塞,导致其他dml操作超时执行。 由于binlog的sync运行成本比较高,可以通过增加每组的binlog数量和每次sync的binlog组数量来降低IO压力。

如果设置sync_binlog为1,commit操作需要等待binlog_group_commit_sync_delay时间完成,会阻塞commit操作。 如果设置过大的值(如:1000),一次syncbinlog的量比较大,容易造成IO波动。 如果存大笔交易数据库commit,那么IO波动会更大。

如果binlog_group_commit_sync_delay设置的太小,每个group的binlog数量就会少,无法实现group commit带来的性能优化。 如果设置过大,commit操作会阻塞很长时间,binlog事务会过大。

binlog_group_commit_sync_delay最好设置为10的倍数,否则会导致如下bug: