本文主要是介绍Mysql5.7 checkpoint和LSN,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、什么是checkpoint
① 官方解释
当对缓存在缓冲池中的数据页进行更改时,这些更改会在稍后的某个时间写入数据文件 (写入磁盘),这个过程称为刷新。检查点是已成功写入数据文件的最新更改(由 LSN值表示)的记录。
② 我的理解
checkpoint看了视频查了好多资料都没有搞明白,后面还是看了https://www.cnblogs.com/zmc60/p/15223274.html 这位大神的文章才明白的,建议大家去看一下。
当数据存在innodb buffer pool中,Mysql做update操作时,不是直接修改硬盘的页,而是对buffer pool中对应的页进行修改的。因为在内存修改更快,这时候可能就会产生脏页,因为可能内存中的页和磁盘中的页数据不一致。
page_cleaner_thread线程就会把上面的数据不一致进行刷新同步,刷新一次就会记录一个检查点(checkpoint),可以理解检查点checkpoint是动态更新的,checkpoint变量存储的变量就是当前的LSN。
page_cleaner_thread同步刷新一次,checkpoint变量就记录当前的LSN。
③什么是LSN?
LSN全称:Log Sequence Number :日志序列号,该序列号是一个不断增大的数字,主要存在于数据页、buffer_pool、redolog_buffer、redologfile中
在 MySQL 5.6.3 之前,LSN 是一个 4 字节的无符号整数。当重做日志文件大小限制从 4GB 增加到 512GB 时,LSN 在 MySQL 5.6.3 中变成了一个 8 字节的无符号整数,因为需要额外的字节来存储额外的大小信息。基于 MySQL 5.6.3 或更高版本构建的使用 LSN 值的应用程序应使用 64 位而不是 32 位变量来存储和比较 LSN 值。
简单理解就是一个数字标识,也可以理解为软件的版本号。当数据库有更新操作时,就会产生新的LSN。
④ 那些地方会存储LSN
A) buffer pool内存的页会存储
B) 硬盘中的页会存储
C) redo日志中会存储
可以通过命令:show engine innodb status;
LOG
---
Log sequence number 16715212312
Log flushed up to 16715212312
Pages flushed up to 16715212312
Last checkpoint at 16715212303
0 pending log flushes, 0 pending chkp writes
829937 log i/o's done, 0.00 log i/o's/second
Log sequence number : 表示的内存buffer pool中的LSN
Log flushed up to : 刷新到redo log file on disk中的LSN
Pages flushed up to : 已经刷新到磁盘数据页的LSN
Last checkpoint at : 最后一次(上一次)检查点所在的位置
二、checkpoint的机制是什么样的
1.首先修改内存中数据页时,在修改后的数据页中记录一个LSN号,暂时称为:data_in_buffer_lsn
2.在修改内存中数据页的同时,redo_log_buffer(也是一块内存区域,在buffer_pool中)中同时也会记录修改的物理变化,发生变化会产生redo log,这时会记录redo log 的一个LSN,注意这个LSN是在内存中,暂时称为:redo_log_in_buffer_lsn
3.当日志写了部分后会触发一个日志落盘策略,该策略是由参数:innodb_flush_log_at_trx_commit控制,该参数在前面的内容有介绍,当将redo_log_buffer中redo log日志刷到磁盘上后,此时在redo log日志也会记录一个LSN(该LSN此时在磁盘上),这个操作也是我们经常说的WAL机制,就是日志优先写机制,该机制是用来防止mysql在未经进行刷脏页时出现宕机,可以用redolog file 来进行恢复。暂时称为:redo_log_on_disk_lsn;
4.我们在内存中修改的数据页不可能一直在内存中,这时我们的猪脚出现(checkpoint机制),它就表示在一定的条件下将脏页(数据脏页和日志脏页)刷到磁盘上,当脏页刷到磁盘后,所以会在本次checkpoint刷页结束后,在redo log中记录checkpoint的LSN位置,暂且称之为checkpoint_lsn。
5.要记录checkpoint所在位置很快,只需要设置一个标志即可,但是刷数据页并不一定很快,比如一次性刷的数据页非常多,也就是说要刷入的数据页需要一定的时间来完成,中途刷入的每个数据页都会记录当前页所在的LSN,暂时称为data_page_on_disk_lsn
根据上面的图:假如在⑦的时候LSN=800时,电脑突然断电后,mysql重启的话就会根据最近一次的checkpoint往上找, 比checkpoint小的则不用管,因为磁盘已经同步了,比checkpoint大的则表示需要从redo_log日志进行同步数据。这样才能保证数据的一致性和持久性。
三、什么时候会进行checkpoint操作?
sharp checkpoint:完全检查点,数据库正常关闭时,会触发把所有的脏页都写入到磁盘上(这时候logfile的日志就没用了,脏页已经写到磁盘上了)。
InnoDB Fuzzy Checkpoint 模糊检查点的发生,模糊检查点可以理解为区域检查点。
数据库在运行时不会使用sharp checkpoint,在引擎内部使用fuzzy checkpoint,即只刷新一部分脏页,而不是刷新所有的脏页回磁盘。
下面就是模糊检查点的4中发生情况
① Master Thread Checkpint
master线程定时去checkpint
差不多以每秒或每十秒的速度从缓冲池的脏页列表中刷新一定比例的页回磁盘,这个过程是异步的,不会阻塞用户查询
mysql5.6以后单独放到了page_cleaner_thread线程中了。
② Flush_LRU_LIST checkpoint
当innodb pool中的free list空闲的页没有了,当有新的页需要缓存时,需要把LRU列表尾端的页移除,当这些页是脏页的时候,就需要checkpoint.
可以通过参数innodb_lru_scan_depth控制LRU列表中可用页的数量,也就是一次性刷新页的数量,该值默认为1024,
③ Async/Sync Flush checkpoint 重做日志重用
指的是重做日志文件不可用的情况,这时需要强制将一些页刷新回磁盘,而此时脏页是从脏页列表中选取的。若将已经写入到重做日志的LSN记为redo_lsn,将已经刷新回磁盘最新页的LSN记为checkpoint_lsn,则可定义:
checkpoint_age = redo_lsn - checkpoint_lsn
再定义以下的变量:
async_water_mark = 75% * total_redo_log_file_size
sync_water_mark = 90% * total_redo_log_file_size
④ Diry Page too much Checkpoint
即脏页的数量太多,导致InnoDB存储引擎强制进行Checkpoint。其目的总的来说还是为了保证缓冲池中有足够可用的页。其可由参数innodb_max_dirty_pages_pct控制:这里的75指的是75%,当脏页数的比例超过75%就会刷新。
检查点的监控:
show global status like 'Innodb_buffer_pool_pages%t%';
Innodb_buffer_pool_pages_data:数据页的大小,有多少个页
Innodb_buffer_pool_pages_dirty:脏页的数量,单位是页
Innodb_buffer_pool_pages_total:总的页数
Innodb_buffer_pool_pages_dirty / Innodb_buffer_pool_pages_total:表示脏页在buffer 的占比
这篇关于Mysql5.7 checkpoint和LSN的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!