为什么MySQL会抖一下?

2023-03-10 15:30:04 浏览数 (1)

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

为什么正常执行的SQL突然慢了一下?比如下面在正常不过的查询也会产品慢SQL

代码语言:javascript复制
SELECT * FROM XXX WHERE ID=1;

mysql抖一下就是在刷脏页, 刷脏页的四个场景:

(1)redo log满了

应该就是 InnoDB 的 redo log 写满了。这时候系统会停止所有更新操作,把 checkpoint 往前推进,redo log 留出空间可以继续写。更新数据就一套程序,没有备用方案;更新redo log是必须的一个节点,redo log满了只能排队等待redo log刷出空闲的位置;我想什么时候redo log才会被写满呢?生产的速度远大于消费的速度;数据库出问题了,cpu和io资源被别的地方大量占用。

(2)内存满了

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

buffer pool实际是作为一个内存管理器的理念存在的。在innodb的内存buffer pool中,用 free list 来维护未使用页,用flush list维护脏页,用lru list来维护使用页。

(3)mysql空闲的时候

为了提高效率,mysql有空就会刷脏页

(4)mysql正常关闭的时候,会触发脏页刷盘

因为没能正确地设置 innodb_io_capacity 参数,而导致的性能问题也比比皆是。之前,就曾有其他公司的开发负责人,找一个库的性能问题,说 MySQL 的写入速度很慢,TPS 很低,但是数据库主机的 IO 压力并不大。

主机磁盘用的是 SSD,但是 innodb_io_capacity 的值设置的是 300。于是,InnoDB 认为这个系统的能力就这么差,所以刷脏页刷得特别慢,甚至比脏页生成的速度还慢,这样就造成了脏页累积,影响了查询和更新性能。

  • 脏页比例
  • 脏页刷盘速度
  • 刷新相邻页面策略 (bufferpool脏页比例 或 redolog 都可能成为读写sql的瓶颈。
代码语言:javascript复制
1. 脏页比例默认75%,一定不要让其接近75% innodb_max_dirty_pages_pct =Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total。
2. 刷脏页速度 nnodb_io_capacity定义的能力乘以R%来控制刷脏页的速度。
3. innodb_flush_neighbors=0(不开启脏页相邻淘汰) 
(对于机械硬盘顺序读写会有提升,ssd无提升。iops普通机械硬盘只有几百,ssd有上千,可以不开启)
  • 避免大量刷脏页,脏页flush可能会产生内存抖动。要尽量避免这种情况,你就要合理地设置 innodb_io_capacity 的值,并且平时要多关注脏页比例,不要让它经常接近 75%。

精进自省:一定要给客户选择权,永远不要说不,要有条件地说是。降低期望的同时给予其他的补偿。提高期望的同时附加更多的条件。对于比较大的期望要分步骤达到客户的期望。不要帮客户做决定,而是给客户提供尽可能多的选项,然后引导客户做决定。

0 人点赞