buf_flush_page_cleaner_coordinator协调线程的主循环主线程以最多1s的间隔或者收到buf_flush_event事件就会触发进行一轮的刷脏。

批量刷脏主要有3个场景。

同步刷脏

如果 buf_flush_sync_lsn > 0, 则因为redo log free space 不够了, 那么我们需要进入同步刷脏阶段了。同步刷脏场景下,所有需要写脏数据库的用户线程都会堵塞,这是很严重的情况。

正常刷脏

最常见逻辑 srv_check_activity(last_activity), 也就是系统有正常活动,有DML/DDL, 这个时候会通过 page_cleaner_flush_pages_recommendation() 函数去合理的判断应该刷多少个page, 既不抖动, 也能够满足刷脏需求

空闲刷脏

如果系统没有DML\DDL活动,且ret_sleep == OS_SYNC_TIME_EXCEEDED,说明比较空闲。空闲的情况下因为服务器IO比较空闲,所以Innodb使用buf_flush_page_cleaner_coordinator线程本身进行刷新,刷新的块数计算比较简单就是innodb_io_capacity设置的值。

/******************************************************************//**

page_cleaner thread tasked with flushing dirty pages from the buffer

pools. As of now we'll have only one coordinator.

@return a dummy parameter */

extern "C"

os_thread_ret_t

DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(

/*===============================================*/

void* arg MY_ATTRIBUTE((unused)))

/*!< in: a dummy parameter required by

os_thread_create */

{

/* 忽略一些逻辑 */

while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {

if (ret_sleep != OS_SYNC_TIME_EXCEEDED

&& srv_flush_sync

&& buf_flush_sync_lsn > 0) {

/* 场景1 */

} else if (srv_check_activity(last_activity)) {

ulint n_to_flush;

lsn_t lsn_limit = 0;

/* Estimate pages from flush_list to be flushed */

if (ret_sleep == OS_SYNC_TIME_EXCEEDED) {

last_activity = srv_get_activity_count();

n_to_flush =

page_cleaner_flush_pages_recommendation(

&lsn_limit, last_pages);

} else {

n_to_flush = 0;

}

/* 场景2 */

} else if (ret_sleep == OS_SYNC_TIME_EXCEEDED) {

/* 场景3 */

/* no activity, slept enough */

}

} else {

/* no activity, but woken up by event */

n_flushed = 0;

}

}

三种场景下的具体工作

同步刷脏

pc_request(ULINT_MAX, lsn_limit),会把lsn小于lsn_limit的都flush到硬盘,同时coordinator线程本身也会参与刷脏。

/* woke up for flush_sync */

mutex_enter(&page_cleaner->mutex);

lsn_t lsn_limit = buf_flush_sync_lsn;

buf_flush_sync_lsn = 0;

mutex_exit(&page_cleaner->mutex);

/* Request flushing for threads */

pc_request(ULINT_MAX, lsn_limit);

ib_time_monotonic_ms_t tm = ut_time_monotonic_ms();

/* Coordinator also treats requests */

while (pc_flush_slot() > 0) {}

/* only coordinator is using these counters,

so no need to protect by lock. */

page_cleaner->flush_time += ut_time_monotonic_ms() - tm;

page_cleaner->flush_pass++;

/* Wait for all slots to be finished */

ulint n_flushed_lru = 0;

ulint n_flushed_list = 0;

pc_wait_finished(&n_flushed_lru, &n_flushed_list);

if (n_flushed_list > 0 || n_flushed_lru > 0) {

buf_flush_stats(n_flushed_list, n_flushed_lru);

MONITOR_INC_VALUE_CUMULATIVE(

MONITOR_FLUSH_SYNC_TOTAL_PAGE,

MONITOR_FLUSH_SYNC_COUNT,

MONITOR_FLUSH_SYNC_PAGES,

n_flushed_lru + n_flushed_list);

}

n_flushed = n_flushed_lru + n_flushed_list;

正常刷脏

