基础编程学习快乐每一天
首页
留言
Siddim.com
当前位置:
首页
>
编程知识库
>
后端开发知识
>
谈谈MySQL中的重做日志,回滚日志,以及二进制日志的区别及各自作用
谈谈MySQL中的重做日志,回滚日志,以及二进制日志的区别及各自作用
阅读
1
2020-07-21
MySQL
中有六种日志文件,分别是:重做日志(
redo
log
)、回滚日志(
undo
log
)、二进制日志(
binlog
)、错误日志(
errorlog
)、慢查询日志(
slow
query
log
)、一般查询日志(
general
log
),中继日志(
relay
log
)。
其中重做日志和回滚日志与事务操作息息相关,二进制日志也与事务操作有一定的关系,这三种日志,对理解
MySQL
中的事务操作有着重要的意义。
这里简单总结一下这三者具有一定相关性的日志。
重做日志(redo log)
作用:
确保事务的持久性。
防止在发生故障的时间点,尚有脏页未写入磁盘,在重启
mysql
服务的时候,根据
redo
log
进行重做,从而达到事务的持久性这一特性。
内容:
物理格式的日志,记录的是物理数据页面的修改的信息,其redo log是顺序写入redo log file的物理文件中去的。
什么时候产生:
事务开始之后就产生redo log,redo log的落盘并不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入redo log文件中。
什么时候释放:
当对应事务的脏页写入到磁盘之后,redo log的使命也就完成了,重做日志占用的空间就可以重用(被覆盖)。
对应的物理文件:
默认情况下,对应的物理文件位于数据库的
data
目录下的
ib
_
logfile1
&
amp
;
ib
_
logfile2
innodb
_
log
_
group
_
home
_
dir
指定日志文件组所在的路径,默认./ ,表示在数据库的数据目录下。
innodb
_
log
_
files
_
in
_
group
指定重做日志文件组中文件的数量,默认
2
关于文件的大小和数量,由一下两个参数配置
innodb
_
log
_
file
_
size
重做日志文件的大小。
innodb
_
mirrored
_
log
_
groups
指定了日志镜像文件组的数量,默认
1
其他:
很重要一点,
redo
log
是什么时候写盘的?前面说了是在事物开始之后逐步写盘的。
之所以说重做日志是在事务开始之后逐步写入重做日志文件,而不一定是事务提交才写入重做日志缓存,原因就是,重做日志有一个缓存区
Innodb
_
log
_
buffer
,
Innodb
_
log
_
buffer
的默认大小为
8M
(这里设置的
16M
),
Innodb
存储引擎先将重做日志写入
innodb
_
log
_
buffer
中。
然后会通过以下三种方式将
innodb
日志缓冲区的日志刷新到磁盘
Master
Thread
每秒一次执行刷新
Innodb
_
log
_
buffer
到重做日志文件。
每个事务提交时会将重做日志刷新到重做日志文件。
当重做日志缓存可用空间 少于一半时,重做日志缓存被刷新到重做日志文件
由此可以看出,重做日志通过不止一种方式写入到磁盘,尤其是对于第一种方式,
Innodb
_
log
_
buffer
到重做日志文件是
Master
Thread
线程的定时任务。 因此重做日志的写盘,并不一定是随着事务的提交才写入重做日志文件的,而是随着事务的开始,逐步开始的。
更多面试题,欢迎
另外引用《
MySQL
技术内幕
Innodb
存储引擎》(
page37
)上的原话:
即使某个事务还没有提交,
Innodb
存储引擎仍然每秒会将重做日志缓存刷新到重做日志文件。 这一点是必须要知道的,因为这可以很好地解释再大的事务的提交(
commit
)的时间也是很短暂的。
回滚日志(undo log)
作用:
保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读
内容:
逻辑格式的日志,在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,这一点是不同于redo log的。
什么时候产生:
事务开始之前,将当前是的版本生成undo log,undo 也会产生 redo 来保证undo log的可靠性
什么时候释放:
当事务提交之后,undo log并不能立马被删除,而是放入待清理的链表,由purge线程判断是否由其他事务在使用undo段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间。
对应的物理文件:
MySQL5
.
6
之前,
undo
表空间位于共享表空间的回滚段中,共享表空间的默认的名称是
ibdata
,位于数据文件目录中。
MySQL5
.
6
之后,
undo
表空间可以配置成独立的文件,但是提前需要在配置文件中配置,完成数据库初始化后生效且不可改变
undo
log
文件的个数,如果初始化数据库之前没有进行相关配置,那么就无法配置成独立的表空间了。
更多面试题,欢迎
关于
MySQL5
.
7
之后的独立
undo
表空间配置参数如下
innodb
_
undo
_
directory
= /
data
/
undospace
/ --
undo
独立表空间的存放目录
innodb
_
undo
_
logs
=
128
--回滚段为
128KB
innodb
_
undo
_
tablespaces
=
4
--指定有
4
个
undo
log
文件
如果
undo
使用的共享表空间,这个共享表空间中又不仅仅是存储了
undo
的信息,共享表空间的默认为与
MySQL
的数据目录下面,其属性由参数
innodb
_
data
_
file
_
path
配置。
其他:
undo
是在事务开始之前保存的被修改数据的一个版本,产生
undo
日志的时候,同样会伴随类似于保护事务持久化机制的
redolog
的产生。
默认情况下
undo
文件是保持在共享表空间的,也即
ibdatafile
文件中,当数据库中发生一些大的事务性操作的时候,要生成大量的
undo
信息,全部保存在共享表空间中的。
因此共享表空间可能会变的很大,默认情况下,也就是
undo
日志使用共享表空间的时候,被“撑大”的共享表空间是不会也不能自动收缩的。
因此,
mysql5
.
7
之后的“独立
undo
表空间”的配置就显得很有必要了。
二进制日志(binlog):
作用:
用于复制,在主从复制中,从库利用主库上的
binlog
进行重播,实现主从同步。
用于数据库的基于时间点的还原。
内容:
逻辑格式的日志,可以简单认为就是执行过的事务中的
sql
语句。
但又不完全是
sql
语句这么简单,而是包括了执行的
sql
语句(增删改)反向的信息,
也就意味着
delete
对应着
delete
本身和其反向的
insert
;
update
对应着
update
执行前后的版本的信息;
insert
对应着
delete
和
insert
本身的信息。
在使用
mysqlbinlog
解析
binlog
之后一些都会真相大白。
因此可以基于
binlog
做到类似于
oracle
的闪回功能,其实都是依赖于
binlog
中的日志记录。
什么时候产生:
事务提交的时候,一次性将事务中的
sql
语句(一个事物可能对应多个
sql
语句)按照一定的格式记录到
binlog
中。
这里与
redo
log
很明显的差异就是
redo
log
并不一定是在事务提交的时候刷新到磁盘,
redo
log
是在事务开始之后就开始逐步写入磁盘。
因此对于事务的提交,即便是较大的事务,提交(
commit
)都是很快的,但是在开启了
bin
_
log
的情况下,对于较大事务的提交,可能会变得比较慢一些。
这是因为
binlog
是在事务提交的时候一次性写入的造成的,这些可以通过测试验证。
什么时候释放:
binlog的默认是保持时间由参数expire_logs_days配置,也就是说对于非活动的日志文件,在生成时间超过expire_logs_days配置的天数之后,会被自动删除。
对应的物理文件:
配置文件的路径为
log
_
bin
_
basename
,
binlog
日志文件按照指定大小,当日志文件达到指定的最大的大小之后,进行滚动更新,生成新的日志文件。
对于每个
binlog
日志文件,通过一个统一的
index
文件来组织。
其他:
二进制日志的作用之一是还原数据库的,这与
redo
log
很类似,很多人混淆过,但是两者有本质的不同
作用不同:
redo
log
是保证事务的持久性的,是事务层面的,
binlog
作为还原的功能,是数据库层面的(当然也可以精确到事务层面的),虽然都有还原的意思,但是其保护数据的层次是不一样的。
内容不同:
redo
log
是物理日志,是数据页面的修改之后的物理记录,
binlog
是逻辑日志,可以简单认为记录的就是
sql
语句
另外,两者日志产生的时间,可以释放的时间,在可释放的情况下清理机制,都是完全不同的。
恢复数据时候的效率,基于物理日志的
redo
log
恢复数据的效率要高于语句逻辑日志的
binlog
关于事务提交时,
redo
log
和
binlog
的写入顺序,为了保证主从复制时候的主从一致(当然也包括使用
binlog
进行基于时间点还原的情况),是要严格一致的,
MySQL
通过两阶段提交过程来完成事务的一致性的,也即
redo
log
和
binlog
的一致性的,理论上是先写
redo
log
,再写
binlog
,两个日志都提交成功(刷入磁盘),事务才算真正的完成。
总结:
MySQL
中,对于以上三种日志,每一种细化起来都可以够写一个章节的,这里粗略地总结了一下三种日志的一些特点和作用,以帮助理解
MySQL
中的事物以及事物背后的原理。
参考:《
MySQL
技术内幕
Innodb
存储引擎》
作者:
MSSQL123
cnblogs
.
com
/
wy123
/
p
/
8365234
.
html
? ~
以上数据来源于网络,如有侵权,请联系删除。
上一篇:
面试官:你知道 Redis 内部是怎么实现它的字符串的么?
下一篇:
你能谈谈Java中 synchronized 对象锁和类锁的区别
评论
(0)
提交
类别
基础编程学习
HTML
PHP
Python
编程知识库
后端开发知识
热门文章
Java并发中的同步容器与并发容器,你了解多少?
Innodb中的事务隔离级别和锁的关系,难倒一半面试者!
SpringBoot + minio实现分片上传、秒传、续传
面试官:你知道消息队列如何保证数据不丢失吗?
JAVA知识 Java8新特性
面试官:谈谈为什么要限流,有哪些限流方案?
说说动态代理与静态代理区别
面试官:思考Tomcat 类加载器为什么要违背双亲委派模型?
boot-admin 基于SpringBoot的后台权限管理系统,可作为脚手架,用于快速搭建项目
SpringBoot+Vue+App+硬件实现智能家居系统项目