前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL的刷脏机制

MySQL的刷脏机制

作者头像
向着百万年薪努力的小赵
发布2022-12-02 10:28:29
5490
发布2022-12-02 10:28:29
举报
文章被收录于专栏:小赵的Java学习

文章目录

先了解下前置知识:

缓冲池 Buffer Pool

首先,对于InnoDB存储引擎来说,数据都是放在磁盘上的,存储引擎要操作数据,必须先把磁盘里面的数据加载到内存里面才可以操作。   这里就有个问题,是不是我们需要的数据多大,我们就一次从磁盘加载多少数据到内存呢?比如我要读6个字节。   磁盘I/O的读写相对于内存的操作来说是很慢的。如果我们需要的数据分散在磁盘的不同的地方,那就意味着会产生很多次的I/O操作。   所以,无论是操作系统也好,还是存储引擎也好,都有一个预读取的概念。也就是说,当磁盘上的一块数据被读取的时候,很有可能它附近的位置也会马上被读取到,这个就叫做局部性原理。那么这样,我们干脆每次多读取一点,而不是用多少读多少。   InnoDB设定了一个存储引擎从磁盘读取数据到内存的最小的单位,叫做页。操作系统也有页的概念。操作系统的页大小一般是4K,而在InnoDB里面,这个最小的单位默认是16KB大小。如果要修改这个值的大小,需要清空数据重新初始化服务。

举个例子,你去烧烤店跟老板说,老板,来一个生蚝。他根本不卖,懒得给你烤。老板卖给你生蚝,就是一打一打地卖。   我们要操作的数据就在这样的页里面,数据所在的页叫数据页。

这里有一个问题,操作数据的时候,每次都要从磁盘读取到内存(再返回给Server),有没有什么办法可以提高效率?   还是缓存的思想。把读取过的数据页缓存起来。   InnoDB设计了一个内存的缓冲区。读取数据的时候,先判断是不是在这个内存区域里面,如果是,就直接读取,然后操作,不用再次从磁盘加载。如果不是,读取后就写到这个内存的缓冲区。   这个内存区域有个专属的名字,叫 Buffer Pool。   修改数据的时候,也是先写入到 buffer pool,而不是直接写到磁盘。当数据在缓存中,也就是内存的数据页和磁盘数据不一致的时候,我们把它叫做脏页。那脏页什么时候才同步到磁盘呢?   InnoDB里面有专门的后台线程把Buffer Pool的数据写入到磁盘,每隔一段时间就一次性地把多个修改写入磁盘,这个动作就叫做刷脏。

刷脏页的时机

MySQL定时刷

MySQL会在自认为系统“空闲”的时候或者当系统更新很频繁,redo log很快就写满的情况下,合理的定时进行刷脏

MySQL内存(buffer pool)不足的时候

当需要将数据页读到内存中时,发现内存不够了,就需要淘汰掉内存中最不经常使用的数据页,空出内存给别的数据页使用,如果淘汰的是“脏页”,就要先把脏页写到磁盘中。

MySQL正常关闭的时候

如果关闭的时候不刷脏,启动的时候就需要去读redo log然后同步数据到磁盘,这样启动速度会变慢。

redo log满了的时候

redo log写满的时候,整个系统就不能再接收更新了,所有的更新必须都阻塞住。这种情况要尽量避免。

刷脏导致的性能问题

一个查询要淘汰的脏页个数太多,会导致查询的相应时间明显变长 日志写满,更新全部读,写性能跌为0,这种情况对敏感业务来说,是不能接受的

因此InnoDB要控制脏页比例,来尽量避免这两种情况

需要正确告诉InnoDB所在主机的IO能力,这样InnoDB才能知道需要全力刷脏页的时候,可以刷多快。 可以通innodb_io_capacity参数来控制InnoDB的刷盘能力,这个值建议设置成磁盘的IOPS,通过fio工具可以测试出磁盘的IOPS,命令如下:

代码语言:javascript
复制
fio -filename=$filename -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=16k -size=500M -numjobs=10 -runtime=10 -group_reporting -name=mytest 

innodb_io_capacity的默认值为200,正确配置innodb_io_capacity可以发挥机器的性能,错误配置也会导致性能问题,比如使用SSD的硬盘就可以将这个值配大些,但是也不能配置过大,配置过大会导致InnoDB把磁盘的能力全用来刷脏页了,不能服务用户请求。

控制刷脏页速度的因素

如果刷脏页慢,会导致内存脏页太多,其次是redo log写满(因为脏页还没有同步到磁盘,redo log就不能覆写)。 InnoDB的刷盘速度就通过脏页比例和redo log写盘速度来控制的.

为了减少刷脏给业务带来的影响,要合理的设置innodb_io_capacity的值,并且平时要多关注脏页比例,不要让它经常解决75%。

代码语言:javascript
复制
--脏页比例计算:
select VARIABLE_VALUE into @a from performance_schema.global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_dirty'; 
select VARIABLE_VALUE into @b from performance_schema.global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_total'; 
select @a/@b;

连带机制

一旦一个查询请求需要在执行过程中刷掉一个脏页时,这个查询就可能要比平时慢了,MySQL中的一个机制可能会让查询更慢。 在准备刷一个脏页的时候,如果这个数据页旁边的数据页刚好是脏页,就会把这个“邻居”也带着一起刷掉,并且这个逻辑会继续蔓延。 通过innodb_flush_neighbors可以控制这个行为,值为1的时候会有上述的连带机制,MySQL8.0以下默认为1。 ​

建议:

当使用的是机械硬盘时,建议开启,这样可以减少很多的随机IO 当使用的是固态硬盘这类IOPS比较高的设备时,建议关闭,因为这个时候IOPS往往不是瓶颈,这样可以减少SQL的响应时间

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 缓冲池 Buffer Pool
  • 刷脏页的时机
    • MySQL定时刷
      • MySQL内存(buffer pool)不足的时候
        • MySQL正常关闭的时候
          • redo log满了的时候
          • 刷脏导致的性能问题
          • 控制刷脏页速度的因素
          相关产品与服务
          云数据库 SQL Server
          腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档