通过page_cleaner_flush_pages_recommendation计算需要刷新的页。

ulint n_to_flush;

lsn_t lsn_limit = 0;

/* Estimate pages from flush_list to be flushed */

if (ret_sleep == OS_SYNC_TIME_EXCEEDED) {

last_activity = srv_get_activity_count();

n_to_flush =

page_cleaner_flush_pages_recommendation(

&lsn_limit, last_pages);

} else {

n_to_flush = 0;

}

/* Request flushing for threads */

pc_request(n_to_flush, lsn_limit);

ib_time_monotonic_ms_t tm = ut_time_monotonic_ms();

/* Coordinator also treats requests */

while (pc_flush_slot() > 0) {

/* No op */

}

/* only coordinator is using these counters,

so no need to protect by lock. */

page_cleaner->flush_time += ut_time_monotonic_ms() - tm;

page_cleaner->flush_pass++ ;

/* Wait for all slots to be finished */

ulint n_flushed_lru = 0;

ulint n_flushed_list = 0;

pc_wait_finished(&n_flushed_lru, &n_flushed_list);

if (n_flushed_list > 0 || n_flushed_lru > 0) {

buf_flush_stats(n_flushed_list, n_flushed_lru);

}

if (ret_sleep == OS_SYNC_TIME_EXCEEDED) {

last_pages = n_flushed_list;

}

n_evicted += n_flushed_lru;

n_flushed_last += n_flushed_list;

n_flushed = n_flushed_lru + n_flushed_list;

if (n_flushed_lru) {

MONITOR_INC_VALUE_CUMULATIVE(

MONITOR_LRU_BATCH_FLUSH_TOTAL_PAGE,

MONITOR_LRU_BATCH_FLUSH_COUNT,

MONITOR_LRU_BATCH_FLUSH_PAGES,

n_flushed_lru);

}

if (n_flushed_list) {

MONITOR_INC_VALUE_CUMULATIVE(

MONITOR_FLUSH_ADAPTIVE_TOTAL_PAGE,

MONITOR_FLUSH_ADAPTIVE_COUNT,

MONITOR_FLUSH_ADAPTIVE_PAGES,

n_flushed_list);

}

空闲刷脏

空闲刷脏是coordinator自己进行,直接按照PCT_IO(100)来生成刷新数量。

#define PCT_IO(p) ((ulong) (srv_io_capacity * ((double) (p) / 100.0)))

buf_flush_lists(PCT_IO(100), LSN_MAX, &n_flushed);

n_flushed_last += n_flushed;

if (n_flushed) {

MONITOR_INC_VALUE_CUMULATIVE(

MONITOR_FLUSH_BACKGROUND_TOTAL_PAGE,

MONITOR_FLUSH_BACKGROUND_COUNT,

MONITOR_FLUSH_BACKGROUND_PAGES,

n_flushed);

}

