SlideShare une entreprise Scribd logo
1  sur  18
Télécharger pour lire hors ligne
InnoDB AIO 原理及相关bug分析

        淘宝希羽
议程
•   InnoDB AIO参数设置
•   InnoDB模拟AIO原理
•   读写线程如何调用及诊断
•   主线程帮什么忙
•   DDL丢表问题分析及解决
InnoDB AIO 参数设置
• innodb_file_io_threads
   – 自从5.1 plugin 和5.5版本被舍弃
   – built-in版本默认值为4,意味着:
        •   innodb_read_io_threads=1
        •   innodb_write_io_threads=1
        •   一个insert buffer线程
        •   一个log线程

• 在SSD 环境, 拥有更强的IO能力,典型设置:
   –   innodb_thread_concurrency=64
   –   innodb_read_io_threads=8
   –   innodb_write_io_threads=8
   –   innodb_io_capacity=2000
InnoDB IO 工作流程
InnoDB 模拟AIO:
                初始化
• srv/srv0start.c:
  innobase_start_or_create_for_mysql
InnoDB模拟AIO:
                 关键的数据结构
• struct os_aio_array_t,4个实例
  – mutex
  – not_full/is_empty (os_event_t)
  – n_slots/n_segments/n_reserved
  – slots (os_aio_slot_t)
• struct os_aio_slot_t
    n_slot=n_[read|write]_segs*n_per_seg
    slot[0]         …    …       slot[n_slot]
    pos|reserved|..
InnoDB模拟AIO:
             工作线程和唤醒线程句柄
• 工作线程句柄 fil/fil0fil.c:fil_aio_wait
  – os_aio_simulated_handle
• 唤醒AIO线程句柄(多处调用)
  – os_aio_simulated_wake_handler_thread
  – 典型场景:找不到可用slot时强制唤醒
   slot[0]   slot[1]   …slot[k]…             slot[n-1]
                       if found slot that
                       needs read/write
                       io, call                           broadcast in
                       os_file_read/write                wake_handler
                       else wait for event
InnoDB 模拟AIO:
核心函数os_aio_simulated_handle
- 获取segment slots
- 如果slot被保留并且io_already_done, 那么goto
  slot_io_done(释放slot及io_already_done);
- 如果任何slot被保留时间>2s, 那么选择最老的以防止饥饿;
- 如果没有找到上述条件的slot, 选择被保留且offset最小的slot.
- 上述两个条件均未找到slot(被保留的),则 goto wait_for_io;
- 否则必然到到一个slot,再继续找到slot’被保留且与之前找到
  slot有连续的IO,再找到与slot’有如此关系的slot’’ …(找到64个)
- memcpy 上述找到的 slot的buf到 combined_buf
- 调用os_file_read/os_file_write来完成读/写.

可能的优化余地:增大slot及批量写的slot数目
Native AIO slot数目为AIO的1/8, 调用os_aio_linux_handle
读写线程如何调用及诊断:
            一切以调用fil_io为开始
• fil_io
   – fil_mutex_enter_and_prepare_for_io
   – fil_node_prepare_for_io
   – os_aio
      • os_aio_simulated_handle
           – os_file_pwrite (lseek && write && [flush])
   – fil_node_complete_io
• fil_flush
• 读同步,写异步
读写线程如何调用及诊断:
            文件IO的诊断信息
• fil_node_prepare_for_io
    – 从fil_system->LRU将node移走(被占用)
    – n_pending++
• fil_node_complete_io
    –   n_pending--
    –   modification_counter++ (set to flush_counter when freed)
    –   将node->space 加到fil_system->unflushed_spaces
    –   将node回到fil_system->LRU
• fil_flush
    –   space->n_pending_flushes++
    –   n_pending_flushes++
    –   os_file_flush
    –   n_pending_flushes—
    –   space->n_pending_flushes--
