我们知道InnoDB采用Write Ahead Log策略来防止宕机数据丢失,即事务提交时,先写重做日志,再修改内存数据页,这样就产生了脏页。既然有重做日志保证数据持久性,查询时也可以直接从缓冲池页中取数据,那为什么还要刷新脏页到磁盘呢?如果重做日志可以无限增大,同时缓冲池足够大,能够缓存所有数据,那么是不需要将缓冲池中的脏页刷新到磁盘。但是,通常会有以下几个问题:

服务器内存有限,缓冲池不够用,无法缓存全部数据重做日志无限增大成本要求太高宕机时如果重做全部日志恢复时间过长 事实上,当数据库宕机时,数据库不需要重做所有的日志,只需要执行上次刷入点之后的日志。这个点就叫做Checkpoint,它解决了以上的问题: 缩短数据库恢复时间缓冲池不够用时,将脏页刷新到磁盘重做日志不可用时,刷新脏页

重做日志被设计成可循环使用,当日志文件写满时,重做日志中对应数据已经被刷新到磁盘的那部分不再需要的日志可以被覆盖重用。

InnoDB引擎通过LSN(Log Sequence Number)来标记版本,LSN是日志空间中每条日志的结束点,用字节偏移量来表示。每个page有LSN,redo log也有LSN,Checkpoint也有LSN。可以通过命令show engine innodb status来观察:

[plain] view plain copy

--- LOG

--- Log sequence number 1039878815567

Log flushed up to 1039878815567 Pages flushed up to 1039878814486

Last checkpoint at 1039878814486 0 pending log writes, 0 pending chkp writes

5469310 log i/o's done, 1.00 log i/o's/second

Checkpoint机制每次刷新多少页,从哪里取脏页,什么时间触发刷新?这些都是很复杂的。有两种Checkpoint,分别为: Sharp CheckpointFuzzy Checkpoint Sharp Checkpoint发生在关闭数据库时,将所有脏页刷回磁盘。在运行时使用Fuzzy Checkpoint进行部分脏页的刷新。部分脏页刷新有以下几种: Master Thread CheckpointFLUSH_LRU_LIST CheckpointAsync/Sync Flush CheckpointDirty Page too much Checkpoint Master Thread Checkpoint Master Thread以每秒或每十秒的速度从缓冲池的脏页列表中刷新一定比例的页回磁盘。这个过程是异步的,不会阻塞查询线程。Flush LRU List Checkpoint

InnoDB要保证LRU列表中有100左右空闲页可使用。在InnoDB1.1.X版本前,要检查LRU中是否有足够的页用于用户查询操作线程,如果没有,会将LRU列表尾端的页淘汰,如果被淘汰的页中有脏页,会强制执行Checkpoint刷回脏页数据到磁盘,显然这会阻塞用户查询线程。从InnoDB1.2.X版本开始,这个检查放到单独的Page Cleaner Thread中进行,并且用户可以通过innodb_lru_scan_depth控制LRU列表中可用页的数量,默认值为1024。Async/Sync Flush Checkpoint

是指重做日志文件不可用时,需要强制将脏页列表中的一些页刷新回磁盘。这可以保证重做日志文件可循环使用。在InnoDB1.2.X版本之前,Async Flush Checkpoint会阻塞发现问题的用户查询线程,Sync Flush Checkpoint会阻塞所有查询线程。InnoDB1.2.X之后放到单独的Page Cleaner Thread。Dirty Page Too Much Checkpoint

脏页数量太多时,InnoDB引擎会强制进行Checkpoint。目的还是为了保证缓冲池中有足够可用的空闲页。其可以通过参数innodb_max_dirty_pages_pct来设置,默认为75%:

[plain] view plain copy

(root@localhost)[(none)]> show variables like 'innodb_max_dirty_pages_pct'; +----------------------------+-------+

| Variable_name | Value | +----------------------------+-------+

| innodb_max_dirty_pages_pct | 75 | +----------------------------+-------+

1 row in set (0.00 sec)

以上是脏页刷新的几种触发机制,接下来,细说一下日志机制及其中第3点Async/Sync flush checkpoint原理。 Log及Checkpoint简介

Innodb的事务日志是指Redo log,简称Log,保存在日志文件ib_logfile*里面。Innodb还有另外一个日志Undo log,但Undo log是存放在共享表空间里面的(ibdata*文件)。

由于Log和Checkpoint紧密相关,因此将这两部分合在一起分析。

名词解释:LSN,日志序列号,Innodb的日志序列号是一个64位的整型。

Log写入

LSN实际上对应日志文件的偏移量,新的LSN=旧的LSN + 写入的日志大小。举例如下:

LSN=1G,日志文件大小总共为600M,本次写入512字节,则实际写入操作为:

| --- 求出偏移量:由于LSN数值远大于日志文件大小,因此通过取余方式,得到偏移量为400M;

| --- 写入日志:找到偏移400M的位置,写入512字节日志内容,下一个事务的LSN就是1000000512;

Checkpoint写入

