平时的工作中,不知道你有没有遇到过这样的场景,一条 SQL 语句,正常执行的时候特别快,但是有时也不知道怎么回事,它就会变得特别慢,并且这样的场景很难复现,它不只随机,而且持续时间还很短。

当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”。

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

那么,什么情况会引发数据库的 flush 过程呢?

第一种场景是InnoDB 的 redo log 写满了,这时候系统会停止所有更新操作,把 checkpoint 往前推进,redo log 留出空间可以继续写。

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

第三种场景对应的就是 MySQL 认为系统“空闲”的时候。当然,MySQL忙起来可是会很快就能把redo log 记满的,所以要合理地安排时间,即使是忙的时候,也要见缝插针地找时间,只要有机会就刷一点“脏页”。

第四种场景对应的就是 MySQL 正常关闭的情况。这时候,MySQL 会把内存的脏页都 flush 到磁盘上,这样下次 MySQL 启动的时候,就可以直接从磁盘上读数据,启动速度会很快。

接下来,你可以分析一下上面四种场景对性能的影响。

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

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

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

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

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

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

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

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

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

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

InnoDB 刷脏页的控制策略

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

这就要用到 innodb_io_capacity 这个参数了,它会告诉 InnoDB 你的磁盘能力。

现在你知道了,InnoDB 会在后台刷脏页,而刷脏页的过程是要将内存页写入磁盘。所以,无论是你的查询语句在需要内存的时候可能要求淘汰一个脏页,还是由于刷脏页的逻辑会占用 IO 资源并可能影响到了你的更新语句,都可能是造成你从业务端感知到 MySQL“抖”了一下的原因。

要尽量避免这种情况,你就要合理地设置 innodb_io_capacity 的值,并且平时要多关注脏页比例(参数 innodb_max_dirty_pages_pct),不要让它经常接近 75%。

Mysql的刷脏页问题的更多相关文章

  1. MySQL:刷脏页

    1. 脏页,干净页 当内存数据页和磁盘数据页上的内容不一致时,我们称这个内存页为脏页: 内存数据写入磁盘后,内存页上的数据和磁盘页上的数据就一致了,我们称这个内存页为干净页. 2. 刷脏页的时机 2. ...

  2. 【MySQL 读书笔记】SQL 刷脏页可能造成数据库抖动

    开始今天读书笔记之前我觉得需要回顾一下当我们在更新一条数据的时候做了什么. 因为 WAL 技术的存在,所以当我们执行一条更新语句的时候是先写日志,后写磁盘的.当我们在内存中写入了 redolog 之后 ...

  3. Innodb刷脏页技术深度挖掘

    DBA某数据库集群每日17:00左右会出现一个性能陡降的现象,在10~20秒内主库出现大量慢查询.这些查询本身没有性能问题,也没有任何关联,可以认为是由于数据库系统负载较重,由于并发导致的慢查询.通过 ...

  4. MySQL中InnoDB脏页刷新机制Checkpoint

    我们知道InnoDB采用Write Ahead Log策略来防止宕机数据丢失,即事务提交时,先写重做日志,再修改内存数据页,这样就产生了脏页.既然有重做日志保证数据持久性,查询时也可以直接从缓冲池页中 ...

  5. MySQL所谓的脏页和“抖”一下是什么联系?

    在我们平时经常用到的sql更新语句,之前是认为只要sql执行,当前sql的操作会立马执行到服务器磁盘上并返回,但是后来我才知道,事实并非如此,在了解事实之前,首先可能需要先了解什么是redo log, ...

  6. 面试题:了解MySQL的Flush-List吗?顺便说一下脏页的落盘机制!(文末送书)

    Hi,大家好!我是白日梦! 今天我要跟你分享的MySQL话题是:"了解Flush-List吗?顺便说一下脏页的落盘机制!(文末送书)" 本文是MySQL专题的第 8 篇,共110篇 ...

  7. InnoDB Redo Flush及脏页刷新机制深入分析

    概要: 我们知道InnoDB采用Write Ahead Log策略来防止宕机数据丢失,即事务提交时,先写重做日志,再修改内存数据页,这样就产生了脏页.既然有重做日志保证数据持久性,查询时也可以直接从缓 ...

  8. redis存在大量脏页问题的追查记录

    from:https://www.zybuluo.com/SailorXiao/note/136014 case现场 线上发现一台机器内存负载很重,top后发现一个redis进程占了大量的内存,TOP ...

  9. Checkpoint--查看各DB上的脏页

    可以使用sys.dm_os_buffer_descriptors来看数据页在buffer pool中的状态,其中is_modified来标示数据页是否为脏页 --------------------- ...

随机推荐

  1. dfs序七个经典问题(转)

    我这个人不怎么喜欢写轻重链剖分和LCT 还是喜欢dfs序.括号序列之类的 毕竟线段树好写多了 然后就有了这篇转载的文章 写在这边以后有时间看看 原文链接:https://www.cnblogs.com ...

  2. 特征点检测学习_2(surf算法)

    依旧转载自作者:tornadomeet 出处:http://www.cnblogs.com/tornadomeet 特征点检测学习_2(surf算法) 在上篇博客特征点检测学习_1(sift算法) 中 ...

  3. 51nod 1684 子集价值

    lyk最近在研究位运算. 它发现除了xor,or,and外还有很多运算. 它新定义了一种运算符“#”. 具体地,可以由4个参数来表示. ai,j表示 i#j. 其中i,j与a的值均∈[0,1]. 当然 ...

  4. 洛谷P2344 奶牛抗议

    题目背景 Generic Cow Protests, 2011 Feb 题目描述 约翰家的N 头奶牛正在排队游行抗议.一些奶牛情绪激动,约翰测算下来,排在第i 位的奶牛的理智度为Ai,数字可正可负. ...

  5. 中南多校对抗赛 第三场 E

    E:Eulerian Flight Tour 题意: 给你一张无向图,要你给这个图加边使得其形成一个欧拉回路 题解: 首先使得所有节点的度都为偶数,然后将这个图联通起来 对于度为奇数的点,将将他和他的 ...

  6. CSU 多校训练第二场 J Pinemi Puzzles

    传送门:http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=2279 题意: 代码: #include <set> #incl ...

  7. centos 前端环境搭建

    Node.js 安装 wget 下载安装 yum -y install gcc make gcc-c++ openssl-devel wget node v6.11.0 下载 wget https:/ ...

  8. python的StringIO模块

    StringIO经常被用来作字符串的缓存,因为StringIO的一些接口和文件操作是一致的,也就是说同样的代码,可以同时当成文件操作或者StringIO操作. 一.StringIO中的常用方法 1.r ...

  9. 「Python」python-nmap安装与入门

    1.安装namp https://nmap.org/download.html 下载链接 PS:windows安装似乎麻烦一些,需要多下载npcap,官网有链接 2.python安装 注意,注意,注意 ...

  10. 前端PHP入门-010-内部函数

    内部函数,是指在函数内部又声明了一个函数. 注意事项: 内部函数名,不能是已存在的函数名 假设在函数a里面定义了一个内部函数,不能调用两次函数a. <?php function foo() { ...