主线程帮什么忙
• 调用buf_flush_batch来刷肮页和唤醒AIO
 – 以不同的负荷来刷脏页(以当前IO的繁忙程度来
   分配IO能力)
 – 从flush_list刷页块(相邻页也被刷)
   • buf_flush_list->buf_flush_batch(BUF_FLUSH_LIST)
 – 最终调用 buf_flush_buffered_writes
   • 从缓存中的doublewrite 刷可能的buffer到存储
   • 如果使用模拟AIO,则要唤醒AIO线程
flush_list和LRU_list
  • 两种刷页方式的特点
      – 所有页先从buffer pool刷到缓存中的doublewrite
          • 主线程周期性触发(修改页比例 > 脏页比例), 从flush_list中
            刷
          • 工作线程主动刷(没有可用的空闲blocks),从LRU_list中刷
      – doublewrite组成: 128 pages, each 16K, all 2M

      – 始于buf_flush_page: 将 flushable 页从buffer pool 写
        到某个文件                      fil_io (no trx_dwb)

buf_flush_page   buf_flush_write_block_low    buf_flush_post_to_doublewrite_buf

                                             buf_flush_buffer_writes
DDL表丢失问题背景
•   #62100
•   DDL失败后表丢失
•   过去一年在线上操作经历5次
•   自2008年就在buglist中存在
•   2011年下提交patch
•   2012年初Mark&Inaam讨论改进patch
•   MySQL 5.5.22融入patch
DDL 丢表分析:
              基本信息
• fil_rename_tablespace
  – 设置stop_ios=TURE
  – 等待直到n_pending==0 &&
    n_pending_flushes==0
  – 设置stop_ios=FALSE
• fil_mutex_enter_and_prepare_for_io
  – 等待直到stop_ios = FALSE
• 被阻塞直到超时, mysqld最终abort
DDL丢表分析:
关键的backtrace
DDL丢表分析:
               自问自答
• 为什么n_pending > 0?
  – 没有活动的写线程
• 没有写线程没有被唤醒?
  – 被阻塞在doublewrite->mutex
• 谁拥有doublewrite->mutex
  – srv_master 线程拥有但被阻塞
• 为什么DDL异常下不能正确回滚?
  – 没有正确设置参数以告知调用者
• 其它风险?
  – 对DDL操作的中间临时表的写是否延时
DDL丢表解决方法
• 在等待时间过长时强制唤醒AIO线程
• 正确设置回滚的标记
• 修正max_open_files的判断逻辑位置
最后
• 讨论时间

Contenu connexe

Tendances

Java SE 8 技術手冊第 14 章 - NIO 與 NIO2
Java SE 8 技術手冊第 14 章 - NIO 與 NIO2Java SE 8 技術手冊第 14 章 - NIO 與 NIO2
Java SE 8 技術手冊第 14 章 - NIO 與 NIO2Justin Lin
 
Web scraping入門1
Web scraping入門1Web scraping入門1
Web scraping入門1兆欽 丘
 
執行緒與並行API
執行緒與並行API執行緒與並行API
執行緒與並行APIJustin Lin
 
Ch1 系统启动
Ch1 系统启动Ch1 系统启动
Ch1 系统启动guest4d1b8c
 
Java SE 8 技術手冊第 10 章 - 輸入輸出
Java SE 8 技術手冊第 10 章 - 輸入輸出Java SE 8 技術手冊第 10 章 - 輸入輸出
Java SE 8 技術手冊第 10 章 - 輸入輸出Justin Lin
 
全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版Simen Li
 
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJava SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJustin Lin
 
從模組到類別
從模組到類別從模組到類別
從模組到類別Justin Lin
 
揭秘家用路由器Ch10 sharing
揭秘家用路由器Ch10 sharing揭秘家用路由器Ch10 sharing
揭秘家用路由器Ch10 sharingYi-Jun Zheng
 
PHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming SkillsPHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming SkillsHo Kim
 
使用 Eloquent ORM
使用 Eloquent ORM使用 Eloquent ORM
使用 Eloquent ORMShengyou Fan
 
型態與運算子
型態與運算子型態與運算子
型態與運算子Justin Lin
 
Coreseek/Sphinx 全文检索实践指南
Coreseek/Sphinx 全文检索实践指南Coreseek/Sphinx 全文检索实践指南
Coreseek/Sphinx 全文检索实践指南HonestQiao
 
