[MySQL 5.6] page cleaner线程的效率问题

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

最近在测试5.6.11的写性能,当我完成一项测试,关闭workload,习惯性设置innodb_max_dirty_pages_pct为0,然后等待脏页刷完再shutdown。

 

发现存在刷脏的抖动:

 

time      flushed    Innodb_data_written

11:49:57  3692        117.3m

11:49:58  1125        33.5m|

11:49:59  4187        134.6m

11:50:00  1241         35.0m

11:50:01  4076        127.4m

 

从pstack的采样结果来看,page cleaner线程频繁出现这样的backtrace。

buf_flush_page_cleaner_thread->page_cleaner_sleep_if_needed->os_thread_sleep

加了两个计数来监控,也发现page cleaner线程平均sleep时间过长(750,000 ms 左右)。

那么为什么会出现波动呢?

检查发现,机器上有一个heartbeat脚本每隔两秒钟更新一条记录。这会导致如下条件成立:

2385                 if (srv_check_activity(last_activity)

2386                     || buf_get_n_pending_read_ios()

2387                     || n_flushed == 0) {

2388                         page_cleaner_sleep_if_needed(next_loop_time);

2389                 }

 

srv_check_activity(last_activity) 为非0值。目前的判断太过粗糙了。一条简单的UPDATE 会造成page cleaner线程的巨大波动。

相应的问题,已经report到buglist上:http://bugs.mysql.com/bug.php?id=69174

好吧,对我而言办法比较土,临时的解决方案就是增加一个变量,来限制最大sleep时间,这样就可以获得一个平缓的刷脏频率:

time      flushed    Innodb_data_written

11:51:43   3971         120.6m

11:51:44   3987         124.6m

11:51:45   3859         124.6m

11:51:46   3992         121.0m

11:51:47   3855         120.7m

 

另外,当srv_check_activity(last_activity)返回非0值后,会走不同的逻辑:

2393                 if (srv_check_activity(last_activity)) {

2394                         last_activity = srv_get_activity_count();

2395

2396                         /* Flush pages from end of LRU if required */

2397                         n_flushed = buf_flush_LRU_tail();

2398

2399                         /* Flush pages from flush_list if required */

2400                         n_flushed += page_cleaner_flush_pages_if_needed();

 

buf_flush_LRU_tail() : 依次遍历每个Buffer pool instance,从LRU尾部开始扫描,直到第srv_LRU_scan_depth个page停止,按批次刷LRU,每次期望刷100个page(一个CHUNK), 每个Bp会轮srv_LRU_scan_depth/100次循环

这里存在的问题,Mark Callaghan Report在这个Bug上:http://bugs.mysql.com/bug.php?id=69170

每一个CHUNK的循环,都是从LRU的尾部开始的,因为这中间会去释放bp的Mutex。

这样问题就比较明显了,如果有很多脏页,例如,我们假设LRU上的都是脏页.从函数buf_flush_LRU_list_batch的逻辑我们可以知道

1.如果这个Page是脏的,不可以替换,将其IO-FIX,并分发IO请求

2.回到LRU尾部,跳过IO-FIX的page,发发现新的脏页,同样将其IO-FIX,并返回到LRU尾部。

可以看到这里时间复杂度是O(N*N).当然如果是快速存储设备,可能在回到LRU尾部重新扫描时,之前IOFIX的page已经完成了IO,因此可以直接放到FreeList上。因此快速存储设备最优可以到达O(N)

按照Inaam的说法,5.6.12对此会有优化,拭目以待。另外在5.6.12中,可能会有很多sleep被替换成condition wait,希望这些能对写负载有帮助。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
网络协议 Java 关系型数据库
年薪50W阿里P7架构师必备知识:并发+JVM+多线程+Netty+MySQL
线程基础、线程之间的共享和协作一 线程基础、线程之间的共享和协作二 线程的并发工具类 线程的并发工具类、原子操作CAS 显式锁和AQS一 显式锁和AQS二 并发容器一 并发容器二 并发容器三、线程池一 线程池二、并发安全一
|
12月前
|
存储 算法 关系型数据库
5.5 【MySQL】Page Header(页面头部)
5.5 【MySQL】Page Header(页面头部)
104 0
|
3月前
|
关系型数据库 MySQL 调度
深入理解MySQL InnoDB线程模型
深入理解MySQL InnoDB线程模型
|
4月前
|
关系型数据库 MySQL Java
实时计算 Flink版产品使用合集之同步MySQL数据到Hologres时,配置线程池的大小该考虑哪些
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStreamAPI、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
4月前
|
关系型数据库 MySQL Java
实时计算 Flink版产品使用合集之mysql通过flink cdc同步数据,有没有办法所有表共用一个dump线程
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
11月前
|
druid 关系型数据库 MySQL
高并发下 MySQL Statement Cancellation Timer 的线程数暴涨
高并发下 MySQL Statement Cancellation Timer 的线程数暴涨
|
SQL Oracle 前端开发
使用MariaDB线程池提高MySQL的扩展性
MySQL的线程池能够有效地解决大量短连接的性能问题,大幅提高MySQL数据库的扩展性。但官方MySQL的线程池在收费的企业版中才有,免费的社区版中没有这个功能,这里介绍MairaDB的线程池。
207 0
|
21天前
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
91 2
|
16天前
|
弹性计算 关系型数据库 数据库
手把手带你从自建 MySQL 迁移到云数据库,一步就能脱胎换骨
阿里云瑶池数据库来开课啦!自建数据库迁移至云数据库 RDS原来只要一步操作就能搞定!点击阅读原文完成实验就可获得一本日历哦~
|
19天前
|
关系型数据库 MySQL 数据库
RDS MySQL灾备服务协同解决方案构建问题之数据库备份数据的云上云下迁移如何解决
RDS MySQL灾备服务协同解决方案构建问题之数据库备份数据的云上云下迁移如何解决