和 bin log 不同,redo log 不是二进制日志。它是物理日志,记录数据页的物理修改。用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。
redo log 是 innodb 为了支持崩溃恢复而出现的,只记录 innodb 存储引擎中表的修改。bin log 和 inndb 总的来说有如下不同:
如名所示,redo log 是重做日志,提供前滚操作。让 inndb 具有崩溃恢复能力从而支持事务,保证数据的持久性与完整性。
redo log 由两部分组成:1. 处于内存中的日志缓存(redo log buffer); 2. 位于磁盘中的重做日志文件(redo log file)。如下图所示:
redo log 以块为单位进行存储的,每个块占512字节,称之为 redo log block。不管是存于缓存中 redo log 还是位于磁盘文件中的 redo log 都是以512字节为一块存储的。
每个redo log block由3部分组成:日志块头、日志块尾和日志主体。其中日志块头占用12字节,日志块尾占用8字节,所以每个 redo log block 的日志主体部分只有512-12-8=492字节。
日志块头包含4部分:
log group 表示的是 redo log group,一个组内由多个大小完全相同的 redo log file 组成。
组是一个逻辑的概念,并没有真正的文件来表示这是一个组,但是可以通过变量 innodb_log_group_home_dir 来定义组的目录,redo log file 都放在这个目录下,默认是在datadir下。
组内 redo log file 的数量由变量 innodb_log_files_group 决定,默认值为2,即两个 redo log file。
-rw-r----- 1 mysql mysql 100663296 Jun 26 09:45 ib_logfile0
-rw-r----- 1 mysql mysql 100663296 Jun 26 09:45 ib_logfile1
在 innodb_log_group_home_dir 配置的路径下可以看到两个 ib_logfile 开头的文件,它们就是 log group 中的 redo log file。大小完全一致且等于变量 innodb_log_file_size 定义的值。
innodb 将 log buffer 中的 redo log block 刷到 log file 中时,会以追加写入的方式循环轮询写入。
即先在第一个log file(即ib_logfile0)的尾部追加写,直到满了之后向第二个log file(即ib_logfile1)写。当第二个log file满了会清空一部分第一个log file继续写入。
一个完整的 redo log block 如下图所示:
众所周知 Innodb 是以页为单位存储数据,redo log 也是一样的(buffer 和 磁盘中均是如此)。 innodb 默认页大小是 16 KB , 所以是一个页是可以存储很多 log block(图 5-2 呈现 log block 的结构)。
每个 log block 中有 492 字节是可以用来存储数据页变化信息的 body 部分,其可分为 4 部分:
尽管大致上结构是一致的,但是如 insert 和 delete 还是有着些差异:
我们都知道 redo log 是先写到 redo log buffer 中,由参数 innodb_log_buffer_size 控制 redo log buffer 大小,默认 16 MB。这个值其实已经够大了,毕竟是记录页的物理修改信息。
未刷到磁盘的日志称为脏日志(dirty log),满足一些时机就会触发持久化到磁盘中。其中以下几种时机会触发写入到磁盘中:
checkpoint 是一个将 buffer pool 中脏数据页和脏日志页刷到磁盘的动作,因为 buffer pool 的容量是有限的,不可能将所有 redo log 存放在缓冲池中。
分为两种类型:
可以用下图来描述 redo log 和 checkpoint 动作是如何循环写的。假如启用了 4个 redo log,从 0 号文件向 3 号文件方向写,其中:
write pos 表示 redo log 当前记录的 LSN (逻辑序列号) 位置,一边写一遍后移。
check point 表示数据页更改记录刷盘后对应 redo log 所处的 LSN (逻辑序列号) 位置,也是往后推移并且循环的。
LSN (log sequence number) 日志的逻辑序列号,占用 8 个字节,其值会随日志的不断写入而增加。
用于实现 crash-save ,如 innodb 重启时会检查磁盘中数据页的 LSN,如小于日志中 check point (见图 5-5)的 LSN 。则将会重 check point 点开始重放恢复数据。
LSN 存在于数据页(包括 buffer pool 和磁盘中)、redo log(包括 buffer pool 和磁盘中)。
使用 show engine innodb status 查看当前各种 LSN 情况:
mysql> show engine INNODB STATUS;
...
# 省略一些与本节不相关的的信息
LOG
---
Log sequence number 59816
Log flushed up to 59816
Pages flushed up to 56169
Last checkpoint at 53898
0 pending log flushes, 0 pending chkp writes
17 log i/o's done, 0.40 log i/o's/second
从上面信息可直观的到有 4 种 LSN:
为了便于直观了解上述请在在一个事务过程中的情况,下面将定义几种 LSN 并体现在一个时序图中情况。
分析上图:
事务开始前,假设此时日志页和数据页都是全部刷到磁盘中,此时上面 4 种 LSN 的值都是相同的并等于 9 。
注意一个知识点: log flushed up to 和 pages flushed up to 的大小无法确定,所以 redo log 和数据页刷盘快慢是不确定的。但是 checkpoint 机制会控制 数据页刷盘速度慢于 redo log ,当数据页刷盘速度超过 redo log 时,将会暂时停止数据页刷盘,等待 redo log 刷盘进度超过数据刷盘。
log sequence number(10) > log flushed up to(9) = pages flushed up to(9) = last checkpoint at(9)
log sequence number(11) = log flushed up to(11) > pages flushed up to(10) = last checkpoint at(10)
log sequence number > log flushed up to # 在此期间 redo log 在 buffer 中 LSN 是大于磁盘中的。
pages flushed up to > last checkpoint at # 在此期间 数据页的 LSN 是大于 checkpoint LSN (还停留在上一次的)。
log sequence number(13) = log flushed up to(13) > pages flushed up to(12) = last checkpoint at(12)
需要知道的是:innodb 在每次启动时,不管上次关闭是正常还是异常的,都会进行尝试恢复操作。
innodb 启动时,磁盘中 checkpoint 代表已经完整刷到磁盘中数据页的 LSN,所以恢复时仅需从 checkpoint 开始的部分。
如:上次的 checkpoint LSN 为 100,且事务是已经提交状态(没有提交就没有必要恢复,不过也要看位于两阶段提交的那个时段)。此时发生宕机,在启动时候数据库会检查数据页中的 LSN,若小于 redo log 中的 LSN,则会从 checkpoint 进行重放 redo log 进行恢复。
如:checkpoint 时发生宕机且数据页刷盘进度大于 redo log 刷盘进度,此时数据页中 LSN 必然是大于 redo log 中 LSN。此种情况在恢复时候判断超过 redo log LSN 的部分不会进行重做(没有必要重放)。
帧同步基础:这里RTS的网络同步:这里状态同步和帧同步的比较:这里
话说,在前面两篇文章中,我们学习了BitmapShader、Path的基本使用,那么这一篇文章,咱们接着来学习一下PathMeasure的用法。什么,你没听说过PathMeasure?那你就要OUT咯~项目效果图废话不多说,在开始讲解之前,先看下最终实现的效果。效果一:仿支付宝支付成功效果效果二:这两个项目都是使用P...
最近在做《算法竞赛入门经典》时
C语言易混淆关键词详解-const, static, extern, typedef, 声明ConstConst关键词并不能把一个变量变成一个常量, 在符号前加上const表示这个符号不能被赋值, 即他的值对这个符号来说是只读的, 但并不代表这个值不能用其他方法去改变. 通过下面的例子就能比较好理解,int i = 5;const int *a = &i;*a = 8;_extern typedef
d3.js学习笔记-02目录d3.js学习笔记-021. 比例尺1.1 定量比例尺(连续)1.1 线性比例尺1.2 指数、对数比例尺1.3 量子、分位比例尺References1. 比例尺1.1 定量比例尺(连续)每个比例尺都需要指定定义域(domain)和值域(range)1.1 线性比例尺d3.scale.linear():创建线性比例尺linear(x):输入一个在定义域内的值x,返回值域内对应的值。linear.invert(y):输入一个在值域内的值,返回定义域内对应的值。l_d3.scale.quantize().domain
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达最近在微信公众号 AIZOO 里看到轻量级人脸检测算法大盘点的文章,里面还提供了Github源码地址,我就把它们逐个下..._人脸识别开源算法
(请保留-> 作者: 罗冰 https://blog.csdn.net/luobing4365)Gitee上Markdown文件的编辑和使用1 标题标题A标题B一级标题二级标题三级标题四级标题五级标题六级标题2 字体3 列表与表格4 分割线与引用5 图片建立Gitee仓库的时候,它会提供一个Readme.md的文件,可以对其进行编辑修改,作为仓库的使用说明。如图1所示,是我为本篇建立的Gitee仓库。图1 建立Gitee仓库最近在对Gitee仓库上的文档进行整理,觉得自己的Readme_gitee markdown 文件编辑器中
安装试用国产系统 ——中标麒麟V7.0首先自然是下载个系统的安装镜像了。下载完镜像,创建一个新的虚拟机 配置好镜像文件,开始安装了 这个倒是和一般的Linux系统没什么区别,反正中标麒麟也是基于Linux 的。 加载十几秒,下面开始正式安装: 使用默认的分区就好了。 安装完成,重启一下。 然后是对系统进行简单的配置,结果忘截图了。。。。登陆进去。 中标麒麟系统的默认桌面:是不..._龙芯软件下载
字典树(trie树),是一种前缀树,可以在O(m)的时间复杂度匹配目标字符串(m为目标字符串的长度),字典树广泛应用在NLP领域作为词典,具体应用有:分词、词频统计、字符串查询、字符串排序等。虽然字典树有较低的时间复杂度,但当词典较大时(如中文分词词典),字典树占用的空间非常大,常常难以满足工业应用的需求,因此需要在保持字典树优异的时间复杂度的前提下,尽可能的优化字典树的空间。本文由浅入深,讲解经典字典树、链表字典树、Hash表字典树、双数组字典树、单数组字典树5种字典树实现及各种实现的优缺点。经典字典_字典树的实现方式
在 HTML 中,表单元素如 , 和 表单元素通常保持自己的状态,并根据用户输入进行更新。而在 React 中,可变状态一般保存在组件的 state(状态) 属性中,并且只能通过 setState() 更新 我们可以通过使 React 的 state 成为 “单一数据源原则” 来结合这两个形式。然后渲染表单的 React 组件也可以控制在用户输入之后的行为。这种形式,其值由 React 控制的..._react textarea
Java爬虫之爬取多篇含有关键词的文章标题和内容实现的功能需要用到的jar包需要对html一些标签有一定的了解代码设计思想源代码实现的功能该代码针对维科网写的爬虫,具体如果想写其它的可以照着这篇模仿来写!输入想要搜索的关键字和输入关键字后的前几页页数(即输入关键字后跳转的网页的页数,如下图)将包含关键字的文章标题和内容提取出来保存在一个txt文件里面(如下图,输入关键词为智能,前2页)需要用到的jar包获取文章信息需要的包:Jsoup;需要对html一些标签有一定的了解可以到w3cs_java 根据关键词查询md文件的标题
排查线上问题常用的几个Linux命令top相当于Windows任务管理器可以看到,输出结果分两部分,前5行是总览,下面是具体的进程资源占用情况。下面逐行看一下第1行top - 18:14:58 up 112 days, 1:35, 1 user, load average: 0.00, 0.10, 0.11依次表示:当前时间、系统已经运行的时间、当前登录的用户数、系统在过去的1分钟,5分钟,15分..._查看进程连接数