有时候会出现这么一种情况:一条 SQL 语句,正常执行的时候特别快,但是有时也不知道怎么回事,它就会变得特别慢,并且这样的场景很难复现,它不只随机,而且持续时间还很短。

SQL语句为何变慢了

根据之前MySQL更新语句的学习,可以知道InnoDB 在处理更新语句的时候,只做了写日志这一个磁盘操作。这个日志叫作 redo log(重做日志),在更新内存写完 redo log 后,就返回给客户端,本次更新成功。做个比喻,也就是《孔乙己》里咸亨酒店掌柜用来记账的粉板,在更新内存写完 redo log 后,就返回给客户端,本次更新成功。

做下类比的话,掌柜记账的账本是数据文件,记账用的粉板是日志文件(redo log),掌柜的记忆就是内存

掌柜总要找时间把账本更新一下,这对应的就是把内存里的数据写入磁盘的过程,术语就是 flush。在这个 flush 操作执行之前,孔乙己的赊账总额,其实跟掌柜手中账本里面的记录是不一致的。因为孔乙己今天的赊账金额还只在粉板上,而账本里的记录是老的,还没把今天的赊账算进去。当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”

不论是脏页还是干净页,都在内存中。在这个例子里,内存对应的就是掌柜的记忆。

对应文章开头的问题: 平时执行很快的更新操作,其实就是在写内存和日志,而 MySQL 偶尔“抖”一下的那个瞬间,可能就是在刷脏页(flush)。

什么情况下会flush

1、第一种场景就是粉板满了,记不下了,如果这时候还有人来记账,就只能放下手上的活,将粉板上的记录擦掉一些,留出空位以便继续记账。当然在擦掉之前,必须先将正确的账目记录到账本中才行。这个场景,对应的就是 InnoDB 的 redo log 写满了。这时候系统会停止所有更新操作,把 checkpoint 往前推进,redo log 留出空间可以继续写。

checkpoint 可不是随便往前修改一下位置就可以的。比如图中,把 checkpoint 位置从 CP 推进到 CP’,就需要将两个点之间的日志(浅绿色部分),对应的所有脏页都 flush 到磁盘上。之后,图中从 write pos 到 CP’之间就是可以再写入的 redo log 的区域。

2、第二种场景是,这一天的生意太好了,需要记住的东西太多了,发现自己脑袋里面记不住这么多东西了,赶紧把当前的一些账记入账本中。

这种场景,对应的就是系统内存不足。当需要新的内存页,而内存不够用的时候,就要淘汰一些数据页空出内存给别的数据页使用。如果淘汰的是“脏页”,就要先将脏页写到磁盘。

为什么不直接淘汰掉内存,下次需要请求的时候,从磁盘读入数据页,然后拿 redo log 出来应用不就行了?主要还是从性能角度出发,如果刷脏页一定会写盘,就保证了每个数据页有两种状态:

  • 一种是内存里存在,内存里就肯定是正确的结果,直接返回;
  • 另一种是内存里没有数据,就可以肯定数据文件上是正确的结果,读入内存后返回。

3、第三种场景是生意不忙的时候,或者打烊之后。这时候柜台没事,掌柜闲着也是闲着,不如更新账本。这种场景,对应的就是 MySQL 认为系统“空闲”的时候。当然,MySQL“这家酒店”的生意好起来可是会很快就能把粉板记满的,所以“掌柜”要合理地安排时间,即使是“生意好”的时候,也要见缝插针地找时间,只要有机会就刷一点“脏页”

4、第四种场景是,年底了咸亨酒店要关门几天,需要把账结清一下。这时候掌柜要把所有账都记到账本上,这样过完年重新开张的时候,就能就着账本明确账目情况了。
这种场景,对应的就是 MySQL 正常关闭的情况。这时候,MySQL 会把内存的脏页都 flush 到磁盘上,这样下次 MySQL 启动的时候,就可以直接从磁盘上读数据,启动速度会很快。

四种刷盘场景对MySQL性能的影响

其中,第三种情况是属于 MySQL 空闲时的操作,这时系统没什么压力,而第四种场景是数据库本来就要关闭了。这两种情况下,不会太关注“性能”问题。所以这里,我们主要来分析一下前两种场景下的性能问题。

第一种是“redo log 写满了,要 flush 脏页”,这种情况是 InnoDB 要尽量避免的。因为出现这种情况的时候,整个系统就不能再接受更新了,所有的更新都必须堵住。如果你从监控上看,这时候更新数会跌为 0

第二种是“内存不够用了,要先将脏页写到磁盘”,这种情况其实是常态。InnoDB 用缓冲池(buffer pool)管理内存,缓冲池中的内存页有三种状态:

  • 第一种是,还没有使用的;
  • 第二种是,使用了并且是干净页;
  • 第三种是,使用了并且是脏页

InnoDB 的策略是尽量使用内存,因此对于一个长时间运行的库来说,未被使用的页面很少

而当要读入的数据页没有在内存的时候,就必须到缓冲池中申请一个数据页。这时候只能把最久不使用的数据页从内存中淘汰掉:如果要淘汰的是一个干净页,就直接释放出来复用;但如果是脏页呢,就必须将脏页先刷到磁盘,变成干净页后才能复用

所以,刷脏页虽然是常态,但是出现以下这两种情况,都是会明显影响性能的:

  1. 一个查询要淘汰的脏页个数太多,会导致查询的响应时间明显变长;

  2. 日志写满,更新全部堵住,写性能跌为 0,这种情况对敏感业务来说,是不能接受的。

InnoDB 需要有控制脏页比例的机制,来尽量避免上面的这两种情况。

