概叙
科普文:软件架构数据库系列之【MySQL/innodb刷脏页】-CSDN博客
科普文:软件架构数据库系列之【innodb内存管理四剑客:LRU算法+Free_list、LRU_list、Flush List】-CSDN博客
科普文:软件架构数据库系列之【MySQL:innodb刷脏页多线程的源码解读】-CSDN博客
CheckPoint是MySQL的WAL和Redolog的一个优化技术。
MySQL的CHECKPOINT机制是一种优化技术,主要用于将缓存池中的脏页刷新到磁盘,确保数据的持久性和一致性。
CHECKPOINT机制通过记录一个特定的时间点(称为检查点),在该时间点上,所有在此之前的修改都会被刷新到磁盘上,从而在系统崩溃时能够快速恢复数据。
科普文:软件架构数据库系列之【一文搞懂MySQL中Innodb事务原理/ACID】-CSDN博客
CHECKPOINT的作用
- 缩短数据库的恢复时间:当数据库宕机时,由于CHECKPOINT之前的页已经被刷新到磁盘,因此只需要对CHECKPOINT之后的重做日志进行恢复,从而缩短恢复时间。
- 缓冲池不够用时刷新脏页(buffer pool大小有限):当缓冲池空间不足时,系统会强制执行CHECKPOINT,将脏页刷新到磁盘,以释放空间。
- 重做日志不可用时刷新脏页(redolog file组中日志文件大小有限制):当重做日志不可用时(例如重做日志循环使用),系统会强制执行CHECKPOINT,确保脏页至少刷新到当前重做日志的位置。
科普文:软件架构数据库系列之【图解InnoDB恢复recovery过程】_innodb recovery-CSDN博客
科普文:软件架构数据库系列之【详解InnoDB恢复recovery过程】-CSDN博客
科普文:软件架构数据库系列之【详解InnoDB重做日志Redlog】-CSDN博客
科普文:软件架构数据库系列之【详解InnoDB事务日志(redo log和undo log) 】_innodb两种日志redo和undo-CSDN博客
InnoDB之Dirty page、Redo log_innodb dirty-CSDN博客
科普文:软件架构数据库系列之【详解InnoDB重做日志Redlog】-CSDN博客
CHECKPOINT的触发时机
- 定期执行:系统会定期执行CHECKPOINT,将缓存池中的脏页刷新到磁盘。
- 内存不足时:当缓冲池内存不足时,系统会触发CHECKPOINT以释放空间。
- 重做日志不可用时:当重做日志需要循环使用时,系统会强制执行CHECKPOINT以确保数据的一致性。
CHECKPOINT的实现机制
CheckPoint做了什么事情?将缓存池中的脏页刷回磁盘。
checkpoint定期将db buffer的内容刷新到data file,当遇到内存不足、db buffer已满等情况时,需要将db buffer中的内容/部分内容(特别是脏数据)转储到data file中。
在转储时,会记录checkpoint发生的位置,在故障回复时候,只需要redo/undo最近的一次checkpoint之后的操作。
CHECKPOINT通过LSN(Log Sequence Number)来实现。LSN是一个8字节的数字,用于标记日志的顺序和位置。每个页、重做日志和CHECKPOINT都有一个LSN,系统通过LSN来确保数据的一致性和顺序恢复。
科普文:软件架构数据库系列之【PostgreSQL中的 WAL文件与LSN 】_pg wal 文件名 lsn-CSDN博客
科普文:软件架构数据库系列之【详解InnoDB逻辑序列号LSN (log sequence number)】_innodb lsn-CSDN博客
科普文:软件架构数据库系列之【MySQL源码之innodb事务和Mini-Transaction】-CSDN博客
CHECKPOINT的种类
InnoDB存储引擎内部,有两种Checkpoint,分别为:Sharp Checkpoint、Fuzzy Checkpoint
- Sharp CHECKPOINT:在数据库关闭时执行,将所有脏页刷新到磁盘。由于会影响数据库的可用性,通常只在关闭时使用。
- Fuzzy CHECKPOINT:在数据库运行时使用,只刷新一部分脏页,以提高性能。
通过这些机制和策略,MySQL能够有效地管理脏页的刷新,确保数据的持久性和一致性,同时优化系统的性能和恢复时间。
1、Sharp CheckPoint
发生在数据库关闭时,会将所有的脏页刷回磁盘,这是默认的工作方式,即参数innodb_fast_shutdown=1。
但是若数据库在运行时也使用Sharp Checkpoint,那么数据库的可用性就会受到很大的影响。故在InnoDB存储引擎内部使用Fuzzy Checkpoint进行页的刷新,即只刷新一部分脏页,而不是刷新所有的脏页回磁盘。
2、Fuzzy CheckPoint
为提高性能,数据库运行时使用Fuzzy CheckPoint进行页的刷新,即只刷新一部分脏页。
Fuzzy Checkpoint(模糊检查点):
- Master Thread Checkpoint;
- FLUSH_LRU_LIST Checkpoint;
- Async/Sync Flush Checkpoint;
- Dirty Page too much Checkpoint
在Innodb事务日志中,采用了Fuzzy Checkpoint,Innodb每次取最老的modified page(last checkpoint)对应的LSN,再将此脏页的LSN作为Checkpoint点记录到日志文件,意思就是此LSN之前的LSN对应的日志和数据都已经flush到redo log。
有以下几种情况可能发生Fuzzy CheckPoint:
【1】如果缓冲池里面的脏页太多,也会导致checkpoint.其目的就是保证缓冲池里面有足够的可用的页。当缓冲池里面脏页超过75%,强制刷新一部分脏页到磁盘。
【2】Master Thread中存在CheckPoint,会以每秒或者每十秒的频率从缓冲池的脏页里面刷新一定比例的页回磁盘。这个过程是异步的,也就是用户感受不到。
【3】在LRU list里面也存在CheckPoint,具体来说因为innoDB存储引擎需要LRU list里面需要大约100个空闲页(也就是说LRU list不能放满),因此如果检查发现LRU list没有100个空闲页,他就会将LRU list尾部的页移除,但是如果这些页里面有脏页,那么需要进行CheckPoint,立即将这些脏页刷新到磁盘。
【4】当redo log可用空间太少的时候,也会导致checkpoint。之前说到,提交修改时是先写到redo log里面,然后再修改页。但是redo log并不能无限增大,redo log的大小是一定的,因此redo log是不断的进行循环利用的,也就是说新的修改会覆盖掉redo log的可覆盖部分,那哪些部分是可覆盖的呢?就是如果数据库宕机之后恢复时,不需要这部分的redo log,他们就是可覆盖的。
LSN标记
InnoDB引擎通过LSN(Log Sequence Number)来标记版本,LSN是日志空间中每条日志的结束点,用字节偏移量来表示。
1、LSN(Log Sequence Number)
- LSN是用来标记版本的
- LSN是8字节的数字
- 每个page有LSN,redo log也有LSN,Checkpoint也有LSN
2、Log Sequence Number
当mysql crash的时候,Innodb扫描redo log,从last checkpoint开始apply redo log到buffer pool,直到last checkpoint对应的LSN等于Log flushed up to对应的LSN,则恢复完成。
如上图所示,Innodb的一条事务日志共经历4个阶段:
- 创建阶段:事务创建一条日志
- 日志刷盘:日志写入到磁盘上的日志文件
- 数据刷盘:日志对应的脏页数据写入到磁盘上的数据文件
- 写CKP:日志被当作Checkpoint写入日志文件;
对应这4个阶段,系统记录了4个日志相关的信息,用于其它各种处理使用:
- Log sequence number(LSN1):当前系统LSN最大值,新的事务日志LSN将在此基础上生成(LSN1+新日志的大小);
- Log flushed up to(LSN2):当前已经写入日志文件的LSN;
- Oldest modified data log(LSN3):当前最旧的脏页数据对应的LSN,写Checkpoint的时候直接将此LSN写入到日志文件;
- Last checkpoint at(LSN4):当前已经写入Checkpoint的LSN;
对于系统来说,以上4个LSN是递减的,即: LSN1>=LSN2>=LSN3>=LSN4。
此外,我们还需要了解LSN,这个用来标记版本信息,单位是字节,我觉得可以把它理解为某部分数据的字节数。
有以下几种LSN:
1、checkpoint_lsn:表示缓冲区里面已经刷新回磁盘的最新页的LSN,表明了该LSN之前的数据都刷回到磁盘了,且如果要做恢复操作,也只要从当前这个 CheckPoint LSN 开始恢复。(可以理解为已经刷新回磁盘的字节数)
2、redo_lsn:重做日志的lsn,也就是日志里面的最新版本(也可以理解为重做日志里面的字节数,因为我们之前会把页保存在redo log里面)
3、我们定义checkpoint_age=redo_lsn-checkpoint_lsn;
4、每个重做日志为1G,一共两个重做日志,加起来的大小为2GB,定义为total_redo_log_file_size。
如果checkpoint_age<0.75*total_redo_log_file_size,那么不需要刷新任何脏页到磁盘。
如果checkpoint_age>0.75*total_redo_log_file_size,那么从Flush list里面刷新足够的脏页回磁盘,使得checkpoint_age<0.75*total_redo_log_file_size。
checkpoint_lsn和redo_lsn之间的关系如下:
1、重做日志LSN = CheckPoint的LSN ,则表示所有页都已经刷回磁盘
2. 重做日志的LSN > CheckPoint的LSN ,则表示还有页没刷到磁盘;如果是宕机,则需要用日志恢复。
可以用图表来表示:
日志中的LSN大部分情况下是大于 CheckPoint的LSN,也就是说 CheckPoint的LSN部分,是我们已经刷新到磁盘的部分,这部分日志留着也没用,因为实际数据已经刷新回磁盘了,因此是可以覆盖的,而剩下的checkpoint_age还没有刷新回磁盘,这部分日志是必须留着的,因此不可覆盖。之前求的checkpoint_age实际就是不可覆盖部分的大小,如果这部分太大的话(根据上面的公式:不可覆盖部分超过75%)就要把缓存里面的一些脏页刷新回磁盘,这样可以增大CheckPoint的LSN,也就是右边部分,从而减小redo log的不可覆盖部分。
那么上面使用这么多LSN的意义是什么呢?
是为了保证redo log 的循环可用,因为如果redo log 的不可覆盖部分太大,后面我们想在redo log里面添加新的内容都无法添加了,因此checkpoint机制可以不断把脏页刷新到磁盘,从而减小redo log的不可覆盖部分,保证可以不断往redo log里面添加数据。
CHECKPOINT日常关注的问题
一、我们的日志生成速度?
1、每天生成多少日志、产生多少redo log
mysql> show global status like 'Innodb_os_log_written';
+-----------------------+--------+
| Variable_name | Value |
+-----------------------+--------+
| Innodb_os_log_written | 107008 |
+-----------------------+--------+
1 row in set (0.01 sec)
2、如果redolog量大,需要修改如下参数,增加logfile的大小和组数
mysql> show variables like 'i%log_file%';
+---------------------------+----------+
| Variable_name | Value |
+---------------------------+----------+
| innodb_log_file_size | 50331648 |
| innodb_log_files_in_group | 2 |
+---------------------------+----------+
2 rows in set (0.00 sec)
2、日志写入速度?
Log buffer有没有满、满的话为什么满
mysql> show variables like 'i%log_buffer%';
+------------------------+----------+
| Variable_name | Value |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+
1 row in set (0.01 sec)
mysql> show global status like '%log_pending%';
+------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| Innodb_os_log_pending_fsyncs | 0 |
| Innodb_os_log_pending_writes | 0 |
+------------------------------+-------+
2 rows in set (0.01 sec)
3、脏页的写入速度?
1、Log buffer满了会hang住
2、Logfile满了不能被覆盖也会hang住
3、如果脏页写入速度慢的话,logfile满了也不能被覆盖,系统容易hang住,log buffer如果满了的话也容易hang住。
4、数据库启动时间是多少?
启动时,默认是要先恢复脏页。当然,能通过参数innodb_force_recovery启动控制。
如果innodb_buffer_pool很大,32G,极端情况可能有32G的脏页,这个时候如果崩了,恢复的话需要恢复这32G的脏页,时间非常长。
二、日志点分析
通过show engine innodb status\G解释一下LOG相关的四行参数的值:
Log sequence number 143942609---LSN:日志序列号(1)
//字节,日志生成的最新位置,最新位置出现在log buffer中
Log flushed up to 143942609---(2)
//字节,日志已经写入到log file的位置,1-2=log buffer日志量,最好是<=1M
Pages flushed up to 143942609---(3)
//字节,脏页的数量(日志字节数来衡量),2-3=脏页的数量(日志字节为单位)
Last checkpoint at 143942600---(4)
//字节,共享表空间上的日志记录点,最后一次检查点,及崩溃恢复时指定的起点,3-4就是崩溃恢复多跑的日志,值越大说明需要提升checkpoint的跟进速度。
查看命令:show innodb status\G;
innodb_max_dirty_pages_pct与检查点的关系
数据库运行一段时间后,经常导致服务器大量的swap,怀疑是innodb中的脏数据太多了,因为没有free space了,mysql通知OS,把一些脏页交换出去,以上只是猜测。
有一个现象是每次关数据库时都要关很久,并且在关数据库时,发现有大量的swap in。
如果是数据库进程异常关闭,打开数据库又会花很长的时间来作恢复。
我想提高一下mysql检查点发生的频率。看了Adaptive checkpointing,发现mysql检查点事件受两个因素的制约:一个是amount,另外一个是age.
amount主要由innodb_max_dirty_pages_pct参数控制;至于age,主要是由日志文件大小有关。
因为修改日志文件大小,要重启数据库,所以没有做这个尝试;于是尝试修改innodb_max_dirty_pages_pct参数。
查看当前innodb_max_dirty_pages_pct参数的值:
mysql> show variables like ‘%pct%’;
+—————————-+——-+
| Variable_name | Value |
+—————————-+——-+
| innodb_max_dirty_pages_pct | 90 |
+—————————-+——-+
1 row in set (0.00 sec)
查看当前的检查点位置(对于如何获取此信息,花了比较多的时间,才找到此方法)
show innodb status\G;
LOG
—
Log sequence number 16 881655880
Log flushed up to 16 881649862
Last checkpoint at 16 546135914
我们可以看到检查点与log sequence number,Log flushed up to都有相当大的差距。
———————-
BUFFER POOL AND MEMORY
———————-
Total memory allocated 19338953832; in additional pool allocated 13600768
Buffer pool size 1048576
Free buffers 17666
Database pages 1009478
Modified db pages 204553
修改的页占到整个数据库buffer pool页将近20%,大小为204553*16k/1024=3.196G,有这么多的脏数据没有写到数据文件。如果此时关闭数据库,必然要花很长的时间。如果数据库服务器因为掉电或者mysqld进程异常中断,那么打开,恢复的时间也会很长。
在咨询mysql界的朋友后,大家对innodb_max_dirty_pages_pct基本上也是采用默认值,不过,觉得这个方向是对的,就开始一步步调此参数。因为脏页占整个pool的20%,所以直接将此参数从90调到20.反复执行命令show innodb status\G;发现检查点仍然增长缓慢。过了一会儿,发现系统并无任何异常之处,继续调低此参数到15,此时间发现脏页Modified db pages减少下来,检查点增长稍微快一点。最终综合考虑缓存大小,把此参数设为5.
mysql> set global innodb_max_dirty_pages_pct=5;
Query OK, 0 rows affected (0.00 sec)
—
LOG
—
Log sequence number 16 1160564756
Log flushed up to 16 1160560077
Last checkpoint at 16 1037968260 –检查点追上来了
———————-
BUFFER POOL AND MEMORY
———————-
Total memory allocated 19338952464; in additional pool allocated 15022080
Buffer pool size 1048576
Free buffers 5291
Database pages 1021765
Modified db pages 61626 –这个值从204553快速下降
情况如自己预计的那样,脏页迅速减少,检查点追上来了。使用mysql的朋友,对于mysql服务器的交换,一直都采用直接关闭swap的做法。不知道使用此方法,即提高检查点发生的频率,减少脏页数量,能否解决我们常见的mysql交换问题呢?
后台清理线程
后台清理工作:脏页刷盘、undo回收
1、page cleaner thread:刷新脏页
2、purge thread:清空undo页、清理“deleted”page
一、innodb_page_cleaners
page cleaner线程从buffer pool中刷脏页的线程数量。
1、5.7新特性
1、5.6版本以前,脏页的清理工作交由master线程的;
2、Page cleaner thread是5.6.2引入的一个新线程(单线程),从master线程中卸下buffer pool刷脏页的工作独立出来的线程(默认是启一个线程);
3、5.7开始支持多线程刷脏页;
2、发起脏页的写请求
清理因为触发需要脏页回收的脏页(脏很久了、冷脏页……)
注意:真正干活的,将dirty page写入磁盘的是innodb_write_io_threads
3、如何调整这个参数
mysql> show variables like 'i%cleaners';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| innodb_page_cleaners | 1 |
+----------------------+-------+
1 row in set (0.05 sec)
1、配置文件my.cnf中添加innodb_page_cleaners=num值
2、默认是1;最大可以是64,也就是会有64个page cleaner线程并发工作清理脏页
4、如何判断是否要修改增加innodb_page_cleaners
mysql> show global status like '%wait_free';
+------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| Innodb_buffer_pool_wait_free | 0 |
+------------------------------+-------+
1 row in set (0.01 sec)
Innodb_buffer_pool_wait_free:标志着脏页有没有成为系统的性能瓶颈;如果值很大,则需要增加innodb_page_cleaners值,同时增加写线程。
1、通常,对于buffer pool的写发生在后台,当innodb需要读或创建一个数据页,但是没有干净的可用页,innodb就会为等待的操作能完成先将一些脏页刷入磁盘。
2、Innodb_buffer_pool_wait_free就是这等待操作的实例数。如果innodb_buffer_pool_size的大小设置适当,这个值就会很小,甚至为0。
二、innodb_purge_threads
purge线程,后台线程,致力于innodb清理,资源回收操作。
innodb_purge_threads
在 MySQL 8.0 中已经被移除。InnoDB 存储引擎在之前的版本中使用后台线程来处理 undo 日志和合并插入缓冲(insert buffer),其中包括一个清理线程(purge thread),它负责回收已经使用并且不再需要的 undo 日志。
从 MySQL 8.0 开始,InnoDB 引入了一种新的后台线程(Purge Thread),它是在 InnoDB 存储引擎层面实现的,而不是通过传统的后台线程。这就意味着,你不需要再通过 innodb_purge_threads
参数来设置清理线程的数量,因为这个参数已经不再使用了。
InnoDB 存储引擎会根据需要动态地启动和管理 Purge Thread,你不需要进行任何设置。如果你需要调整与清理操作相关的其他参数,可以查看并调整 innodb_purge_batch_size
和 innodb_max_purge_lag
等参数。
这里是一些相关参数的简单说明:
-
innodb_purge_batch_size
: 控制每个 purge thread 在每个运行周期中清除的最大行数。 -
innodb_max_purge_lag
: 控制单个事务在提交后,其 undo 信息能被 purge 的最大延迟时间。
你可以在 MySQL 配置文件(通常是 my.cnf
或 my.ini
)中设置这些参数,或者使用 SET GLOBAL
命令动态地在运行时设置它们。例如:
SET GLOBAL innodb_purge_batch_size = 100;
SET GLOBAL innodb_max_purge_lag = 1000;
请注意,对于生产环境,你应该在了解这些参数对性能的潜在影响后再进行调整。调整这些参数应该在不影响数据一致性和完整性的前提下进行。
1、清理操作
1、清理undo页
undo记录修改前的数据用于回滚,已提交的时候,不再回滚,即可清理该undo信息。
2、清理page里面的有“deleted”标签的数据行
1、当我们delete数据行时,是对数据页中要删除的数据行做标记“deleted”,事务提交(速度快);
2、后台线程purge线程对数据页中有“deleted”标签的数据行进行真正的删除。
2、调整依据
1、系统存在大量的delete、对主键的update
mysql> show global status like '%rows%d%ted';
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| Innodb_rows_deleted | 0 |
| Innodb_rows_updated | 5 |
+---------------------+-------+
2 rows in set (0.01 sec)
2、mysql> show engine innodb status \G
Trx id counter 1159171 #事务计数
Purge done for trx's n:o < 1157813 #事务清空位置
#1159171-1157813表示有待清空的事务量
undo n:o < 0 #当前清理事务undo位置
state: running but idle #启动但是闲置
History list length 1029 #当前undo数据页的总量1029*16K
3、调整:innodb_purge_threads默认值是1,OLTP系统一般会修改为4
mysql> show variables like '%purge_t%';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| innodb_purge_threads | 4 |
+----------------------+-------+
1 row in set (0.01 sec)
三、checkpoint
检查点,表示脏页写入到磁盘的时候,所以检查点也就意味着脏数据的写入。
1、checkpoint的目的
1、缩短数据库的恢复时间
2、buffer pool空间不够用时,将脏页刷新到磁盘
3、redolog不可用时,刷新脏页
2、检查点分类
1、sharp checkpoint:完全检查点,数据库正常关闭时,会触发把所有的脏页都写入到磁盘上(这时候logfile的日志就没用了,脏页已经写到磁盘上了)。
1、完全检查点,发生在数据库正常关闭的时候。
2、在数据库在运行时不会使用sharp checkpoint,在引擎内部使用fuzzy checkpoint,即只刷新一部分脏页,而不是刷新所有的脏页回磁盘。
2、fuzzy checkpoint:模糊检查点,部分页写入磁盘。
1、发生在数据库正常运行期间。
2、模糊检查点,不是sharp的就是模糊检查点(4种):master thread checkpoint、flush_lru_list checkpoint、async/sync flush checkpoint、dirty page too much checkpoint。
四、fuzzy checkpoint发生的4个条件
模糊检查点的发生,也就是脏页写入磁盘的情况。
差不多以每秒或每十秒的速度从缓冲池的脏页列表中刷新一定比例的页回磁盘,这个过程是异步的,不会阻塞用户查询。
1、周期性,读取flush list,找到脏页,写入磁盘
2、写入的量比较小
3、异步,不影响业务
mysql> show variables like '%io_cap%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| innodb_io_capacity | 200 |
| innodb_io_capacity_max | 2000 |
+------------------------+-------+
2 rows in set (0.01 sec)
4、通过capacity能力告知进行刷盘控制
通过innodb的io能力告知控制对flush list刷脏页数量,io_capacity越高,每次刷盘写入脏页数越多;
如果脏页数量过多,刷盘速度很慢,在io能力允许的情况下,调高innodb_io_capacity值,让多刷脏页。
MySQL会保证,保证里面有多少可用的空闲页,在innodb 1.1.x版本之前,需要检查在用户查询线程中是否有足够的可用空间(差不多100个空闲页),显然这会阻塞用户线程,如果没有100个可用空闲页,那么innodbhi将lru列表尾端的页移除,如果这些页中有脏页,那么需要进行checkpoint。Innodb 1.2(5.6)之后把他单独放到一个线程page cleaner中进行,用户可以通过参数innodb_lru_scan_depth控制lru列表中可用页的数量,默认是1024。
读取lru list,找到脏页,写入磁盘。
mysql> show variables like '%lru%depth';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_lru_scan_depth | 1024 |
+-----------------------+-------+
1 row in set (0.01 sec)
此情况下触发,默认扫描1024个lru冷端数据页,将脏页写入磁盘(有10个就刷10,有100个就刷100个……)
log file快满了,会批量的触发数据页回写,这个事件触发的时候又分为异步和同步,不可被覆盖的redolog占log file的比值:75%--->异步、90%--->同步。
当这两个事件中的任何一个发生的时候,都会记录到errlog中,一旦errlog出现这种日志提示,一定需要加大logfile。
Async/Sync Flush Checkpoint是为了保证重做日志的循环使用的可用性。在InnoDB 1.2.x版本之前,Async Flush Checkpoint会阻塞发现问题的用户查询线程,而Sync Flush Checkpoint会阻塞所有的用户查询线程,并且等待脏页刷新完成。从InnoDB 1.2.x版本开始——也就是MySQL 5.6版本,这部分的刷新操作同样放入到了单独的Page Cleaner Thread中,故不会阻塞用户查询线程。
4、dirty page too much checkpoint
很明显,脏页太多检查点,为了保证buffer pool的空间可用性的一个检查点。
1、脏页监控,关注点
mysql> show global status like 'Innodb_buffer_pool_pages%t%';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| Innodb_buffer_pool_pages_data | 2964 |
| Innodb_buffer_pool_pages_dirty | 0 |
| Innodb_buffer_pool_pages_total | 8191 |
+--------------------------------+-------+
3 rows in set (0.00 sec)
mysql> show global status like '%wait_free';
+------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| Innodb_buffer_pool_wait_free | 0 |
+------------------------------+-------+
1 row in set (0.00 sec)
- 1、Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total:表示脏页在buffer 的占比
- 2、Innodb_buffer_pool_wait_free:如果>0,说明出现性能负载,buffer pool中没有干净可用块
2、脏页控制参数
mysql> show variables like '%dirty%pct%';
+--------------------------------+-----------+
| Variable_name | Value |
+--------------------------------+-----------+
| innodb_max_dirty_pages_pct | 90.000000 |
| innodb_max_dirty_pages_pct_lwm | 0.000000 |
+--------------------------------+-----------+
2 rows in set (0.01 sec)
1、默认是脏页占比90%的时候,就会触发刷盘,将脏页写入磁盘,腾出内存空间。建议不调,调太低的话,io压力就会很大,但是崩溃恢复就很快;
2、lwm:low water mark低水位线,刷盘到该低水位线就不写脏页了,0也就是不限制。
注意:上面在调整的时候,要关注系统的写性能iostat -x。
参考:
https://zhuanlan.zhihu.com/p/655604788
MySQL · 引擎特性 · PolarDB Innodb刷脏优化(一) - 墨天轮
https://zhuanlan.zhihu.com/p/655604788
标签:checkpoint,log,刷脏页,Checkpoint,LSN,innodb,脏页,日志 From: https://blog.csdn.net/Rookie_CEO/article/details/143649277