[MySQL 5.6] Innodb page cleaner线程刷新策略

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

这部分内容是从http://mysqllover.com/?p=512 剥离出来,原文中为了保持整洁,将这些内容删除。

 

有以下几个参数会影响到Page cleaner的行为:

 

innodb_lru_scan_depth

innodb_adaptive_flushing_lwm

innodb_max_dirty_pages_pct_lwm

innodb_io_capacity_max

innodb_flushing_avg_loops

 

在函数page_cleaner_flush_pages_if_needed中会确定三个影响刷脏页行为的变量

1.    根据redo log计算比例(pct_for_lsn),当小于innodb_adaptive_flushing_lwm时,pct_for_lsn值为0,当小于异步刷redo的比例(log_sys->max_modified_age_async)时且关闭选项innodb_adaptive_flushing时,pct_for_lsn也为0,否则,计算:

((innodb_io_capacity_max/innodb_io_capacity)

*(lsn_age_factor * sqrt((double)lsn_age_factor)))/7.5

其中lsn_age_factor为当前的(redo比例*100)/max_modified_age_async

2.    根据脏页计算比例(pct_for_dirty),当innodb_max_dirty_pages_pct_lwm设置为0时,和以前的行为类似,如果脏页比例大于innodb_max_dirty_pages_pct时,pct_for_dirty设置为100,否则如果脏页比大于innodb_max_dirty_pages_pct_lwm,pct_for_dirty值为

(dirty_pct * 100)/( innodb_max_dirty_pages_pct+1)

3.    最近innodb_flushing_avg_loops次平均刷脏页的数量,同时还考虑上次统计时候的平均数量,再除以2

avg_page_rate= ((sum_pages / srv_flushing_avg_loops) + avg_page_rate) / 2

另外也会计算lsn的刷新速率

lsn_rate= (cur_lsn – prev_lsn) / srv_flushing_avg_loops;

lsn_avg_rate= (lsn_avg_rate + lsn_rate) / 2;

 

然后根据上述两个值计算要刷新的page数:

pct_total = ut_max(pct_for_dirty, pct_for_lsn);

n_pages = (PCT_IO(pct_total) + avg_page_rate) / 2;

if (n_pages > srv_max_io_capacity) {

n_pages =srv_max_io_capacity;

}

除了脏页的数量外,还要确定一个lsn下限值(lsn_limit),oldest_modification小于lsn_limit的block需要被刷新掉,其计算方式也受参数innodb_flushing_avg_loops影响:

每innodb_flushing_avg_loops次循环,计算

lsn_rate = (cur_lsn – prev_lsn) /srv_flushing_avg_loops;

lsn_avg_rate = (lsn_avg_rate + lsn_rate) / 2;

lsn_avg_rate表示LSN最近的平均推进速率

然后计算lsn_limit:

if (last_pages && cur_lsn – last_lsn >lsn_avg_rate / 2) {

age_factor= prev_pages / last_pages;

}

lsn_limit = oldest_lsn + lsn_avg_rate * (age_factor +1)

prev_pages表示上一次刷新时,试图刷的page数,last_pages表示上次实际刷新的page数,age_factor总是大于等于1的。

Oldest_lsn表示当前bp中的最老LSN.

 

在确定了需要刷新的page数及哪些Page需要被刷新后,就可以调用函数page_cleaner_do_flush_batch-> buf_flush_list做实际的操作了。

 

innodb_flush_log_at_timeout #每隔这么多秒刷一次日志,只有在innodb_flush_log_at_trx_commit=2时才生效.在master线程中判断,见函数srv_sync_log_buffer_in_background,在两个函数中会调用:

1.srv_master_do_active_tasks

2.srv_master_do_idle_tasks

从命名也可以理解,master线程在系统繁忙及空闲时,都会去做判断。在5.6的master线程函数srv_master_thread中,每sleep 1秒,会根据当前的系统负载是否繁忙去调用上面这两个函数,相比之前的函数,master线程函数要清爽很多了。每隔innodb_flush_log_at_timeout秒,会调用log_buffer_sync_in_background(TRUE)去刷日志。


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
存储 关系型数据库 MySQL
MySQL InnoDB数据存储结构
MySQL InnoDB数据存储结构
|
1月前
|
存储 缓存 关系型数据库
MySQL的varchar水真的太深了——InnoDB记录存储结构
varchar(M) 能存多少个字符,为什么提示最大16383?innodb怎么知道varchar真正有多长?记录为NULL,innodb如何处理?某个列数据占用的字节数非常多怎么办?影响每行实际可用空间的因素有哪些?本篇围绕innodb默认行格式dynamic来说说原理。
829 6
MySQL的varchar水真的太深了——InnoDB记录存储结构
|
2月前
|
存储 缓存 关系型数据库
MySQL - 存储引擎MyISAM和Innodb
MySQL - 存储引擎MyISAM和Innodb
|
12天前
|
存储 关系型数据库 MySQL
MySQL引擎对决:深入解析MyISAM和InnoDB的区别
MySQL引擎对决:深入解析MyISAM和InnoDB的区别
28 0
|
2月前
|
存储 SQL 关系型数据库
Mysql专栏 - mysql、innodb存储引擎、binlog的工作流程
Mysql专栏 - mysql、innodb存储引擎、binlog的工作流程
75 0
|
3月前
|
存储 算法 关系型数据库
MySQL相关(八)- innodb行级锁深入剖析
MySQL相关(八)- innodb行级锁深入剖析
45 0
|
3月前
|
存储 算法 关系型数据库
MySQL相关(七)- innodb 锁的介绍及使用
MySQL相关(七)- innodb 锁的介绍及使用
28 0
|
3月前
|
存储 关系型数据库 MySQL
MySQL相关(番外篇)- innodb 逻辑存储结构
MySQL相关(番外篇)- innodb 逻辑存储结构
32 0
|
3月前
|
存储 关系型数据库 MySQL
MySQL存储引擎 InnoDB、MyISAM、Memory存储引擎的特点与区别
MySQL存储引擎 InnoDB、MyISAM、Memory存储引擎的特点与区别
56 0
|
3月前
|
存储 SQL 缓存
MySQL `innodb_flush_log_at_trx_commit` 参数
MySQL `innodb_flush_log_at_trx_commit` 参数