InnoDB 刷脏页的控制策略

首先,要正确地告诉 InnoDB 所在主机的 IO 能力,这样 InnoDB 才能知道需要全力刷脏页的时候,可以刷多快

这就要用到 innodb_io_capacity 这个参数了,它会告诉 InnoDB 你的磁盘能力。这个值我建议你设置成磁盘的 IOPS。磁盘的 IOPS 可以通过 fio 这个工具来测试,下面的语句是我用来测试磁盘随机读写的命令:

 fio -filename=$filename -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=16k -size=500M -numjobs=10 -runtime=10 -group_reporting -name=mytest

MySQL——MySQL的flush相关推荐

  1. mysql reflush pri_Mysql Flush privileges命令的功能与使用

    flush privileges 命令本质上的作用是将当前user和privilige表中的用户信息/权限设置从mysql库(MySQL数据库的内置库)中提取到内存里.MySQL用户数据和权限有修改后 ...

  2. 虚拟机CENTOS7下 安装8.0版本MySQL MySQL主从配置详细~

    全部代码,写在后面吧! 全部的代码在后面. 1.安装mysql 先rz命令上传一下!出现未响应是很正常的情况!等会就好啦. ls查看一下,已经出现啦~ xz -d mysql-8.0.13-linux ...

  3. mysql:mysql error:Access denied for user 'root'@'localhost' (using password: YES)

    在给服务器添加用户的时候,一不小心添加主机名错误.我直接把ip给添加上去了,这就十分尴尬了,然后在修改的时候碰到了这个问题,记录一下. 一.mysql添加用户时的操作: insert into mys ...

  4. mysql use mysql_1、设置mysql远程访问执行mysql 命令进入mysql 命令模式,执行如下SQL代码mysql use mysql; mysql GRANT ALL ON ...

    1.设置mysql远程访问 执行mysql 命令进入mysql 命令模式,执行如下SQL代码mysql> use mysql; mysql> GRANT ALL ON *.* TO adm ...

  5. mysql 单机双实列_{ mysql } MySQL单机多实例及主从复制

    没有过多的,直接上码 my.cnf [mysql_multi] mysqld = /usr/bin/mysqld_safe mysqladmin = /usr/bin/mysqladmin user ...

  6. chown –r mysql:mysql,mysql部署,操作及异常处理

    1.将mysql-5.1.50-linux-x86_64-glibc23.tar.gz移至/usr/local/目录下,并改名为mysql 增加mysql组 #groupadd mysql 建mysq ...

  7. db mysql / mysql dba / mysql manual / mysql config / mysql innotop

    MySQL 5.1 Reference Manual http://dev.mysql.com/doc/refman/5.1/en/ Including MySQL Cluster NDB 6.X/7 ...

  8. MySQL mysql性能调优

    MySQL性能调优,SQL优化.索引优化 慢查询日志 当查询超过一定的时间没有返回结果的时候,才会记录到慢查询日志中.默认不开启. 采样的时候手工开启.可以帮助我们找出执行慢的 SQL 语句 查看慢 ...

  9. MySQL——MySQL高可用之PXC

    PXC简介 参考 Percona 官方 https://www.percona.com/ PXC(Percona XtraDB Cluster)是一个开源的MySQL高可用解决方案.它将Percona ...

  10. net start mysql MySQL 服务正在启动 . MySQL 服务无法启动。 服务没有报告任何错误。

    在启动项目时,发现昨天能够跑的项目今天跑不了了.一看原来是mysql数据库出现了问题,远程数据库连不上了.那这可咋整啊?用管理员模式启动dos,输入net start mysql: 出现问题:MySQ ...

最新文章

  1. 为什么有些高级开发不喜欢 Python?
  2. 2021.04.07 oppo HR面
  3. win7下构建swarm nodes实现跨host的容器之间的通信
  4. 数据结构源码笔记(C语言):直接插入排序
  5. 好物推荐:notion想同步什么东西,直接在这里写就可以,不用再发消息,真棒
  6. 9 操作系统第二章 进程管理 管程
  7. excel删除空行_教你简单小妙招将Excel里重复的数据筛选出来!
  8. Android BottomNavigationBar导航栏
  9. iTween for Unity
  10. Julia : 中文字符串的取值 UnicodeError 及解决方案
  11. 【技术白皮书】第四章:信息抽取技术产业应用现状及案例(上)
  12. 华为USG6000基本内容总结
  13. ubuntu22 使用todesk被远程控制时显示黑屏或者白屏
  14. 【最终幻想15 国王之剑】制作介绍1:不再是游戏动画,而是“电影”制作
  15. 基于metpy库画T-LnP图(国内主流形式,并非斜温)
  16. kurento和打洞的服务器的安装及部署
  17. PMM使用Grafana告警
  18. 中国燃料电池行业“十四五”规划及需求规模分析报告2021-2027年
  19. 竞争性谈判和竞争性磋商的区别
  20. 类似蘑菇街、迷尚的流瀑布图片展示Demo

热门文章

  1. HTML设置文字和图片居中
  2. MySQL连接查询,子查询,union(合并),分页
  3. echarts 饼图 labelLine
  4. android震动代码分析
  5. 使用adb 命令时提示“adb”既不是内部或外部命令,也不是可运行的程序
  6. Word2007 表格换页自动“续表”方法
  7. 儿童用白炽灯和护眼灯哪个好?推荐适合儿童使用的护眼灯
  8. 【OBS-STUDIO】OBSApp: OBS入口类
  9. 最详细的XAMPP的安装及使用教程(图文)
  10. CAD—dwg格式解析库:libdxfrw和libredwg