02.python基础
02.python基础02.python基础
02.python基础modou li
 
不一樣的Web server... coServ
不一樣的Web server... coServ不一樣的Web server... coServ
不一樣的Web server... coServBen Lue
 
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJava SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJustin Lin
 

Tendances (20)

Java SE 8 技術手冊第 14 章 - NIO 與 NIO2
Java SE 8 技術手冊第 14 章 - NIO 與 NIO2Java SE 8 技術手冊第 14 章 - NIO 與 NIO2
Java SE 8 技術手冊第 14 章 - NIO 與 NIO2
 
Web scraping入門1
Web scraping入門1Web scraping入門1
Web scraping入門1
 
輸入輸出
輸入輸出輸入輸出
輸入輸出
 
執行緒與並行API
執行緒與並行API執行緒與並行API
執行緒與並行API
 
Ch1 系统启动
Ch1 系统启动Ch1 系统启动
Ch1 系统启动
 
Java SE 8 技術手冊第 10 章 - 輸入輸出
Java SE 8 技術手冊第 10 章 - 輸入輸出Java SE 8 技術手冊第 10 章 - 輸入輸出
Java SE 8 技術手冊第 10 章 - 輸入輸出
 
Node分享 展烨
Node分享 展烨Node分享 展烨
Node分享 展烨
 
Php
PhpPhp
Php
 
全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版
 
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJava SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
 
從模組到類別
從模組到類別從模組到類別
從模組到類別
 
Tcfsh bootcamp day2
 Tcfsh bootcamp day2 Tcfsh bootcamp day2
Tcfsh bootcamp day2
 
揭秘家用路由器Ch10 sharing
揭秘家用路由器Ch10 sharing揭秘家用路由器Ch10 sharing
揭秘家用路由器Ch10 sharing
 
PHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming SkillsPHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming Skills
 
使用 Eloquent ORM
使用 Eloquent ORM使用 Eloquent ORM
使用 Eloquent ORM
 
型態與運算子
型態與運算子型態與運算子
型態與運算子
 
Coreseek/Sphinx 全文检索实践指南
Coreseek/Sphinx 全文检索实践指南Coreseek/Sphinx 全文检索实践指南
Coreseek/Sphinx 全文检索实践指南
 
02.python基础
02.python基础02.python基础
02.python基础
 
不一樣的Web server... coServ
不一樣的Web server... coServ不一樣的Web server... coServ
不一樣的Web server... coServ
 
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJava SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
 

Similaire à S1: InnoDB AIO原理及相关bug分析

Mysql体系结构及原理(innodb)公开版
Mysql体系结构及原理(innodb)公开版Mysql体系结构及原理(innodb)公开版
Mysql体系结构及原理(innodb)公开版longxibendi
 
数据库内核分享——第一期
数据库内核分享——第一期数据库内核分享——第一期
数据库内核分享——第一期frogd
 
数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)
数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)
数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)frogd
 
InnoDB Transaction Lock and MVCC
InnoDB Transaction Lock and MVCCInnoDB Transaction Lock and MVCC
InnoDB Transaction Lock and MVCCfrogd
 
Buffer pool implementaion inno db vs oracle
Buffer pool implementaion inno db vs oracleBuffer pool implementaion inno db vs oracle
Buffer pool implementaion inno db vs oraclefrogd
 
Introduction to Nand Flash interface (chinese)
Introduction to Nand Flash interface (chinese)Introduction to Nand Flash interface (chinese)
Introduction to Nand Flash interface (chinese)Sneeker Yeh
 
My sql 5.6新特性深入剖析——innodb引擎
My sql 5.6新特性深入剖析——innodb引擎My sql 5.6新特性深入剖析——innodb引擎
My sql 5.6新特性深入剖析——innodb引擎frogd
 
MySQL AIO详解
MySQL AIO详解MySQL AIO详解
MySQL AIO详解mysqlops
 
为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)Kris Mok
 
对MySQL应用的一些总结
对MySQL应用的一些总结对MySQL应用的一些总结
对MySQL应用的一些总结Lixun Peng
 
