MYSQL三大日志binlog、redoLog、undoLog

binlog

1.概念

binlog用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。binlog是mysql的逻辑日志,并且由Server层进行记录,使用任何存储引擎的mysql数据库都会记录binlog日志。binlog日志有三种格式,分别为STATMENT、ROW和MIXED。

2.binlog使用场景

在实际应用中,binlog的主要使用场景有两个,分别是主从复制和数据恢复。
1)、主从复制:在Master端开启binlog,然后将binlog发送到各个Slave端,Slave端重放binlog从而达到主从数据一致。
2)、 数据恢复:通过使用mysqlbinlog工具来恢复数据。

3.binlog 写入策略

1、sync_binlog=0 的时候,表示每次提交事务binlog不会马上写入到磁盘,而是先写到page cache,相对于磁盘写入来说写page cache要快得多,不过在Mysql 崩溃的时候会有丢失日志的风险
2、sync_binlog=1 的时候,表示每次提交事务都会执行 fsync 写入到磁盘
3、sync_binlog的值大于1 的时候,表示每次提交事务都 先写到page cach,只有等到积累了N个事务之后才fsync 写入到磁盘,同样在此设置下Mysql 崩溃的时候会有丢失N个事务日志的风险。

很显然三种模式下,sync_binlog=1 是强一致的选择,选择0或者N的情况下在极端情况下就会有丢失日志的风险,具体选择什么模式还是得看系统对于一致性的要求。

4.案例

以修改数据为例,binlog 是以表为记录主体,在ROW模式下,binlog保存的表的每行变更记录。
比如update tb_user set age =18 where name =‘赵白’ ,如果这条语句修改了三条记录的话,那么binlog记录就是

UPDATE `db_test`.`tb_user` WHERE @1=5 @2='赵白' @3=91 @4='1543571201' SET  @1=5 @2='赵白' @3=18 @4='1543571201'
 UPDATE `db_test`.`tb_user` WHERE @1=6 @2='赵白' @3=91 @4='1543571201' SET  @1=5 @2='赵白' @3=18 @4='1543571201'
 UPDATE `db_test`.`tb_user` WHERE @1=7 @2='赵白' @3=91 @4='1543571201' SET  @1=5 @2='赵白' @3=18 @4='1543571201'

redo log

1.概念

redo log记录的是操作数据变更的物理日志,听起来好像和binlog有类似的地方,有时候我都会想有了binlog为什么还要redo log,当然从其它地方可以找到很多的理由,但是我认为最核心的一点就是redo log记录的数据变更粒度和binlog的数据变更粒度是不一样的,也正因为这个binlog是没有进行崩溃恢复事务数据的能力的。

2.redo log作用

redo log 能保证对于已经COMMIT的事务产生的数据变更,即使是系统宕机崩溃也可以通过它来进行数据重做,达到数据的一致性,这也就是事务持久性的特征,一旦事务成功提交后,只要修改的数据都会进行持久化,不会因为异常、宕机而造成数据错误或丢失,所以解决异常、宕机而可能造成数据错误或丢是redo log的核心职责。

3.案例

比如update tb_user set age =18 where name =‘赵白’ ,如果这条语句修改了三条记录的话,那么binlog记录就是

 把表空间10、页号5、偏移量为10处的值更新为18。
 把表空间11、页号1、偏移量为2处的值更新为18。
 把表空间12、页号2、偏移量为9处的值更新为18。

4.redo log写入策略

MYSQL三大日志binlog、redoLog、undoLog_第1张图片

undo log

1.概念

数据库事务四大特性中有一个是原子性,具体来说就是 原子性是指对数据库的一系列操作,要么全部成功,要么全部失败,不可能出现部分成功的情况。实际上,原子性底层就是通过undo log实现的。undo log主要记录了数据的逻辑变化,比如一条INSERT语句,对应一条DELETE的undo log,对于每个UPDATE语句,对应一条相反的UPDATE的undo log,这样在发生错误时,就能回滚到事务之前的数据状态。同时,undo log也是MVCC(多版本并发控制)实现的关键

2.案例

对user_info表执行 update user_info set name =“李四”where id=1 会进行如下流程操作
1、首先获得一个事务编号 104
2、把user_info表修改前的数据拷贝到undo log
3、修改user_info表 id=1的数据
4、把修改后的数据事务版本号改成 当前事务版本号,并把DB_ROLL_PTR 地址指向undo log数据地址。
MYSQL三大日志binlog、redoLog、undoLog_第2张图片

你可能感兴趣的:(后端,MYSQL,JAVA,mysql,数据库,java)