mysql ssd 刷脏_MySQL-Innodb-批量刷脏的场景相关推荐

  1. mysql数据刷盘_MySQL InnoDB 日志管理机制中的MTR和日志刷盘

    1.MTR(mini-transaction) 在MySQL的 InnoDB日志管理机制中,有一个很重要的概念就是MTR.MTR是InnoDB存储擎中一个很重要的用来保证物理写的完整性和持久性的机制. ...

  2. mysql必须的组件_mysql innodb的重要组件

    innodb包涵如下几个组件 一.innodb_buffer_pool: 1 它主要用来缓存数据与索引(准确的讲由于innodb中的表是由聚集索引组织的,所以数据只不是过主键这个索引的叶子结点). 二 ...

  3. mysql备份和优化_MySql Innodb存储引擎--备份和优化

    备份的目的 做灾难恢复:对损坏的数据进行恢复和还原 需求改变:因需求改变而需要把数据还原到改变以前 测试:测试新功能是否可用 备份需要考虑的问题 可以容忍丢失多长时间的数据: 恢复数据要在多长时间内完 ...

  4. mysql ssd 性能测试 写入_MySQL服务器的SSD性能问题分析和测试详解

    [问题] 我们有台HP的服务器,SSD在写IOPS约5000时,%util达到80%以上,那么这块SSD的性能究竟有没有问题,为解决这个问题做了下面测试. [工具] blktrace是linux下用来 ...

  5. mysql 散列查询_MySQL InnoDB中hash查找表的实现

    MySQL版本:5.7.14 源码位置为hash0hash.h hash0hash.cc 作为一种时间复杂度最优为O(1)的数据结构,但是最坏时间复杂对位O(n)的一种数据结构,但是在良好的设计has ...

  6. mysql表空间权限_MySQL InnoDB表空间加密示例详解

    前言 从 MySQL5.7.11开始,MySQL对InnoDB支持存储在单独表空间中的表的数据加密 .此功能为物理表空间数据文件提供静态加密.该加密是在引擎内部数据页级别的加密手段,在数据页写入文件系 ...

  7. mysql锁表更新_Mysql InnoDB 数据更新导致锁表

    一.数据表结构 CREATE TABLE `jx_attach` ( `attach_id` int(11) NOT NULL AUTO_INCREMENT, `feed_id` int(11) DE ...

  8. mysql表空间不足_MySQL Innodb表空间不足的处理方法 风好大

    官方给出的解决方案: 添加和删除 InnoDB 数据和日志文件 这一节描述在InnoDB表空间耗尽空间之时,或者你想要改变日志文件大小之时,你可以做的一些事情. 最简单的,增加InnoDB表空间大小的 ...

  9. mysql 建表报错_mysql innodb 引擎 ,建表时报错:ERROR 1118 (42000)

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 mysql 5.7.20 当我在建表时,完整报错信息如下: ERROR 1118 (42000): Row size too large (> 81 ...

  10. mysql并发参数查看_MySQL Innodb 并发涉及参数

    可以通过innodb_thread_concurrency 来调节  并发线程数的限制值,使用innodb_thread_sleep_delay来调整当 并发 thread 到达 innodb_thr ...

最新文章

  1. cnn中关于平均池化和最大池化的理解
  2. ArcSDE工作机制
  3. 上计算机课睡觉检讨书400,小学生上自习课睡觉检讨书
  4. Array.prototype.slice Array.prototype.splice 用法阐述
  5. vue和aspx判断加页面传值.txt
  6. RDLC报表显示存储于数据库的图片
  7. 最详细 Spring Boot 入门(-)
  8. Struts1.x系列教程(19):LookupDispatchAction类处理一个form多个submit
  9. 国家电网考试计算机基础知识,大学计算机基础(国家电网考试整理)
  10. 51单片机学习1-8
  11. matlab画一只猫,【MATLAB系列04】当一只猫遇见了Matlab
  12. 多款iPhone遭遇中国禁售令!福建法院判决高通胜诉苹果
  13. 忍得住清贫 耐得住寂寞 禁得起诱惑
  14. python实现提取视频里的语音转换为文字
  15. 检测局域网内在线IP
  16. idea开发中git合并的代码,
  17. 黑马程序员Python学习一预备
  18. 【Java】环境搭建
  19. 微信公众号推送消息前期准备
  20. python爬虫,爬起点小说网小说

热门文章

  1. Java基本数据类型详解(为什么byte的范围是-2^7 ~ 2^7-1?)
  2. 如何保证缓存和数据库一致性?
  3. matlab非齐次泊松过程,非齐次泊松过程和复合Poisson过程.ppt
  4. 消除类游戏201512(C语言版)
  5. Git Cherry-pick (摘樱桃) 实现分支的部分提交合并到Master
  6. Linux cut命令详解
  7. 用WebStorm搭建vue项目
  8. element-ui——element-ui 问号提示组件的使用
  9. 利用U盘进行软件加密的方法
  10. [附源码]PHP计算机毕业设计天源旅游网站(程序+LW)