ElasticSearch Training#2 (advanced concepts)-ESCC#1
ElasticSearch Training#2 (advanced concepts)-ESCC#1ElasticSearch Training#2 (advanced concepts)-ESCC#1
ElasticSearch Training#2 (advanced concepts)-ESCC#1medcl
 
Showinnodbstatus公开
Showinnodbstatus公开Showinnodbstatus公开
Showinnodbstatus公开longxibendi
 
Altibase管理培训 安装篇
Altibase管理培训 安装篇Altibase管理培训 安装篇
Altibase管理培训 安装篇小新 制造
 
Mysql调优
Mysql调优Mysql调优
Mysql调优ken shin
 
MySQL新技术探索与实践
MySQL新技术探索与实践MySQL新技术探索与实践
MySQL新技术探索与实践Lixun Peng
 
用Raspberry PI學Linux驅動程式
用Raspberry PI學Linux驅動程式用Raspberry PI學Linux驅動程式
用Raspberry PI學Linux驅動程式Stanley Ho
 
Linux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeLinux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeAngel Boy
 
2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江thinkinlamp
 
2011 06-12-lamp-mysql
2011 06-12-lamp-mysql2011 06-12-lamp-mysql
2011 06-12-lamp-mysqlpwesh
 

Similaire à S1: InnoDB AIO原理及相关bug分析 (20)

Mysql体系结构及原理(innodb)公开版
Mysql体系结构及原理(innodb)公开版Mysql体系结构及原理(innodb)公开版
Mysql体系结构及原理(innodb)公开版
 
数据库内核分享——第一期
数据库内核分享——第一期数据库内核分享——第一期
数据库内核分享——第一期
 
数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)
数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)
数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)
 
InnoDB Transaction Lock and MVCC
InnoDB Transaction Lock and MVCCInnoDB Transaction Lock and MVCC
InnoDB Transaction Lock and MVCC
 
Buffer pool implementaion inno db vs oracle
Buffer pool implementaion inno db vs oracleBuffer pool implementaion inno db vs oracle
Buffer pool implementaion inno db vs oracle
 
Introduction to Nand Flash interface (chinese)
Introduction to Nand Flash interface (chinese)Introduction to Nand Flash interface (chinese)
Introduction to Nand Flash interface (chinese)
 
My sql 5.6新特性深入剖析——innodb引擎
My sql 5.6新特性深入剖析——innodb引擎My sql 5.6新特性深入剖析——innodb引擎
My sql 5.6新特性深入剖析——innodb引擎
 
MySQL AIO详解
MySQL AIO详解MySQL AIO详解
MySQL AIO详解
 
为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)
 
对MySQL应用的一些总结
对MySQL应用的一些总结对MySQL应用的一些总结
对MySQL应用的一些总结
 
ElasticSearch Training#2 (advanced concepts)-ESCC#1
ElasticSearch Training#2 (advanced concepts)-ESCC#1ElasticSearch Training#2 (advanced concepts)-ESCC#1
ElasticSearch Training#2 (advanced concepts)-ESCC#1
 
Showinnodbstatus公开
Showinnodbstatus公开Showinnodbstatus公开
Showinnodbstatus公开
 
Altibase管理培训 安装篇
Altibase管理培训 安装篇Altibase管理培训 安装篇
Altibase管理培训 安装篇
 
Rootkit 101
Rootkit 101Rootkit 101
Rootkit 101
 
Mysql调优
Mysql调优Mysql调优
Mysql调优
 
MySQL新技术探索与实践
MySQL新技术探索与实践MySQL新技术探索与实践
MySQL新技术探索与实践
 
用Raspberry PI學Linux驅動程式
用Raspberry PI學Linux驅動程式用Raspberry PI學Linux驅動程式
用Raspberry PI學Linux驅動程式
 
Linux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeLinux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledge
 
2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江
 
2011 06-12-lamp-mysql
2011 06-12-lamp-mysql2011 06-12-lamp-mysql
2011 06-12-lamp-mysql
 

Plus de Hui Liu

