MySQL 12 为什么我的MySQL会“抖”一下?
一条SQL语句,正常执行时候特别快,但有时会变得特别慢,且这种情况很难复现,随机且持续时间很短,看上去像是“抖”了一下。
你的SQL语句为什么变“慢”了
在MySQL 02中,介绍了WAL机制,InnoDB在处理更新语句时,更新内存写完redo log后,就返回给客户端,本次更新成功。
而内存里的数据最后要写入磁盘,这个操作称为flush。当内存数据页跟磁盘数据页内容不一致时,称这个内存页为脏页,内存数据写入磁盘后两者上的数据页内容一致,称为干净页。不论脏页还是干净页,都是指的内存中的数据页。
对于开头提出的场景,平时执行很快的更新操作,其实就是在写内存和日志,而“抖”的瞬间,很有可能就是在flush脏页。
有几种情况会引发数据库的flush过程:
InnoDB的redo log写满,这时候系统会停止所有的更新操作,通过flush把redo log中的checkpoint往前推进,使得redo log能有空间可以继续写;
系统内存不足。当需要新的内存页,而内存不够用,就需要淘汰一些数据页,空出内存给别的数据页。如果要淘汰的是脏页,就需要先将脏页刷到磁盘。可能会问,这种情况为什么不能直接淘汰内存,下次请求时从磁盘读入数据页,然后应用redo log?这里是从性能考虑的,对于刷脏页写盘的方法,保证每个数据页有两种状态:
内存里存在,肯定是正确结果,能直接返回;
内存里不存在,磁盘中肯定是正确结果,读入内存后返回。
MySQL认为系统“空闲”,有机会就会进行flush;
MySQL正常关闭时,会把内存的脏页都flush到磁盘,这样下次MySQL启动时,直接从磁盘读数据即可,启动速度很快。
分析上述四种情况对性能的影响:
第一种情况要尽量避免,因为这种情况下整个系统不能再更新,从监控上看更新数会跌为0;
第二种情况较常见。在InnoDB中,用缓冲池(buffer pool)管理内存,缓冲池中的内存页有三种状态:
还没有使用;
使用了且是干净页;
使用了且是脏页;
由于InnoDB策略是尽量使用内存,因此对于一个长时间运行的库来说,未被使用的页面很少。如果要读入的数据页不在内存中,就需要在缓冲池申请一个数据页,把内存中最久未使用的数据页淘汰。如果淘汰的是脏页,就需要先flush。
而如果一个查询要淘汰的脏页个数太多,会导致查询的响应时间明显变长,会明显影响性能。
第三种情况,系统没什么压力;
第四种情况,数据库本身就要关闭了,不需要太关注性能问题。
InnoDB刷脏页的控制策略
接下来讲讲控制策略,以及和策略相关的参数。
首先,需要正确告诉InnoDB所在主机的IO能力,这样InnoDB才能知道需要全力刷脏页的时候可以刷多快。这需要用到innodb_io_capacity参数,它会告诉InnoDB你的系统的磁盘能力,其值建议设置成磁盘的IOPS,而磁盘的IOPS可以通过fio工具进行测试。
知道了“全力刷脏页”的能力,但使用时不可能一直全力刷,毕竟磁盘能力不能只用来刷脏页,还需要服务用户请求。因此,需要让InnoDB控制引擎按照“全力”的一定百分比来刷页。
那么,如果设计策略控制刷脏页的速度,你会考虑哪些因素呢?考虑到如果刷太慢,内存中脏页数会太多,且redo log可能写满,因此主要参考因素就是:
脏页比例;
redo log写盘速度。
InnoDB会根据这两个因素单独算出来两个数字:
参数
innodb_max_dirty_pages_pct是脏页比例上限,默认为75%。InnoDB会根据当前脏页比例\(M\),算出一个范围在0-100间的数字,计算方法为:F1(M)
{
if M>=innodb_max_dirty_pages_pct then
return 100;
return 100*M/innodb_max_dirty_pages_pct;
}
InnoDB每次写入的日志都有一个序号,假设当前写入的序号跟checkpoint对应的序号之间的差值为\(N\)。InnoDB会根据\(N\)算出一个范围在0-100之间的数字,\(N\)越大算出来的值\(F2(N)\)越大。
根据两个数字\(F1(M)\)和\(F2(N)\),取其中较大的值记为\(R\),之后引擎可以按照innodb_io_capacity定义的能力乘以\(R\)%来控制刷脏页的速度。
上述过程的流程如图:

讲到这里你应该知道,无论是查询语句在需要内存的时候可能要求淘汰一个脏页,还是由于刷脏页会占用IO资源影响更新语句,都可能感知到MySQL“抖了一下。要尽量避免这种情况,就需要合理设置innodb_io_capacity的值,并且平时要多关注脏页比例,不要让它经常接近75%。
其中,脏页比例计算方法是Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total。
接下来,再看一个策略。
一旦一个查询请求需要在执行过程中先 flush 掉一个脏页时,这个查询就可能要比平时慢了。MySQL中有个机制,可能让查询更慢:在准备刷一个脏页的时候,如果这个数据页旁边的数据页也是脏页,就会把这个“邻居”也带着一起刷掉,那么可能不断往后顺延。
在InnoDB中,用innodb_flush_neighbors参数控制该行为,值为1会有上述机制。
这类优化在机械磁盘时代比较有意义,可以减少很多随机IO。而对IOPS比较高的设备比如SSD,建议把值设为0,因为这时候IOPS往往不是瓶颈,而只刷自己能更快执行完必要的刷脏页操作,减少SQL语句响应时间。
在MySQL 8.0中,该参数默认值已经为0了。
MySQL 12 为什么我的MySQL会“抖”一下?的更多相关文章
- 12 | 为什么我的MySQL会“抖”一下? 学习记录
		
