资讯专栏INFORMATION COLUMN

mysql commit 引起的性能问题

IT那活儿 / 3164人阅读
mysql commit 引起的性能问题


概述



对于支持事务的关系型数据库来说,事务的完成需要执行commit命令,用于保存该事务操作的相关日志、标记该事务已完成,确保数据的一致性。通常情况下,commit命令执行很快,但也会存在commit是性能瓶颈,影响整体数据库性能的情况发生。




案例分析



慢日志分析

对慢日志分析可见,commit操作平均耗时近1分钟是非正常现象。


MySQL commit机制

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

  • prepare阶段

innodb write/sync事务redo、undolog,binlog不做任何操作。


  • commit阶段

mysql层write/syncbinlog,innodb写 commit 至redolog。

从这个机制可以看出,commit操作包括binlog的落地动作。这就延长了commit动作的时间,也成了一个性能瓶颈,为了优化这一性能问题,mysql5.6推出了组提交机制。


binlog组提交的基本思想是,引入队列机制保证innodb commit顺序与binlog落盘顺序一致,并将事务分组,组内的binlog刷盘动作交给一个事务进行,实现组提交目的。


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


FLUSH 阶段

  1. 持有Lock_log mutex [leader持有,follower等待]

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

  3. 将binlog buffer到I/O cache

  4. 通知dump线程dump binlog


SYNC阶段

  1. 释放Lock_log mutex,持有Lock_sync mutex[leader持有,follower等待]

  2. 将一组binlog 落盘(sync动作,最耗时,假设sync_binlog为1)


COMMIT阶段

  1. 释放Lock_sync mutex,持有Lock_commit mutex[leader持有,follower等待]

  2. 遍历队列中的事务,逐一进行innodb commit

  3. 释放Lock_commit mutex

  4. 唤醒队列中等待的线程


组提交就是每次sync一组binlog,从而提升效率,而一组binlog的数量则由以下两个参数决定:


  • binlog_group_commit_sync_delay=N:在等待N μs后,开始事务刷盘

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




数据库参数分析



参数名

参数值

sync_binlog

1

binlog_group_commit_sync_delay

1

binlog_group_commit_sync_no_delay_count

1000


以上参数为故障发生时数据库的参数设置,可以看binlog_group_commit_sync_delay设置为1微妙,即1微妙内sync一组binlog,这对于高并发的dml操作而言对IO压力相对比较大;sync_binlog参数在组提交机制下其意义也发生了变化,官方文档如下:


当sync_binlog设置为0或1时,binlog_group_commit_sync_delay时间后sync一组binlog;当sync_binlog设置N(N>1)时binlog_group_commit_sync_delay时间后syncN组binlog。


所以整体上看,故障发生时有大量的dml操作,且因为数据库的参数设置1微妙sync一组binlog,对IO造成了很大压力,再加上同时有大量的select查询,此刻IO已经达到极限,最终造成commit提交阻塞,事务不能及时释放资源,其它dml操作因不能及时获取事务锁、io等资源而延长执行时间。




总结


由于数据库设置为1微妙sync一组binlog,在大并发dml操作时对IO造成很大压力,造成commit阻塞和其它dml操作执行延长。由于binlog的sync操作代价相对较高,因此可以增加每组binlog的数量、每次syncbinlog组的数量,减轻对IO的压力。


设置sync_binlog为1,则commit操作需要等待binlog_group_commit_sync_delay时间才能完成,阻塞了commit操作,设置太大的值(如:1000),则一次syncbinlog量比较大,很容易造成IO波动,如果存大大事务,则IO波动会更大。


binlog_group_commit_sync_delay设置太小,则每组中binlog数量较小,起不到组提交带来的性能优化,设置太大则阻塞了commit操作很长时间且binlog事务太大。


binlog_group_commit_sync_delay最好设置为10的倍数,不然会引起如下bug:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/130192.html

相关文章

  • Java知识点总结(JDBC-事务)

    摘要:隔离级别个等级的事务隔离级别,在相同的数据环境下,使用相同的输入,执行相同的工作,根据不同的隔离级别,可以导致不同的结果。不同事务隔离级别能够解决的数据并发问题的能力是不同的。 Java知识点总结(JDBC-事务) @(Java知识点总结)[Java, JDBC] 事务 事务基本概念 一组要么同时执行成功,要么同时执行失败的 SQL 语句。是数据库操作的一个执行单元! 事务开始于:...

    Zachary 评论0 收藏0
  • JavaWEB开发13——事务与连接池

    摘要:一致性一个事务中,事务前后数据的完整性必须保持一致。持久性持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。 一、事务概述1.什么是事务一件事情有n个组成单元 要不这n个组成单元同时成功 要不n个单元就同时失败就是将n个组成单元放到一个事务中2.mysql的事务默认的事务:一条sql语句就是一个事务 默认就开启事务并提交事...

    13651657101 评论0 收藏0
  • 记一次 Mybatis 一级缓存清理无效引起源码走读

    摘要:今天对象在学习时发现对象的方法并不能清理一级缓存同一下相同查询条件返回的结果还是旧值。测试代码如下上网搜索网上搜索找到了相同问题并没有人解答。例如查看官方文档实例有一个本地缓存在执行和时被清理。要明确地关闭它获取打算做更多的工作你可以调用。 今天对象在学习 Mybatis 时发现 org.apache.ibatis.session.SqlSession 对象的 clearCache()...

    voyagelab 评论0 收藏0

发表评论

0条评论

IT那活儿

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<