热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

2015年1月MySQL内核报告:深入解析性能优化与GroupCommit改进

在2015年1月的MySQL内核报告中,我们详细探讨了性能优化和GroupCommit机制的改进。尽管网上已有大量关于GroupCommit的资料,本文将简要回顾其发展,并重点分析MySQL5.6及之前版本中引入的二进制日志(Binlog)对性能的影响。此外,我们还将深入讨论最新的优化措施,如何通过改进GroupCommit机制显著提升系统的整体性能和稳定性。

背景

关于Group Commit网上的资料其实已经足够多了,我这里只简单的介绍一下。

众所周知,在MySQL5.6之前的版本,由于引入了Binlog/InnoDB的XA,Binlog的写入和InnoDB commit完全串行化执行,大概的执行序列如下:

当sync_binlog=1时,很明显上述的第二步会成为瓶颈,而且还是持有全局大锁,这也是为什么性能会急剧下降。


很快Mariadb就提出了一个Binlog Group Commit方案,即在准备写入Binlog时,维持一个队列,最早进入队列的是leader,后来的是follower,leader为搜集到的队列中的线程依次写Binlog文件, 并commit事务。Percona 的Group Commit实现也是Port自Mariadb。不过仍在使用Percona Server5.5的朋友需要注意,该Group Commit实现可能破坏掉Semisync的行为,感兴趣的点击bug#1254571


Oracle MySQL 在5.6版本开始也支持Binlog Group Commit,使用了和Mariadb类似的思路,但将Group Commit的过程拆分成了三个阶段:flush stage 将各个线程的binlog从cache写到文件中; sync stage 对binlog做fsync操作(如果需要的话);commit stage 为各个线程做引擎层的事务commit。每个stage同时只有一个线程在操作。


Tips:当引入Group Commit后,sync_binlog的含义就变了,假定设为1000,表示的不是1000个事务后做一次fsync,而是1000个事务组。


Oracle MySQL的实现的优势在于三个阶段可以并发执行,从而提升效率。更进一步的理解,可以参考这篇博客


XA Recover


在Binlog打开的情况下,MySQL默认使用MYSQL_BIN_LOG来做XA协调者,大致流程为:


通过这种方式,可以让InnoDB和Binlog中的事务状态保持一致。显然只要事务在InnoDB层完成了Prepare,并且写入了Binlog,就可以从崩溃中恢复事务,这意味着我们无需在InnoDB commit时显式的write/fsync redo log。


Tips:MySQL为何只需要扫描最后一个Binlog文件呢 ? 原因是每次在rotate到新的Binlog文件时,总是保证没有正在提交的事务,然后fsync一次InnoDB的redo log。这样就可以保证老的Binlog文件中的事务在InnoDB总是提交的。


问题


其实问题很简单:每个事务都要保证其Prepare的事务被write/fsync到redo log文件。尽管某个事务可能会帮助其他事务完成redo 写入,但这种行为是随机的,并且依然会产生明显的log_sys->mutex开销。


优化


从XA恢复的逻辑我们可以知道,只要保证InnoDB Prepare的redo日志在写Binlog前完成write/sync即可。因此我们对Group Commit的第一个stage的逻辑做了些许修改,大概描述如下:


通过延迟写redo log的方式,显式的为redo log做了一次组写入,并减少了log_sys->mutex的竞争。


目前官方MySQL已经根据我们report的bug#73202锁提供的思路,对5.7.6的代码进行了优化,对应的Release Note如下:

性能数据

简单测试了下,使用sysbench, update_non_index.lua, 100张表,每张10w行记录,innodb_flush_log_at_trx_commit=2, sync_binlog=1000,关闭Gtid





推荐阅读
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 解读MySQL查询执行计划的详细指南
    本文旨在帮助开发者和数据库管理员深入了解如何解读MySQL查询执行计划。通过详细的解析,您将掌握优化查询性能的关键技巧,了解各种访问类型和额外信息的含义。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Navicat Premium 15 安装指南及数据库连接配置
    本文详细介绍 Navicat Premium 15 的安装步骤及其对多种数据库(如 MySQL 和 Oracle)的支持,帮助用户顺利完成软件的安装与激活。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
  • 在现代网络环境中,两台计算机之间的文件传输需求日益增长。传统的FTP和SSH方式虽然有效,但其配置复杂、步骤繁琐,难以满足快速且安全的传输需求。本文将介绍一种基于Go语言开发的新一代文件传输工具——Croc,它不仅简化了操作流程,还提供了强大的加密和跨平台支持。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
  • 网络运维工程师负责确保企业IT基础设施的稳定运行,保障业务连续性和数据安全。他们需要具备多种技能,包括搭建和维护网络环境、监控系统性能、处理突发事件等。本文将探讨网络运维工程师的职业前景及其平均薪酬水平。 ... [详细]
author-avatar
mobiledu2502930087
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有