Innodb实现了Fuzzy Checkpoint的机制,每次取到最老的脏页,然后确保此脏页对应的LSN之前的LSN都已经写入日志文件,再将此脏页的LSN作为Checkpoint点记录到日志文件,意思就是“此LSN之前的LSN对应的日志和数据都已经写入磁盘文件”。恢复数据文件的时候,Innodb扫描日志文件,当发现LSN小于Checkpoint对应的LSN,就认为恢复已经完成。

Checkpoint写入的位置在日志文件开头固定的偏移量处,即每次写Checkpoint都覆盖之前的Checkpoint信息。

Flush刷新流程及原理介绍

由于Checkpoint和日志紧密相关,将日志和Checkpoint一起说明,详细的实现机制如下:

Innodb的一条事务日志共经历4个阶段:

1) 创建阶段:事务创建一条日志;

2) 日志刷盘:日志写入到磁盘上的日志文件;

3) 数据刷盘:日志对应的脏页数据写入到磁盘上的数据文件;

4) 写CKP:日志被当作Checkpoint写入日志文件;

对应这4个阶段,系统记录了4个日志相关的信息,用于其它各种处理使用:

Log sequence number(LSN1):当前系统LSN最大值,新的事务日志LSN将在此基础上生成(LSN1+新日志的大小);

Log flushed up to(LSN2):当前已经写入日志文件的LSN;

Pages flushed up to(LSN3):当前最旧的脏页数据对应的LSN,写Checkpoint的时候直接将此LSN写入到日志文件;

Last checkpoint at(LSN4):当前已经写入Checkpoint的LSN;

对于系统来说,以上4个LSN是递减的,即: LSN1>=LSN2>=LSN3>=LSN4.

具体的样例如下(使用show engine innodb status \G命令查看)

[plain] view plain copy

--- LOG

--- Log sequence number 1039878815567

Log flushed up to 1039878815567 Pages flushed up to 1039878814486

Last checkpoint at 1039878814486 0 pending log writes, 0 pending chkp writes

5469310 log i/o's done, 1.00 log i/o's/second

Async/Sync Flush Checkpoint原理

Innodb的数据并不是实时写盘的,为了避免宕机时数据丢失,保证数据的ACID属性,Innodb至少要保证数据对应的日志不能丢失。对于不同的情况,Innodb采取不同的对策:

1)宕机导致日志丢失

Innodb有日志刷盘机制,可以通过innodb_flush_log_at_trx_commit参数进行控制;

2)日志覆盖导致日志丢失

Innodb日志文件大小是固定的,写入的时候通过取余来计算偏移量,这样存在两个LSN写入到同一位置的可能,后面写的把前面写得就覆盖了,以“写入机制”章节的样例为例,LSN=100000000和LSN=1600000000两个日志的偏移量是相同的了。这种情况下,为了保证数据一致性,必须要求LSN=1000000000对应的脏页数据都已经刷到磁盘中,也就是要求Last checkpoint对应的LSN一定要大于1000000000,否则覆盖后日志也没有了,数据也没有刷盘,一旦宕机,数据就丢失了。

为了解决第二种情况导致数据丢失的问题,Innodb实现了一套日志保护机制,详细实现如下:

直线代表日志空间(Log cap,约等于日志文件总大小*0.8,0.8是一个安全系数),Ckp age和Buf age是两个浮动的点,Buf async、Buf sync、Ckp async、Ckp sync是几个固定的点。各个概念的含义如下:

概念计算含义

Ckp ageLSN1- LSN4还没有做Checkpoint的日志范围,若Ckp age超过日志空间,说明被覆盖的日志(LSN1-LSN4-Log cap)对应日志和数据“可能”还没有刷到磁盘上

Buf ageLSN1- LSN3还没有将脏页刷盘的日志的范围,若Buf age超过日志空间,说明被覆盖的日志(LSN1-LSN3-Log cap)对应数据“肯定”还没有刷到磁盘上

Buf async日志空间大小 * 7/8强制将Buf age-Buf async的脏页刷盘,此时事务还可以继续执行,所以为async,对事务的执行速度没有直接影响(有间接影响,例如CPU和磁盘更忙了,事务的执行速度可能受到影响)

Buf sync日志空间大小 * 15/16强制将2*(Buf age-Buf async)的脏页刷盘,此时事务停止执行,所以为sync,由于有大量的脏页刷盘,因此阻塞的时间比Ckp sync要长。

Ckp async日志空间大小 * 31/32强制写Checkpoint,此时事务还可以继续执行,所以为async,对事务的执行速度没有影响(间接影响也不大,因为写Checkpoint的操作比较简单)

Ckp sync日志空间大小 * 64/64强制写Checkpoint,此时事务停止执行,所以为sync,但由于写Checkpoint的操作比较简单,即使阻塞,时间也很短

当事务执行速度大于脏页刷盘速度时,Ckp age和Buf age会逐步增长,当达到async点的时候,强制进行脏页刷盘或者写Checkpoint,如果这样做还是赶不上事务执行的速度,则为了避免数据丢失,到达sync点的时候,会阻塞其它所有的事务,专门进行脏页刷盘或者写Checkpoint。

