mysql redolog binlog 之二阶段提交

一:什么是redolog和binglog?

redo logBinglog
日志类型物理日志
物理日志即数据页中的真实二级制数据,恢复速度快
逻辑日志
即sql语句,因需要逐条执行,恢复速度慢
存储格式innodb存储引擎数据的单位是页,redo log也是基于页进行存储,一个默认16K大小的页中存了很多512Byte的log block,log block的存储格式如下
[log block header 12Byte,log block body 492 Bytes,log block tailer 8 Bytes]
statement:SQL语句的形式
row:记录相关行的每一列的值(官方推荐)
用途重做数据页数据复制
所处层级innodb存储引擎中存储引擎的上层,因此不管用什么存储引擎,都可以开启binlog

二:redolog和binlog可以相互替代或者只保留其一吗?

1. 可以使用binlog替代redolog进行数据恢复吗?

不可以

innodb利用wal技术进行数据恢复,write ahead logging技术依赖于物理日志进行数据恢复,binlog不是物理日志是逻辑日志,因此无法使用;
那么,为什么write ahead logging技术不可以使用逻辑日志进行数据恢复呢?这个问题可以考虑一下自增锁的场景,当自增锁的模式设置为innodb_autoinc_lock_mode = 2时,mysql会锁住分配自增值的代码逻辑,不去进行自增值的预分配,由此带来的问题就是,高并发场景下多个事务中的insert(单条insert语句包含多个待插入值)逻辑会造成自增ID不固定的问题,由此带来的结果就是,利用binlog中的逻辑日志进行主从复制时,从库中的ID和主库中的ID不一致。因此,在特定场景下,逻辑日志相对于物理日志,显得不是那么可靠。

2. 可以只使用redolog而不使用binlog吗?

不可以

redolog是循环写,写到末尾要回到开头继续写,这样的日志无法保留历史记录,无法进行数据复制。
个人理解redolog其实是物理数据的一个缓存,理论上可以不需要redolog,插入的数据落盘后再返回插入成功,但是数据落盘的过程比较耗时,需要更新各种索引(B+树),因此现在数据落入redolog即返回成功,加快了返回速度。

三:为什么redolog和binlog要进行二阶段提交?

首先区分一个概念,commit①步骤是属于begin…commit②语句中的一个步骤,且是最后一个步骤,两个commit是包含的关系。

如果redo log持久化并进行了提交,而binlog未持久化数据库就crash了,则从库从binlog拉取数据会少于主库,造成不一致。因此需要内部事务来保证两种日志的一致性。

四:二阶段提交步骤

在这里插入图片描述
prepare:redolog写入log buffer,并fsync持久化到磁盘,在redolog事务中记录2PC的XID,在redolog事务打上prepare标识
commit:binlog写入log buffer,并fsync持久化到磁盘,在binlog事务中记录2PC的XID,同时在redolog事务打上commit标识
其中,prepare和commit阶段所提到的“事务”,都是指内部XA事务,即2PC

五、redolog和binlog二阶段提交与redolog和binlog的顺序提交是否真的有区别?

如果redolog和binlog顺序提交,则具体步骤会如下:

  1. redolog刷入cache并fsync刷盘,并打上commit标识

  2. binlog刷入cache并fsync刷盘

类比begin…commit和begin…rollback,commit和rollback这两个操作是只能二选一,且一旦commit则不能再rollback。同样,redolog中的事务一旦打上commit标识,是无法回退的,否则有可能覆盖其他事务的更新(例如A事务对某一行进行了插入并打上commit标识,而B事务紧接着对该行进行了修改,最后A事务突然回滚B事务,则B事务的操作被强制覆盖,这是不妥的)。如果redolog进行了commit,而此时数据库crash导致binlog刷盘失败,redolog无法回滚,会造成redolog和binlog不一致。

但是通过事务可以同时提交redolog和binlog,两者落盘之后都会记录2PC事务的XID(redolog和binlog中事务落盘的标识),若中途数据库crash,通过XID关联两者并在恢复时决定commit和rollback与否,详细步骤见下一段“恢复步骤”。

六:恢复步骤?

redolog中的事务如果经历了二阶段提交中的prepare阶段,则会打上prepare标识,如果经历commit阶段,则会打上commit标识(此时redolog和binlog均已落盘)。

Step1. 按顺序扫描redolog,如果redolog中的事务既有prepare标识,又有commit标识,就直接提交(复制redolog disk中的数据页到磁盘数据页)

Step2 .如果redolog事务只有prepare标识,没有commit标识,则说明当前事务在commit阶段crash了,binlog中当前事务是否完整未可知,此时拿着redolog中当前事务的XID(redolog和binlog中事务落盘的标识),去查看binlog中是否存在此XID

​ a. 如果binlog中有当前事务的XID,则提交事务(复制redolog disk中的数据页到磁盘数据页)

​ b. 如果binlog中没有当前事务的XID,则回滚事务(使用undolog来删除redolog中的对应事务)

可以将mysql redolog和binlog二阶段提交和广义上的二阶段提交进行对比,广义上的二阶段提交,若某个参与者超时未收到协调者的ack通知,则会进行回滚,回滚逻辑需要开发者在各个参与者中进行记录。mysql二阶段提交是通过xid进行恢复。

参考:
http://blog.itpub.net/28218939/viewspace-1975809/
https://www.cnblogs.com/f-ck-need-u/p/9010872.html#auto_id_16
https://www.cnblogs.com/f-ck-need-u/p/9001061.html#auto_id_14
https://www.infoq.cn/article/M6g1yjZqK6HiTIl_9bex
https://www.cnblogs.com/wupeixuan/p/11734501.html
https://segmentfault.com/a/1190000014810628
https://www.cnblogs.com/stevenczp/p/6265686.html
https://www.cnblogs.com/clouddbdever/p/5627409.html
https://juejin.im/post/5e5c6620f265da5741120978#heading-4

  • 12
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
MySQLRedo LogBinlog和Undo Log是三种不同的日志类型,用于支持数据库事务的持久性、复制和回滚操作。 1. Redo Log(重做日志): Redo LogMySQL引擎内部使用的一种日志,记录了所有已提交的修改操作,以保证数据库在发生崩溃等异常情况下能够进行恢复。当数据库发生崩溃时,可以通过Redo Log来重放这些修改操作,使数据库恢复到崩溃前的状态。Redo Log是在InnoDB存储引擎实现的,通常以磁盘文件形式存在,可被视为一种类似于事务日志的机制。 2. Binlog(二进制日志): BinlogMySQL数据库服务器层产生的一种日志,用于记录数据库所有的修改操作,包括数据修改和数据定义语句(DDL)。与Redo Log不同,Binlog记录的是逻辑操作而不是物理操作,以提供对数据的逻辑复制和恢复能力。Binlog通常以二进制文件的形式存在,并且可以被用于主从复制和数据恢复等任务。 3. Undo Log(回滚日志): Undo Log是用于支持事务回滚操作的一种日志。当一个事务执行修改操作时,旧值会被记录在Undo Log,以便于回滚操作时能够恢复到之前的状态。Undo Log通常与事务的隔离级别和并发控制有关,主要用于MVCC(多版本并发控制)的实现。 这三种日志在MySQL扮演了不同角色,分别用于保证数据的持久性、支持复制和提供事务回滚功能。在数据库的正常运行和异常恢复起到至关重要的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值