<MySQL实战45讲>12 | 为什么我的MySQL会“抖”一下? 学习记录 http://naotu.baidu.com/file/15aa54cab2fa882c6a2a1dd52e ...
 - Ubuntu 12.04上安装MySQL并运行
		
Ubuntu 12.04上安装MySQL并运行 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 安装MySQL数据库 sudo apt-get upda ...
 - Navicat Premium 12连接ubuntu18 ,Mysql 5.7.27-0
		
1,搭建好mysql服务器,cd /etc/mysql/mysql.conf.d,进入mysql配置目录,vim mysqld.cnf 2,注释掉,bind-address =127.0.0.1 , ...
 - 【网站建设】Linux上安装MySQL - 12条命令搞定MySql
		
从零开始安装mysql数据库 : 按照该顺序执行 : a. 查看是否安装有mysql:yum list installed mysql*, 如果有先卸载掉, 然后在进行安装; b. 安装mysql客 ...
 - Linux上安装MySQL - 12条命令搞定MySql
		
从零开始安装mysql数据库 : 按照该顺序执行 : a. 查看是否安装有mysql:yum list installed mysql*, 如果有先卸载掉, 然后在进行安装; b. 安装mysql客 ...
 - Mysql学习总结(12)——21分钟Mysql入门教程
		
21分钟 MySQL 入门教程 目录 一.MySQL的相关概念介绍 二.Windows下MySQL的配置 配置步骤 MySQL服务的启动.停止与卸载 三.MySQL脚本的基本组成 四.MySQL中的数 ...
 - MySQL and Postgres command equivalents (mysql vs psql)
		
MySQL and Postgres command equivalents (mysql vs psql) 博客分类: Database From: http://blog.endpoint.c ...
 - 【转】MYSQL入门学习之七:MYSQL常用函数
		
转载地址:http://www.2cto.com/database/201212/175864.html 一.数学函数 www.2cto.com ABS(x) ...
 - Can't find file: './mysql/plugin.frm' (errno: 13)[mysql数据目录迁移错位]错误解决
		
大概需要4个步骤,其中第1步通过service mysql stop停止数据库,第4步通过service mysql start启动数据库. 第2步移动数据文件,不知道是否为Ubuntu智能的原因,移 ...
 - MySQL监控模板说明-Percona MySQL Monitoring Template for Cacti
		
http://blog.chinaunix.net/uid-16844903-id-3535535.html https://www.percona.com/doc/percona-monitorin ...
 
随机推荐
- CF1740C题解
			
众所周知,这道题的难度是 1400,所以是简单题. 分析 首先,坚信这是一道简单题,所以不要想复杂了. 首先我们需要对 aaa 数组排序,这点是肯定的,为啥应该不用我解释. 下面,我们假设 p1, ...
 - Python3处理文档_word文档(三)_向word文档中添加表格
			
利用python-docx自动生成表格 add_table()方法会返回一个Table对象.rows代表行数,cols代表列数:style代表样式,具体可以查看官方文档. 一.创建一个8行5列的表格 ...
 - 【翻译】Processing系列|(二)安卓模式的安装使用及打包发布
			
上一篇:[翻译]Processing系列|(一)简介及使用方法 下一篇:[翻译] Processing系列|(三)安卓项目构建 我的目的是在学习完成之后写出一个安卓程序,所以第二篇就是Processi ...
 - Day.js 2kb日期时间处理javascript库
			
Day.js 与 Moment.js 的比较 优点 体积小:Day.js 的体积仅为 2KB 左右,而 Moment.js 的体积约为 67KB. API 相似:Day.js 的 API 与 Mome ...
 - 信息资源管理文字题之“航空集团从哪些方面改变企业的IT服务”
			
一.材料:某航空集团公司拥有一个地域分散.多厂商.多平台.多系统的复杂IT环境.IT系统运行复杂,业务系统故障多,技术人员的被动工作方式难以适应企业IT服务需要. 要求:是运用IT服务管理关联只是为该 ...
 - vue3 基础-API-案例-ToDoList
			
前面几篇我们介绍了 compostion API 的一些基础用法, 如 setup, ref, reactive, toRefs, toRef, context 等. 本篇呢找了一个经典的 TodoL ...
 - 鸿蒙Next复杂列表性能优化:让滑动体验如丝般顺滑
			
@charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...
 - 基于CARLA/ROS的多传感器融合感知系统实战教程(附完整代码)
			
引言:为什么需要多传感器融合? 在自动驾驶系统中,单一传感器存在固有缺陷: 摄像头:易受光照影响,缺乏深度信息: 激光雷达(LiDAR):成本高,纹理信息缺失: 毫米波雷达:分辨率低,角度精度差. 本 ...
 - PyQt5高清屏幕自适应设置 QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
			
Qt Designer 设计界面: 在高清屏未设置AA_EnableHighDpiScaling的预览界面:布局字体控件尺寸上明显存在偏差. 设置了AA_EnableHighDpiScaling的预览 ...
 - 7 指纹浏览器 User-Agent 指纹伪装教程
			
目的 navigator.userAgent 是浏览器中最常被网站读取的属性之一,用于识别浏览器内核.版本.操作系统信息,甚至设备类型.它是构成浏览器指纹的关键字段,广泛应用于用户识别.设备分类.风控 ...