5.6 nutshell - 性能优化
5.6 nutshell  - 性能优化5.6 nutshell  - 性能优化
5.6 nutshell - 性能优化Hui Liu
 
MySQL的并发线程性能问题
MySQL的并发线程性能问题MySQL的并发线程性能问题
MySQL的并发线程性能问题Hui Liu
 
InnoDB并发控制在密集型并发更新下的问题
InnoDB并发控制在密集型并发更新下的问题InnoDB并发控制在密集型并发更新下的问题
InnoDB并发控制在密集型并发更新下的问题Hui Liu
 
DBA学院课程之:MySQL故障诊断案例
DBA学院课程之:MySQL故障诊断案例DBA学院课程之:MySQL故障诊断案例
DBA学院课程之:MySQL故障诊断案例Hui Liu
 
阿里集团MySQL特性(5.5介绍)
阿里集团MySQL特性(5.5介绍)阿里集团MySQL特性(5.5介绍)
阿里集团MySQL特性(5.5介绍)Hui Liu
 
阿里集团MySQL并行复制特性
阿里集团MySQL并行复制特性阿里集团MySQL并行复制特性
阿里集团MySQL并行复制特性Hui Liu
 
InnoDB IO优化
InnoDB IO优化InnoDB IO优化
InnoDB IO优化Hui Liu
 

Plus de Hui Liu (7)

5.6 nutshell - 性能优化
5.6 nutshell  - 性能优化5.6 nutshell  - 性能优化
5.6 nutshell - 性能优化
 
MySQL的并发线程性能问题
MySQL的并发线程性能问题MySQL的并发线程性能问题
MySQL的并发线程性能问题
 
InnoDB并发控制在密集型并发更新下的问题
InnoDB并发控制在密集型并发更新下的问题InnoDB并发控制在密集型并发更新下的问题
InnoDB并发控制在密集型并发更新下的问题
 
DBA学院课程之:MySQL故障诊断案例
DBA学院课程之:MySQL故障诊断案例DBA学院课程之:MySQL故障诊断案例
DBA学院课程之:MySQL故障诊断案例
 
阿里集团MySQL特性(5.5介绍)
阿里集团MySQL特性(5.5介绍)阿里集团MySQL特性(5.5介绍)
阿里集团MySQL特性(5.5介绍)
 
阿里集团MySQL并行复制特性
阿里集团MySQL并行复制特性阿里集团MySQL并行复制特性
阿里集团MySQL并行复制特性
 
InnoDB IO优化
InnoDB IO优化InnoDB IO优化
InnoDB IO优化
 

