MySQL 5.7: Page Cleaner的刷脏问题

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

之前我已经写过一篇博客,讨论过在flush LRU_LIST/FLUSH_LIST时,5.7对其做的优化,总的来说,就是使用类似Hazard Pointer的方式,避免在flush的过程中重复扫描LIST,将时间复杂度从O(N*N)下降到了O(N)。有兴趣的同学可以翻阅下这篇博客:http://mysqllover.com/?p=1031

本文的目的主要是补充下5.7目前所做的多个page cleaner的实现思路,社区相关的bug讨论,以及我近期对page cleaner所做的一些优化工作。

支持多个Page cleaner

为了提升扩展性和刷脏效率,在5.7.4版本里引入了多个page cleaner线程。从而达到并行刷脏的效果。

在该版本中,Page cleaner并未和buffer pool绑定,其模型为一个协调线程 + 多个工作线程,协调线程本身也是工作线程。因此如果innodb_page_cleaners设置为8,那么就是一个协调线程,加7个工作线程

协调线程的入口函数为buf_flush_page_cleaner_coordinator

工作线程的入口函数为buf_flush_page_cleaner_worker

在启动时会初始化一个slot数组,大小为buffer pool instance的个数(buf_flush_page_cleaner_init)。

协调线程在决定了需要flush的page数和lsn_limit后,会设置slot数组,将其中每个slot的状态设置为PAGE_CLEANER_STATE_REQUESTED, 并设置目标page数及lsn_limit,然后唤醒worker线程 (pc_request)

worker线程被唤醒后,从slot数组中取一个未被占用的slot,修改其状态,表示已被调度,然后对该slot所对应的buffer pool instance进行操作。

为了支持对单个bp instance进行LRU/FLUSH_LIST的刷新,对原有代码做了大量的改动,worker线程可以直接调用buf_flush_LRU_list 及buf_flush_do_batch 指定buffer pool进行flush操作。 互相之间不干扰,因此可以并行刷脏。 改动整体而言比较简单。

由于当前版本page cleaner是不和buffer pool绑定的,因此,最好不要将page cleaner的个数设定的大于buffer pool instance的个数。

如果当前实例不活跃,即没有负载时,则单独由协调线程做100%的刷脏。

worklog:

http://dev.mysql.com/worklog/task/?id=6642

代码比较简单,不展开阐述,感兴趣的可以读读补丁:

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/7189

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/7244

进一步改进Multi Page Cleaner

在MySQL 5.7.5里进一步改进了multi page cleaner特性,让其支持在crash recovery和shutdown时能够应用多个page cleaner特性,来加快崩溃恢复和关闭实例的速度。

实现方式也比较简单,例如对于recovery过程中,如果需要刷脏时,不主动刷脏,而是唤醒page cleaner,然后等待page cleaner完成。

PATCH:

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/8489

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/8522

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/8532

社区相关BUG

http://bugs.mysql.com/bug.php?id=68481

期望允许page cleaner做furious flush,而不是每秒做一次,对于写入负载很猛的场景,很容易到达同步checkpoint点

http://bugs.mysql.com/bug.php?id=70500

不管是否active,总是做LRU FLUSH。 因为在某些场景下,可能没什么用户负载,checkpoint age很低,但诸如purge操作需要很多free page时, 这时候我们其实期望page cleaner 负责清出更多的空闲block。

事实上, webscalesql已经这么做了。感兴趣的可以直接去checkout webscalesql的代码看看

http://bugs.mysql.com/bug.php?id=71411

buf_do_LRU_batch函数的返回值表示从LRU上flush的脏页数,但却把压缩表上驱逐的解压页也纳入了统计。这可能会引起某些innodb_metrics的错误值。 这还会影响到page cleaner的刷脏策略。

http://bugs.mysql.com/bug.php?id=74637

让page cleaner的刷新策略更加自适应。应该根据redo space 和free list做出自适应的page cleaner策略调整,我(id zhai weixiang) 在bug中也回复了可行的策略:对于lru_list,percona server有更加聪明的做法,独立出LRU线程并根据free list长度调整sleep时间;对于flush_list,我们可以对sleep的时间做动态调整,根据max_modified_age_sync来进行估算。

可行的改进

针对page cleaner的问题,我基于阿里内部的版本中做了些修改 (感兴趣的阿里同学可以找我拿测试branch),大概包含如下几点:

  1. 分拆LRU FLUSH到独立线程,根据FREE LIST长度自适应调整刷LRU策略 (from percona)
  2. PAGE CLEANER支持multi page cleaner (from 5.7)。并根据redo space 计算自适应的刷脏频率
  3. 从用户线程移除SINGLE PAGE FLUSH,总是由LRU FLUSH线程来释放空闲page.
  4. MULTI PAGE CLEANER依然会引起double write buffer的单点竞争。为了解决这个问题,引入多个double write file,每个double write buffer文件对应特定的buffer pool instance.
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
7月前
|
存储 算法 关系型数据库
5.5 【MySQL】Page Header(页面头部)
5.5 【MySQL】Page Header(页面头部)
61 0
|
关系型数据库 Shell 数据库
MySQL损坏page问题分析
背景 MySQL5.7.21 Centos 7.4 innodb_force_recovery=0 信息收集 MySQL物理备份报错 190425 11:58:54 >> log scanned up to (174805994673) 190425 11:58:55 >> log.
4091 0
|
关系型数据库 MySQL 索引
关于MYSQL INNODB index page header学习和实验总结
关于INNODB  index header 所用到的工具是自己写的mysqlblock和bcview, 我放到了百度云盘 http://pan.baidu.com/s/1num76RJ 供大家下载和使用 普通表空间(及设置了innodb_file_per_table每个表都对应一个idb文件)从第4个块开始通常是innodb的数据页。
1118 0
|
关系型数据库 MySQL Linux
MYSQL Space id in fsp header,but in the page header错误
今天启动MYSQL的时候发现如下问题: 2015-12-14 20:51:59 2098 [ERROR] InnoDB: Space id in fsp header 131225,but in the page header 65 2015-12-14 20:5...
2726 0