美文网首页
show engine innodb status中Pages

show engine innodb status中Pages

作者: 轻松的鱼 | 来源:发表于2021-09-05 15:21 被阅读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 结束的位置。

    测试验证

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

    • Log sequence number 增加了,因为系统 LSN 是实时产生的;
    • Log flushed up to 没变,说明 redo log 还没刷盘(也可能观察到这个值增加并且和 Log sequence number 一致,因为 InnoDB 后台线程每秒会刷 redo log,未提交事务的 redo log 可能提前刷盘);
    • Pages flushed up to 没变,因为这个值不是实时产生的,只要我们手速够快,在执行完 insert 后立刻查看 LSN,就可以看到这个值不变;
    • Last checkpoint point 没变,同样的只要手速够快,在 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):

    相关文章

      网友评论

          本文标题:show engine innodb status中Pages

          本文链接:https://www.haomeiwen.com/subject/cjpjwltx.html