show engine innodb status中Pages

2021-09-05  本文已影响0人  轻松的鱼

有一个很久前就存在的疑惑:
在没有写入的情况下,show engine innodb status 中的 Pages flushed up to 为什么不等于 Last checkpoint point?它表示什么?

今天在写一篇文章时,想通过一个测试,从这几个 LSN 的变化来验证一个说法,结果重新勾起了这个问题,在一番“研究”后(其实就是google了一通,当然还是需要一些测试验证),终于弄明白了其中含义。

主要还是借鉴了一篇文章:http://blog.itpub.net/30221425/viewspace-2154670/,因为有大量的源码分析,而我看不懂源码,所以花了不少时间才理解其中原理,并且通过测试验证了其准确性,然后整理成了一个让像我这样不懂代码的人更方便阅读的文档。

LSN

show engine innodb status 的输出中,有一部分是 LSN 的状态:

mysql> pager grep -A 5 LOG                                      
PAGER set to 'grep -A 5 LOG'
mysql> show engine innodb status\G
LOG
---
Log sequence number 2471197058
Log flushed up to   2471197058
Pages flushed up to 2471197058
Last checkpoint at  2471197049
1 row in set (0.00 sec)

Log sequence number:所有修改数据的操作都会产生 redo log,这是系统当前 redo log 序列号(后面简称 LSN)的最大值;
Log flushed up to:当前已经刷盘的 redo log 的序列号;
Pages flushed up to:讨论的重点;
Last checkpoint at:最后一次 checkpoint 的位置。

Pages flushed up to 到底表示什么?最常见的说法就是脏页刷新到磁盘的 LSN,但 Last checkpoint at 也表示在此之前的数据页已经刷盘,而且通常我们看到的 Pages flushed up to 总是比 Last checkpoint at 大 ,所以这个说法肯定是错误的。

根据参考文章中的源码分析,Pages flushed up to 的取值逻辑是:
Pages flushed up to 取的是 buffer pool instance 中的所有 flush list 尾部的数据页中最小的 oldest modification lsn 的值;
如果取到的 oldest modification lsn 为 0,意味着没有脏页,那么就取 log_sys->lsn 的值,即 show engineinnodb status 显示的 Log sequence number。

在没数据写入的情况下,为什么 Last checkpoint point 不等于 Pages flushed up to?

是因为做 checkpoint 时同时 redo 日志会写 MLOG_CHECKPOINT,而 MLOG_CHECKPOINT 占用9个字节,所以系统 LSN 会加9,而由于脏页都被刷盘了,flush list 为空,获取 Pages flushed up to 时会直接取系统 LSN 值,所以也会比 Last checkpoint point 大 9。

获取 Pages flushed up to 和 checkpoint 不是一个原子操作,它是在 checkpoint 前就获取了,指的是下一次 checkpoint 结束的位置。

测试验证

我们手工开启一个事务写入一行数据(不提交),会发现如下图所示:

我们隔几秒钟后再查看 LSN,会发现:所有值都变了,并且前 3个值一样,Last checkpoint point 比它们的值小 9。这是因为InnoDB Master Thread 每秒、每十秒都会做 checkpoint,所有脏页都刷盘后,flush list 为空,符合我们前面所说的原理: 在持续写入的情况下,是可以观察到 Last checkpoint point 等于 Pages flushed up to 的(checkpoint 后还没有获取新的 Pages flushed up to):
上一篇下一篇

猜你喜欢

热点阅读