当前位置: 首页 > 编程日记 > 正文

MySQL Innodb日志机制深入分析

 

1.1. Log & Checkpoint

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

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

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

1.1.1. 写入机制

1.1.1.1. Log写入

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

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

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

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

1.1.1.2. Checkpoint写入

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

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

1.1.2. 管理机制

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

如上图所示,Innodb的一条事务日志共经历4个阶段:

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

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

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

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

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

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

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

l Oldest modified data log(LSN3):当前最旧的脏页数据对应的LSN,写Checkpoint的时候直接将此LSN写入到日志文件;

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

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

具体的样例如下(使用show innodb status /G命令查看,Oldest modified data log没有显示):

1.1.3. 保护机制

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

l 宕机导致日志丢失
Innodb有日志刷盘机制,可以通过innodb_flush_log_at_trx_commit参数进行控制;

l 日志覆盖导致日志丢失

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 age

LSN1- LSN4

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

Buf age

LSN1- 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点:

附注:Innodb的日志保护机制实现可以参考log0log.c文件的void log_check_margins(void)函数。

转载于:https://www.cnblogs.com/bluecoder/p/3737286.html

相关文章:

单元测试的重要性

一些错误的认识 在实际的单元测试过程中总会有一些错误的认识左右着我们,使之成为单元测试最大的障碍,在此将其一一分析如下: 它太浪费时间了,现在要赶进度,时间上根本不允许,或者随便做做应付领导。 我是一…

浅谈网络协议(四) IP的由来--DHCP与PXE

2019独角兽企业重金招聘Python工程师标准>>> 上一节说过,IP就是一台计算机的通讯地址,要和其他机器通讯,就需要一个通讯地址,就要给网卡配置这么一个地址。 配置 IP 那如何配置呢?可以使用 ifconfig&#x…

(C++)1026 程序运行时间

#include<cstdio> const int CLK_TCK100;int main(){ //1.读入c1,c2int c1,c2;scanf("%d%d",&c1,&c2); //2.定义常量CLK_TCK100 //难点&#xff1a;不足 1 秒的时间四舍五入到秒 --不用round()&#xff0c;避免浮点数运算 int dif c2-c1;if(dif%100&…

Spring中@Autowired注解、@Resource注解的区别

Spring不但支持自己定义的Autowired注解&#xff0c;还支持几个由JSR-250规范定义的注解&#xff0c;它们分别是Resource、PostConstruct以及PreDestroy。  Resource的作用相当于Autowired&#xff0c;只不过Autowired按byType自动注入&#xff0c;而Resource默认按 byName自…

(C++)1046 划拳

划拳是古老中国酒文化的一个有趣的组成部分。酒桌上两人划拳的方法为&#xff1a;每人口中喊出一个数字&#xff0c;同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和&#xff0c;谁就赢了&#xff0c;输家罚一杯酒。两人同赢或两人同输则继续下一轮&…

JAVA中重写equals()方法的同时要重写hashcode()方法

object对象中的 public boolean equals(Object obj)&#xff0c;对于任何非空引用值 x 和 y&#xff0c;当且仅当 x 和 y 引用同一个对象时&#xff0c;此方法才返回 true&#xff1b;注意&#xff1a;当此方法被重写时&#xff0c;通常有必要重写 hashCode 方法&#xff0c;以…

从0到1,苏宁API网关的演进之路

http://www.infoq.com/cn/articles/suning-11-11-api-gateway?utm_campaigninfoq_content&utm_sourceinfoq&utm_mediumfeed&utm_termglobal 2012年&#xff0c;在开放云融推动各产业全面发展的大背景下&#xff0c;苏宁API对外开放。基于苏宁各内部业务系统的资源…

HTML 注意事项

这行与下面图片的间距比较小asdf 代码如下: <table id"table1"cellspacing"0"cellpadding"0"width"100%"border"0"><tbody><tr><td>这行与下面图片的间距比较小</td></tr><tr>&l…