因此从理论上来说,只要事务执行速度大于脏页刷盘速度,最终都会触发日志保护机制,进而将事务阻塞,导致MySQL操作挂起。

由于写Checkpoint本身的操作相比写脏页要简单,耗费时间也要少得多,且Ckp sync点在Buf sync点之后,因此绝大部分的阻塞都是阻塞在了Buf sync点,这也是当事务阻塞的时候,IO很高的原因,因为这个时候在不断的刷脏页数据到磁盘。例如如下截图的日志显示了很多事务阻塞在了Buf sync点:

本文由职坐标整理并发布,了解更多内容,请关注职坐标MySQL数据库频道!

mysql 日志刷新到磁盘_MySQL数据库刷日志的方法相关推荐

  1. mysql进行mof提权_MySQL数据库Root权限MOF方法提权研究

    MySQL数据库Root权限MOF方法提权研究 MySQL Root权限MOF方法提权是来自国外Kingcope大牛发布的MySQL Scanner & MySQL Server for Wi ...

  2. linux mysql 实战_Linux平台MySQL多实例项目实施_MySQL数据库基础与项目实战06

    Linux平台MySQL多实例项目实施_MySQL数据库基础与项目实战06 视频教程学习地址 Oracle/MySQL数据库学习专用QQ群:336282998.189070296 学完风哥本课程能熟悉 ...

  3. mysql隔离级别加锁情况_MySQL数据库事务各隔离级别加锁情况--read committed amp;amp; MVCC...

    上节回顾 上篇记录了我对MySQL 事务 隔离级别read uncommitted的理解. 这篇记录我对 MySQL 事务隔离级别 read committed & MVCC 的理解. 前言 ...

  4. mysql中数据如何备份_mysql数据库如何进行备份和恢复

    一.确保mysql开启了binlog日志功能 在/etc/my.cnf文件里的[mysqld]区块添加: #这个是存储的位置为mysql配置文件的位置 log-bin=mysql-bin 然后重启my ...

  5. mysql黑窗口常用命令_mysql数据库常用命令

    1.MySQL常用命令 create database name; 创建数据库 use databasename; 选择数据库 drop database name 直接删除数据库,不提醒 show ...

  6. mysql配置读写分离无效_MySQL数据库的同步配置+MySql 读写分离

    MySQL数据库的同步. MySQL是开源的关系型数据库系统.主从同步复制(Replication)是从一台MySQL数据库服务器(主服务器master)复制数据到另一个服务器(从服务器slave)的 ...

  7. mysql慢查询日志分析工具比较_MySQL慢查询日志总结 日志分析工具mysqldumpslow

    慢查询日志概念 MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志 ...

  8. mysql 日志抓取变化_MySQL慢查询日志分析提取【转】

    原文:https://www.cnblogs.com/skymyyang/p/7239010.html 一:查询slow log的状态,如示例代码所示,则slow log已经开启. mysql> ...

  9. MySQL同步到hadoop工具_MySQL数据库实时同步数据到Hadoop分布式文件系统的工具Applier...

    通过Map/Reduce进行批处理递送到Apache Hadoop仍然是中枢环节.,但随着要从"超思维速度"分析方面获取竞争优势的压力递增,因此Hadoop( 分布式文件系统 )自 ...

最新文章

  1. 网站开发技巧参考大全
  2. java null 转空_java 对象属性为 null 值转为 空串
  3. python 压缩 解压
  4. Hadoop简介与分布式安装
  5. 项目中遇到的某些问题及解决办法(一)
  6. Kubernetes(k8s)底层网络原理刨析
  7. OSG仿真案例(10)——osg仿真录屏抓取图像,自定义修改路径,程序控制(而不是按键控制)...
  8. 吴恩达的21节Deeplearning.ai课程学习经验总结
  9. 口袋妖怪模拟器android,口袋妖怪叶绿模拟器手机版
  10. webpower中国区发布《2014年中国邮件营销行业数据报告》
  11. html面试信息登记表
  12. Flash绘画与动画宝典
  13. HDU CCPC网络选拔赛 6441 Find Integer(数学)
  14. netbackup基础知识
  15. MoviePy - 中文文档4-MoviePy实战案例-给MoviePy Logo做一个闪动的阴影效果
  16. 文件服务器之:NFS服务器
  17. R实战:【股票分析】用quantmod在股票的K线上添加标记
  18. Python 凯撒密码
  19. 让我摘下星星送给你_想摘下星星给你摘下月亮给你是什么歌
  20. 金蝶K3开发-改造单据录入之快速录单

热门文章

  1. 前端单页面应用分布式部署探索
  2. hdu 1240(三维bfs)
  3. 【C语言】如何茫茫人海中找出总分最高的学生
  4. 苹果系统测试硬盘软件怎么看,苹果电脑怎么检查或修好磁盘
  5. Unity仿微信QQ等聊天软件的UI效果
  6. 【HTML5学习小结(2)】
  7. HTML: css中的display属性
  8. Lazada(东南亚)珠宝配饰、手表市场如何?这些热销需求产品一定要知道!
  9. BeanCopier工具类
  10. steel studs