找回密码
 立即注册
查看: 199|回复: 3

MySQL中 LSN 和 Checkpoint 关系

[复制链接]

18

主题

0

回帖

58

积分

版主

积分
58
发表于 2023-5-4 18:42:20 | 显示全部楼层 |阅读模式
为什么需要Checkpoint技术?

考虑如下场景:假如redo-log重做日志可以无限增加,而且buffer-pool数据池足够大,那么就不需要将MySQL写入的缓冲池的数据页面刷回到磁盘。因为当主机crash时候,恢复数据库变得很容易,从无限容量的redo重做日志中对磁盘中的数据页面进行重放就可以了。
但这有必需有至少二个前提条件:

  • 数据库的buffer-pool可以缓存所有的页面数据
  • Redo-log重做日志可以无限增长
显然上面二个前提约束条件是不成能成立的。
为了解决如下问题,checkpoint查抄点技术应运而生:

  • 缩短数据库从crash中恢复的时间
  • MySQL buffer-pool缓冲池有上限,脏页面需要按时刷新回磁盘
  • 重做日志redo-log不能无限增长
有了checkpoint技术,当数据库从crash恢复时,数据库不需要重放执行所有的重做日志,因为checkpoint查抄点(小于checkpoint_lsn的值)前面的脏页面已经安全刷回磁盘了。数据库只需要执行查抄点之后的脏页面来进行恢复,从而大大减少了恢复的时间。

在讨论实现机制前,还需要先讨论一些关键概念。
MySQL在持久化与性能之间做了很多权衡与折衷。数据记录的改削首先写入buffer-pool内存中,但是为了将随机IO转换成挨次IO,会将数据记录对数据库改削所对应的物理日志写入redo-log缓存中。更进一步,或直接或间接的后台线程将数据写入OS buffer后,最后再同步磁盘中。
Buffer pool -> log Buffer -> os Buffer -> Log files on disk




LSN概述

LSN (log sequence number)是日志的逻辑序列号,在InnoDB存储引擎中,LSN的值会随着日志的写入而逐渐增大。新的日志LSN等于旧的LSN加上新增日志的大小。
LSN的分类?

每个页面都有 LSN,重做日志redo-log也有 LSN,查抄点checkpoint也有 LSN。可以使用如下命令来不雅察看:
  1. mysql> show engine innodb status\G;
复制代码


此中:

  • log sequence number: 代表当前的重做日志redo log(in buffer)在内存中的LSN
  • log flushed up to: 代表刷到redo log file on disk中的LSN
  • pages flushed up to: 代表已经刷到磁盘数据页上的LSN
  • last checkpoint at: 代表上一次查抄点地址位置的LSN
LSN的存储位置?




LSN不仅存在于重做日志redo log,还存在于普通数据页面中,每个数据页面的头部有FIL-PAGE_LSN字段,它记录了当前数据页最后一次被改削时日志序列LSN值。

按照上图流程,更新一笔记录时:

  • 先写内存数据页面(内存的数据页面有LSN字段)
  • 然后写缓冲内存的重做日志redo-log(内存的重做日志redo-log记录有LSN字段)
  • 最后提交时innodb_flush_log_at_trx_commit写重做日志redo-log进磁盘文件(磁盘的redo-log日志记录有pageLSN字段)
简言之,LSN这个值在几个处所存储:

  • 在数据页面(内存与磁盘)存储LSN
  • 在重做日志redo-log(内存)存储LSN
  • 在重做日志redo-log(磁盘)存储LSN
  • Checkpoint对应的LSN也是存储在重做日志记录中
恰好对应上文:
  1. mysql> show engine innodb status\G;
复制代码

  • log sequence number: 代表当前的重做日志redo log(in buffer)在内存中的LSN
  • log flushed up to: 代表刷到redo log file on disk中的LSN
  • pages flushed up to: 代表已经刷到磁盘数据页上的LSN
  • last checkpoint at: 代表上一次查抄点地址位置的LSN
问题1:MySQL怎么判断脏页?

基于数据页面的LSN,可以了解当前数据页面的版本。MySQL系统在更新记录时,会在对应的重做日志redo-log中更新LSN的值,与此同时记录的数据页面的头部也会记录redo-log中的LSN最新的值。当MySQL刷脏数据页面时,磁盘中数据页面文件的LSN的值也会增加。
回到我们的问题,MySQL怎么判断脏页?
只需要判断这个页面的LSN值,如果数据页面的LSN的值大于 Checkpoint的LSN值,说明这个数据页面接受了新的更新(所有数据页面的LSN更新到更大的值)。那么这个页面就是脏页。
问题2:MySQL基于Checkpoint如何从crash中恢复?

MySQL在崩溃恢复时,会从重做日志redo-log的Checkpoint处开始执行重放操作。 它从last Checkpoint对应的LSN开始扫描redo-log日志,并将其应用到buffer-pool中,直到last Checkpoint对应的LSN等于 log flushed up to 对应的 LSN (也就是redo-log磁盘上存储的LSN值),则恢复完成 。
说白了,查抄点要做的操作就是将缓冲池中的数据页刷到磁盘,最终达到内存与外存数据页的一致。查抄点的感化是縮短当数据库发生crash时数据库恢复所需要的时间。
尽管从理论上来说,由于重做日志redo-log记录了所有的页操作,当数据库crash时,恢复重做日志redo-log即可。但考虑到数据库是一个需要保证高可用的应用环境,从crash环境中快速恢复回来对处事的可用性是一个关键指标。因此查抄点checkpoint机制就是将内存页写加磁盘,这样发生crash的时候,已经刷到磁盘的数据页就不再需要恢复,只需要恢复查抄点之后的操作。
回复

使用道具 举报

0

主题

2

回帖

9

积分

新手上路

积分
9
发表于 2023-5-4 18:42:42 | 显示全部楼层
请教一下 pages flushed up to和last checkpoint at之间为什么会有gap呢
回复

使用道具 举报

0

主题

1

回帖

5

积分

新手上路

积分
5
发表于 2023-5-4 18:43:42 | 显示全部楼层
pages flushed up to指的是脏页中的最大的LSN,是下一次刷新checkpoint的终点
回复

使用道具 举报

0

主题

1

回帖

17

积分

新手上路

积分
17
发表于 2023-5-4 18:44:24 | 显示全部楼层
讲得很明白,一下子我就理解了整个过程。真牛。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|T9AI - 深度人工智能平台 ( 沪ICP备2023010006号 )

GMT+8, 2024-5-20 01:15 , Processed in 0.060713 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表