一:redo log(重做日志 是物理日志 InnoDB特有的日志)
数据库中很多表其实是放在磁盘的,只有一少部分使用的时候才调入内存。如果我们需要修改表的信息要怎样做呢?首先是在内存中修改表的信息吧,其次找到磁盘表对应的位置,在上面update表的信息吧。对磁盘操作时很慢的啊,那有啥办法可以解决这个问题呢?redo log出现了。
1.redo log是用来干啥的
redo log可以保存数据库执行的指令,并把在内存中的表的信息更新了,但是不去更新磁盘上表的信息。那啥时候去更新呢?等系统自己空闲的时候再自动进行磁盘读写。InnoDB的redo log是固定大小的,比如可以配置为一组4个文件,每个文件的大小是1GB,那么总共就可以记录4GB的操作。
2.redo log满了咋处理
redo log写满了,系统没法办法只能停下来去把信息更新到磁盘上。留出一些空间留继续保存新的命令。
3.Crash-safe
有了redo log,InnoDB就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crash-safe。
二:bindo log(归档日志 是逻辑日志)
MySQL自带的引擎是MyISAM,但是MyISAM没有crash-safe的能力,binlog日志只能用于归档。而InnoDB是另一个公司以插件形式引入MySQL的,既然只依靠binlog是没有crash-safe能力的,所以InnoDB使用另外一套日志系统——也就是redo log来实现crash-safe能力。binlog会记录所有的逻辑操作,并且是采用追加写的形式。主要用于数据库恢复到某一个时刻,当然这样的前提是有这段时间的binlog。
三:redo log和bindo log的对比
- redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。
- redo log是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1 ”。
- redo log是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写”是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
四:两阶段提交
1.定义
redo log的写入拆成了两个步骤:prepare和commit。对于要写入redolog的新行:
2.详述
先来回顾下经典的2PC协议,有两个角色:一个协调者(coordinator)和若干参与者(participant),协议执行可以分为如下几个阶段:
预处理阶段:严格来说,预处理阶段并不是2PC的一部分,在实际的分布式数据库中,这个阶段由协调者向若干参与者发送SQL请求或执行计划,包括获取行锁,生成redo数据等操作。
Prepare阶段:客户端向协调者发送事务提交请求,协调者开始执行两阶段提交,向所有的事务参与者发送prepare命令,参与者将redo数据持久化成功后,向协调者应带prepare成功。这里隐含的意思是,参与者一旦应答prepare成功,就保证后续一定能够成功执行commit命令(redolog持久化成功自然保证了后续能够成功commit)。
Commit阶段
执行Commit:协调者收到所有参与者应答prepare成功的消息后,执行commit,先在本地持久化事务状态,然后给所有的事务参与者发送commit命令。参与者收到commit命令后,释放事务过程中持有的锁和其他资源,将事务在本地提交(持久化一条commit日志),然后向协调者应答commit成功。协调者收到所有参与者应答commit成功的消息后,向客户端返回成功。
执行Abort:prepare阶段中如果有参与者返回prepare失败或者超时未应答,那么协调者将执行abort,同样先在本地持久化事务状态,然后给所有参与者发送abort命令。参与者收到abort命令后,释放锁和其他资源,将事务回滚(有必要的情况下还要持久化一条abort日志)。
3.为啥需要两阶段提交?
这是为了让两份日志之间的逻辑一致。
你是不是会感觉bindolog多余?
但是binlog还不能去掉。
一个原因是,redolog只有InnoDB有,别的引擎没有。
另一个原因是,redolog是循环写的,不持久保存,binlog的“归档”这个功能,redolog是不具备的。