综述
binlog二进制日志是server层的,主要是左主从复制,时间点恢复使用
redo log重做日志是InnoDB存储引擎层的,用来保证事务安全
undo log回滚日志保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC) ,也即非锁定读
一、redo log
重做日志
作用:确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。
内容:物理格式的日志,记录的是物理数据页面的修改的信息,其redo log是顺序写入redo log file的物理文件中去的。
二、bin log
归档日志(二进制日志)
作用:用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步。
用于数据库的基于时间点的还原。
内容:逻辑格式的日志,可以简单认为就是执行过的事务中的sql语句。
但又不完全是sql语句这么简单,而是包括了执行的sql语句(增删改)反向的信息,也就意味着delete对应着delete本身和其反向的insert;update对应着update执行前后的版本的信息;insert对应着delete和insert本身的信息。
binlog 有三种模式:Statement(基于 SQL 语句的复制)、Row(基于行的复制) 以及 Mixed(混合模式)
三、undo log
****回滚日志
作用:保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读
内容:逻辑格式的日志,在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,这一点是不同于redo log的。
[mysql日志:redo log、binlog、undo log 区别与作用]
www.cnblogs.com/wq-blogs/p/… blog.csdn.net/suifeng629/…
CrashSafe指MySQL服务器宕机重启后,能够保证:\
- 所有已经提交的事务的数据仍然存在。\
- 所有没有提交的事务的数据自动回滚。
前面的文章讲过,Innodb通过Redo Log和Undo Log可以保证以上两点。为了保证严格的CrashSafe,必须要在每个事务提交的时候,将Redo Log写入硬件存储。这样做会牺牲一些性能,但是可靠性最好。为了平衡两者,InnoDB提供了一个系统变量,用户可以根据应用的需求自行调整
Mysql面试题系列-什么是crash-safe能力?什么是两阶段提交?
前言
这是我的第一篇Mysql系列的文章,接下来我将以Mysql面试题为线索,写一系列Mysql相关的文章,欢迎关注和支持, 有需要的小伙伴可以先收藏再看哦~
正文
Innodb引擎具有crash-safe能力,这种crash-safe 能力,是通过引擎层的redo log 来实现的。
redo log
事务在提交写入磁盘前,会先写到redo log里面去。
为什么不直接写到Mysql中去?这是因为数据写到Mysql中去,需要找到磁盘的Mysql的对应的页,涉及磁盘的随机I/O访问,涉及磁盘随机I/O访问是非常消耗时间的一个过程,相比这个时间,先写入redo log,后面再找合适的时机刷盘,能大大提升效率。
另外,如果Mysql 进程异常重启了,系统会自动去检查redo log,将未写入到Mysql的数据从redo log恢复到Mysql中去。
redo log存储的是页的物理日志,即在这个页上做了什么改动。
redo log是固定大小的一组文件,采用“循环写“的方式,如下图,redo log可以设置为一组4个文件:
\
\
什么是循环写呢?事务提交时,会先写到redo log里面去,当写完一个事务时,write pos会往前移动,在redo log中的记录被更新到数据库中时,checkpoint 会往前移动。
write pos和 checkpoint 之间的记录,是可以被擦除的。
当write pos 和 checkpoint 重合时,write pos会回到最开头的文件,重新开始写。
其中checkpoint 表示已经刷新到磁盘上的日志序列号,即LSN。
另外,每个页上也会记录一个LSN,用于表示已经刷新的数据。
crash-safe
redo log的存在使得数据库具有crash-safe能力,即如果Mysql 进程异常重启了,系统会自动
去检查redo log,将未写入到Mysql的数据从redo log恢复到Mysql中去。
当数据库发生异常重启时,系统会自动定位到上次checkpoint的位置,同时,每个数据页中
也存在一个LSN,当redo log中的LSN大于数据页中的LSN时,说明重启前redo log中的数据
未完全写入数据页中,那么将从数据页中记录的LSN开始,从redo log中恢复数据。
比如redolog 的LSN 是 13000,数据库页的LSN是 10000,那么说明重启前有部分数据未完
全刷入到磁盘的数据页中,那么系统将会恢复redo log 中LSN从10000开始到13000的记录到
数据页中。\
当redo log中的LSN小于数据页中的LSN时,说明数据页已经被刷到该位置,所以不需要进行恢复。
两阶段提交
Mysql Server的大体架构
Mysql大体可以分为Server层和存储引擎层,其中binlog在Server层,redo log在存储引擎层。\
\
binlog简介
binlog是Mysql server层的日志,主要用于数据误删后进行数据恢复,另外,主从复制也需要依靠binlog。
过程
redolog 是Mysql InnoDB引擎层的日志,为了保证两份日志最终恢复到数据库的数据是一致的,采用两阶段提交的机制。
主要过程如下:\
1)执行器调用存储引擎接口,存储引擎将修改更新到内存中后,将修改操作写到redo log里面,此时redo log处于prepare状态;
2)存储引擎告知执行器执行完毕,执行器开始将操作写入到bin log中,写完后调用存储引擎的接口提交事务;
3)存储引擎将redo log的状态置为commit。
两阶段提交机制的必要性
binlog 存在于Mysql Server层中,主要用于数据恢复;当数据被误删时,可以通过上一次的全量备份数据加上某段时间的binlog将数据恢复到指定的某个时间点的数据。
redo log 存在于InnoDB 引擎中,InnoDB引擎是以插件形式引入Mysql的,redo log的引入主要是为了实现Mysql的crash-safe能力。
假设redo log和binlog分别提交,可能会造成用日志恢复出来的数据和原来数据不一致的情况。
1)假设先写redo log再写binlog,即redo log没有prepare阶段,写完直接置为commit状态,然后再写binlog。那么如果写完redo log后Mysql宕机了,重启后系统自动用redo log 恢复出来的数据就会比
binlog记录的数据多出一些数据,这就会造成磁盘上数据库数据页和binlog的不一致,下次需要用到
binlog恢复误删的数据时,就会发现恢复后的数据和原来的数据不一致。
2)假设先写binlog再写redolog。如果写完redo log后Mysql宕机了,那么binlog上的记录就会比磁盘上数据页的记录多出一些数据出来,下次用binlog恢复数据,就会发现恢复后的数据和原来的数据不一致。
由此可见,redo log和binlog的两阶段提交是非常必要的。