(C++)1008 数组元素循环右移问题

#include<cstdio> //注意&#xff1a;不允许使用另外数组,序列结尾不能有多余空格,不能直接认为right<n //1.读入数组长度&#xff0c;和右移位数&#xff0c;读入数组 //2.未必要对实际数组进行循环右移&#xff0c;只要输出结果表现出那样就可以 int main(){int n…

C# 文件操作(上传 下载 删除 文件列表...)

using System.IO; 1.文件上传 ---------- 如下要点&#xff1a; HTML部分&#xff1a; <form id"form1" runat"server" method"post" enctype"multipart/form-data"> <input id"FileUpLoad" type"file" …

5个常用Java代码混淆器 助你保护你的代码

【IT168 技术文档】 从事Java编程的人都知道&#xff0c;可以通过逆向工程反编译得到Java程序的源代码&#xff0c;这种反编译工具之一就是JAD。因此&#xff0c;为保护我们的劳动成果&#xff0c;尽可能给反编译人员制造障碍&#xff0c;我们可以使用Java Obfuscator(Java混淆…

9.8.6恢复系统数据库

系统数据库和用户数据库一样容易发生故障&#xff0c;所以确保它们得到足够的保护十分重 要。一般来说&#xff0c;恢复系统数据库时有两种选择。可以从备份还原&#xff0c;或者从头重建它们。我 强烈推荐备份还原方法&#xff0c;因为从头重建意味着有人量的工作要做。由于系…

(C++)1012 数字分类

#include<cstdio> //用switch...case语句来对读入的数字进行分类 //1.读入N //2.A2需要设置变号器 //3.A3,A4需要设置计数器 //注意&#xff1a;某一类数可能根本不存在 int main(){int n;scanf("%d",&n);int res[5]{};//初始化为0 int count[5]{};whil…

老调重弹:插件式框架开发的一个简单应用

VS 2008最近要做一个应用程序检测程序&#xff0c;就是要检测服务器上各应用程序的运行情况&#xff0c;由于各应用程序的差异&#xff0c;很难做一个统一的探测程序&#xff0c;于是决定对任意一个应用程序都采用独立的一条探测规则。为了开发、部署的方便&#xff0c;考虑使用…

mathjax测试

O(∩_∩)O哈哈~&#xff0c;新开通博客测试。 mathjax公式测试。以下是latex公式 $a^2b^2c^2$ <!--more--> 多输入一点东东。新浪娱乐讯 1月3日&#xff0c;网络红人奶茶妹妹章泽天清空微博&#xff0c;而其男友刘强东也删除了“小天是我见过最单纯善良的人…只求以后可以…

Docker镜像使用

当运行容器时&#xff0c;使用的镜像如果在本地中不存在&#xff0c;docker 就会自动从 docker 镜像仓库中下载&#xff0c;默认是从 Docker Hub 公共镜像源下载。 下面我们来学习&#xff1a; 1、管理和使用本地 Docker 主机镜像2、创建镜像列出镜像列表 我们可以使用 docker …

(C++)1018 锤子剪刀布

#include<cstdio>int Map(char c){//将字母映射到数字 if(cB){return 0;}else if(cC){return 1;}else{return 2;} } //对决函数&#xff0c;返回1表示甲胜&#xff0c;0表示平局&#xff0c;-1表示乙胜 int ko(int i1,int i2){if((i11)%3i2){//甲胜 return 1;}else if(i…

我的软考之路(九)——总结篇

经过两个月的备战&#xff0c;软考总算结束了。软考虽然结束了&#xff0c;但是还需要简单的总结一下得与失。我从时间安排&#xff0c;到讲课做真题简单的回顾一下软考的整个过程。 时间安排&#xff1a; 对于时间的安排&#xff0c;整个小组成员每个人都有自己的看法&#xf…

problem-solving-with-algorithms-and-data-structure-usingpython(使用python解决算法和数据结构) -- 基本数据结构(二)...

