关于mysql:技术分享-show-engine-innodb-status中Pages-flushed-up-to-的含义

31次阅读

共计 2665 个字符,预计需要花费 7 分钟才能阅读完成。

作者:胡呈清

爱可生 DBA 团队成员,善于故障剖析、性能优化,集体博客:https://www.jianshu.com/u/a95…,欢送探讨。

本文起源:原创投稿

* 爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


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

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

次要还是借鉴了一篇文章:http://blog.itpub.net/3022142…,因为有大量的源码剖析,而我看不懂源码,所以花了不少工夫才了解其中原理,并且通过测试验证了其准确性,而后整顿成了一个让像我这样不懂代码的人更不便浏览的文档。

明天在写一篇文章时,想通过一个测试,从这几个 LSN 的变动来验证一个说法,后果从新勾起了这个问题,这次我决定彻底弄明确到底是怎么一回事。

次要还是借鉴了一篇文章:http://blog.itpub.net/3022142…,因为有大量的源码剖析,而我也看不懂源码,所以花了不少工夫才了解其中原理,并且通过测试验证了其准确性,而后整顿成了一个更不便让像我这样不懂代码的人了解的文档。

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 的值(这里可能有点难以了解,咱们能够简化了解为取 flush list 中最大的 oldest modification lsn);

如果取到的 oldest modification lsn 为 0,意味着没有脏页,那么咱们就取 log_sys->lsn 的值,即 show engineinnodb status 显示的 Log sequence number。

LSN 更新的逻辑

取 Pages flushed up to 的目标是什么?因为是取的 flush list 中脏页的最大 LSN,接下来做 checkpoint 时,能够用作这次刷脏的一个完结地位。

在一个失常运行的 MySQL 中,零碎 LSN 随着 SQL 的执行(批改数据的 SQL)一直增大(实时的),Pages flushed up to 值也会按某个频率获取更新,所以 Pages flushed up to 个别会落后于零碎 LSN。而后 InnoDB master thread 每秒和每十秒做 checkpoint 时(还有其余的机制触发 checkpoint,这里不思考并不影响了解),在将脏页刷盘后会将 Last checkpoint at 的值更新成 Pages flushed up to,因为 Pages flushed up to 在不断更新,所以咱们察看到的 Last checkpoint at 个别会小于 Pages flushed up to。

在没数据写入的状况下,为什么 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):

正文完
 0