S1: InnoDB AIO原理及相关bug分析

  • 2. 议程 • InnoDB AIO参数设置 • InnoDB模拟AIO原理 • 读写线程如何调用及诊断 • 主线程帮什么忙 • DDL丢表问题分析及解决
  • 3. InnoDB AIO 参数设置 • innodb_file_io_threads – 自从5.1 plugin 和5.5版本被舍弃 – built-in版本默认值为4,意味着: • innodb_read_io_threads=1 • innodb_write_io_threads=1 • 一个insert buffer线程 • 一个log线程 • 在SSD 环境, 拥有更强的IO能力,典型设置: – innodb_thread_concurrency=64 – innodb_read_io_threads=8 – innodb_write_io_threads=8 – innodb_io_capacity=2000
  • 5. InnoDB 模拟AIO: 初始化 • srv/srv0start.c: innobase_start_or_create_for_mysql
  • 6. InnoDB模拟AIO: 关键的数据结构 • struct os_aio_array_t,4个实例 – mutex – not_full/is_empty (os_event_t) – n_slots/n_segments/n_reserved – slots (os_aio_slot_t) • struct os_aio_slot_t n_slot=n_[read|write]_segs*n_per_seg slot[0] … … slot[n_slot] pos|reserved|..
  • 7. InnoDB模拟AIO: 工作线程和唤醒线程句柄 • 工作线程句柄 fil/fil0fil.c:fil_aio_wait – os_aio_simulated_handle • 唤醒AIO线程句柄(多处调用) – os_aio_simulated_wake_handler_thread – 典型场景:找不到可用slot时强制唤醒 slot[0] slot[1] …slot[k]… slot[n-1] if found slot that needs read/write io, call broadcast in os_file_read/write wake_handler else wait for event
  • 8. InnoDB 模拟AIO: 核心函数os_aio_simulated_handle - 获取segment slots - 如果slot被保留并且io_already_done, 那么goto slot_io_done(释放slot及io_already_done); - 如果任何slot被保留时间>2s, 那么选择最老的以防止饥饿; - 如果没有找到上述条件的slot, 选择被保留且offset最小的slot. - 上述两个条件均未找到slot(被保留的),则 goto wait_for_io; - 否则必然到到一个slot,再继续找到slot’被保留且与之前找到 slot有连续的IO,再找到与slot’有如此关系的slot’’ …(找到64个) - memcpy 上述找到的 slot的buf到 combined_buf - 调用os_file_read/os_file_write来完成读/写. 可能的优化余地:增大slot及批量写的slot数目 Native AIO slot数目为AIO的1/8, 调用os_aio_linux_handle
  • 9. 读写线程如何调用及诊断: 一切以调用fil_io为开始 • fil_io – fil_mutex_enter_and_prepare_for_io – fil_node_prepare_for_io – os_aio • os_aio_simulated_handle – os_file_pwrite (lseek && write && [flush]) – fil_node_complete_io • fil_flush • 读同步,写异步
  • 10. 读写线程如何调用及诊断: 文件IO的诊断信息 • fil_node_prepare_for_io – 从fil_system->LRU将node移走(被占用) – n_pending++ • fil_node_complete_io – n_pending-- – modification_counter++ (set to flush_counter when freed) – 将node->space 加到fil_system->unflushed_spaces – 将node回到fil_system->LRU • fil_flush – space->n_pending_flushes++ – n_pending_flushes++ – os_file_flush – n_pending_flushes— – space->n_pending_flushes--
  • 11. 主线程帮什么忙 • 调用buf_flush_batch来刷肮页和唤醒AIO – 以不同的负荷来刷脏页(以当前IO的繁忙程度来 分配IO能力) – 从flush_list刷页块(相邻页也被刷) • buf_flush_list->buf_flush_batch(BUF_FLUSH_LIST) – 最终调用 buf_flush_buffered_writes • 从缓存中的doublewrite 刷可能的buffer到存储 • 如果使用模拟AIO,则要唤醒AIO线程
  • 12. flush_list和LRU_list • 两种刷页方式的特点 – 所有页先从buffer pool刷到缓存中的doublewrite • 主线程周期性触发(修改页比例 > 脏页比例), 从flush_list中 刷 • 工作线程主动刷(没有可用的空闲blocks),从LRU_list中刷 – doublewrite组成: 128 pages, each 16K, all 2M – 始于buf_flush_page: 将 flushable 页从buffer pool 写 到某个文件 fil_io (no trx_dwb) buf_flush_page buf_flush_write_block_low buf_flush_post_to_doublewrite_buf buf_flush_buffer_writes
  • 13. DDL表丢失问题背景 • #62100 • DDL失败后表丢失 • 过去一年在线上操作经历5次 • 自2008年就在buglist中存在 • 2011年下提交patch • 2012年初Mark&Inaam讨论改进patch • MySQL 5.5.22融入patch
  • 14. DDL 丢表分析: 基本信息 • fil_rename_tablespace – 设置stop_ios=TURE – 等待直到n_pending==0 && n_pending_flushes==0 – 设置stop_ios=FALSE • fil_mutex_enter_and_prepare_for_io – 等待直到stop_ios = FALSE • 被阻塞直到超时, mysqld最终abort
  • 16. DDL丢表分析: 自问自答 • 为什么n_pending > 0? – 没有活动的写线程 • 没有写线程没有被唤醒? – 被阻塞在doublewrite->mutex • 谁拥有doublewrite->mutex – srv_master 线程拥有但被阻塞 • 为什么DDL异常下不能正确回滚? – 没有正确设置参数以告知调用者 • 其它风险? – 对DDL操作的中间临时表的写是否延时