数据库小计

Mysql - 脏页

2022-02-24  本文已影响0人  祁小彬

1 . 脏页(内存页)

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

不论是脏页还是干净页,都在内存中。

平时很快的更新操作,都是在写内存和日志。

一条 SQL 语句,正常执行的时候特别快,但是有时也不知道怎么回事,它就会变得特别慢。

那这时候可能就是在刷脏页到磁盘中了~ flush

2 . 什么时候会引起flush?

(1) InnoDB的redo log写满了。这时候系统会停止所有的更新操作,然后让日志可以继续写。

把这部分数据日志都flush到磁盘上面。

(2) 也可能是系统内存不足,需要新的内存页,那么就淘汰一些内存页,空出来的给别的数据页使用。

先把脏页写到磁盘。

PS:使用内存是为了效率更好,

因为如果内存存在数据页,那么数据就一定正确,直接返回;

如果内存没有数据,才需要去磁盘中取,读入到内存,返回;

(3) MySQL 认为系统“空闲”的时候,反正闲着也是闲着hh

反正有机会就刷点数据

(4)MySQL 正常关闭。这时候,MySQL 会把内存的脏页都 flush 到磁盘上,这样下次 MySQL 启动的时候,就可以直接从磁盘上读数据,启动速度会很快。

3 . 影响

3.1 如果是redo log写满了
尽量避免的。因为出现这种情况的时候,整个系统就不能再接受更新了,所有的更新都必须堵住。更新数为 0。

3.2 内存不够用了
常态,很正常。

3.3 buffer pool
因为innodb用的是buffer pool 管理内存,缓冲池中的内存页有三种状态:第一种是还没有使用的;第二种是使用了并且是干净页;第三种是使用了并且是脏页。

Innodb 的内存策略是尽量使用内存。

4 . Innodb 刷脏页的控制策略

我觉得知道一下就好,这个脏页刷的快不快跟磁盘的能力有关。

可以通过innodb_io_capacity 这个参数设置磁盘能力。

InnoDB 的刷盘速度就是要参考这两个因素:一个是脏页比例,一个是 redo log 写盘速度。

平时要多关注脏页比例,不要让它经常接近 75%。

INNODB刷脏页,如果发现旁边也是脏页,那么会连带着一起刷掉。

所以可能会很慢,如果你的查询正好要先flush一个脏页的话。

在 InnoDB 中,innodb_flush_neighbors 参数就是用来控制这个行为的,值为 1 的时候会有上述的“连坐”机制,值为 0 时表示不找邻居,自己刷自己的。

找“邻居”这个优化在机械硬盘时代是很有意义的,可以减少很多随机 IO。机械硬盘的随机 IOPS 一般只有几百。

但是SSD 的IO很高,所以可以不用非要有刷写邻居的操作,可以加快响应。

在 MySQL 8.0 中,innodb_flush_neighbors 参数的默认值已经是 0 了。

5 . QA

对比这个LSN跟checkpoint 的LSN,比checkpoint小的一定是干净页

也就是如果内存中比redolog的头部小,那么就是干净页

每个数据页有LSN,重做日志有LSN,checkpoint有LSN。

占用8字节,LSN主要用于发生crash时对数据进行recovery,LSN是一个一直递增的整型数字,表示事务写入到日志的字节总量。
LSN不仅只存在于重做日志中,在每个数据页头部也会有对应的LSN号,该LSN记录当前页最后一次修改的LSN号,用于在recovery时对比重做日志LSN号决定是否对该页进行恢复数据。前面说的checkpoint也是有LSN号记录的,LSN号串联起一个事务开始到恢复的过程。

感谢:https://www.cnblogs.com/drizzle-xu/p/9713378.html

我感觉就是可以理解为是一个long类型的数字,可以根据这个来比较要不要刷写数据,以及是不是干净页面,在恢复数据要拿这个进行比较。

缓存区域,缓存数据和索引在内存中。

innodb使用了一些链表。
lru链表:用来存储内存中的缓存数据。
free链表:用来存放所有的空闲页,每次需要数据页存储数据时,就首先检测free中有没有空闲的页来分配。
flush链表:在内存中被修改但还没有刷新到磁盘的数据页列表,就是所谓的脏页列表,内存中的数据跟对应的磁盘上的数据不一致,属于该列表的页面同样存在于lru列表中,但反之未必。

将脏页flush到磁盘上是直接将脏页数据覆盖到对应磁盘上的数据

上一篇下一篇

猜你喜欢

热点阅读