中缀、前缀和后缀表达式 1. 前缀表达式符号要求所有运算符在它们处理的两个操作数之前。 2. 后缀表达式要求其操作符在相应的操作数之后。 考虑表达式 A B * C &#xff0c; A B C * 是等价的后缀表达式。操作数 A&#xff0c;B 和 C 保持在它们的相对位置&#xff0c;只有操…

赢在中国(08-02-27)

在Google Calendar中设置了赢在中国的日程&#xff0c;结果没有发短信给我&#xff08;是不是可以起诉它呢&#xff1f;和Google打打官司&#xff0c;可是成名的好机会啊&#xff1a;&#xff09;&#xff09;后面一节还是看到了&#xff0c;印象比较深的是最后一位做教育的选手…

(C++)1041 考试座位号

//B1041 #include<cstdio> //直接将试机号作为下标 struct student{long long no;int sit; };int main(){int n1,n2;//总共参与考试的人数&#xff0c;来迟的人数 student stus[1010];scanf("%d",&n1);long long no;int sit,test;for(int i0;i<n1;i){s…

Premiere制作VCD视频几个关键设置

一&#xff0c;视频设置 1&#xff0c;编码设置&#xff1a;不要选cinepak codec by radius,这个编码速度非常慢,图象也不清晰,一般只在电脑多多媒体交互式演示文件中使用。很多朋友遇到的“速度慢”、“不清晰”&#xff0c;多半是这里设置不合适造成。 2&#xff0c;帧尺寸&a…

qt中定时器Timer的使用

转载于:https://www.cnblogs.com/zhouwenJS/p/3762341.html

python基础===拆分字符串,和拼接字符串

给定某字符&#xff0c;只需要保留其中的有效汉字或者字母&#xff0c;数字之类的。去掉特殊符号或者以某种格式进行拆分的时候&#xff0c;就可以采用re.split的方法。例如 RESTART: Shell >>> s Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.19…

(C++)1036 跟奥巴马一起编程

#include<cstdio> //10列 共5行 131 //11列 共6行 141 //n%20 1n/2-21 //n%2!0 1(n-1)/2-11 int main(){int col,mid;char c;scanf("%d %c",&col,&c);//第一行for(int i 0;i<col;i){printf("%c",c);} printf("\n");//中间行/…

使用LINQ进行多表操作(二)

1:M或者M:M关系的多表操作表结构如下直接写表达式 //正常选取var user context.Users.Where(p >p.UserID 10300).Select(p >new{p, p.UserTags})//带条件选取var user context.Users.Where(p >p.UserID 10300).Select(p >new{p, UserTags p.UserTags.Where(o >…

分布式文件系统

PDF格式PPT下载&#xff1a;分布式文件系统 转载于:https://www.cnblogs.com/mfrbuaa/p/3765902.html

Codis 3.2 集群搭建与测试

这里首选分为四个步骤进行一、软件下载codis 3.2.2 https://github.com/CodisLabs/codis/releasescodis-src https://codeload.github.com/CodisLabs/codis/zip/release3.2zeepkeeper 3.5.4 http://ftp.twaren.net/Unix/Web/apache/zookeeper/zookeeper-3.5.4-beta/zookeeper…

(C++)CSP202009-1 称检测点查询

#include<cstdio> #include<cmath> #define MAXSIZE 200//定义结构体 struct sqList{int r[MAXSIZE1][2];int length0; }; //交换 void swap(sqList* sqz,int index1,int index2){int temp sqz->r[index1][1];sqz->r[index1][1]sqz->r[index2][1];sqz-&…

sysbench的安装和做性能测试

sysbench的安装和做性能测试 http://imysql.cn/node/312 sysbench是一个模块化的、跨平台、多线程基准测试工具&#xff0c;主要用于评估测试各种不同系统参数下的数据库负载情况。 关于这个项目的详细介绍请看&#xff1a;http://sysbench.sourceforge.net。 它主要包括以下几…