mysql事务(一)——redo log与undo log

时间:2023-03-08 17:11:47

数据事务

即支持ACID四大特性。

A:atomicity          原子性——事务中所有操作要么全部执行成功,要么全部执行失败,回滚到初始状态

C:consistency     一致性——数据库总是从一个一致性状态变化到另一个一致性状态

I:isolation            隔离性——一个事务所做的操作在事务提交前是否被另外一个事务可见,mysql可配置,用以适用不同场景

D:durability         持久性——事务一旦提交,所做操作永久保存(不是仅仅在内存中修改)

mysql通过redo log和undo log保障事务

redo log

事务中所有操作会先写到redo log中,然后再同步到数据库文件中。所以数据库文件进行事务操作修改时,redo log肯定已经记录了所有事务操作,此时即使数据库挂掉,事务操作也都已经持久化到redo log中了,数据库恢复后可以继续执行剩下操作。

redo log有两部分组成,redo log buffer与redo log file。如果每个事务的redo log都实时写到file中,再写到数据文件中,那么性能会比较差,所以可以先把一定时间间隔中的事务操作记录到buffer中,然后统一刷新到file中(此时数据库文件的刷新不一定晚于重做日志文件的刷新)。

redo log使用buffer缓存,丢失了数据持久性,数据库宕机时,没有持久化到redo log file中的事务操作也会丢失。此时数据库数据需要回滚到这些丢失事务之前的状态,undo log正好记录了事务之前的状态。

redo log是物理日志,记录里的是对数据库页的操作,不是sql语句,具有幂等性。

log group包含多个redo log,redo log循环覆盖log group中的文件。

undo log

undo log记录了事务提交之前的数据状态。所以当事务操作同步到数据文件仅仅执行了一半就失败了,恢复后无法找到剩余事务操作,那就只好回滚到事务执行前了。这是就可以使用undo log了。

不同于redo log存放在单独文件中,undo log存放在数据库内部特殊的段中(undo segment),这个段位于共享表空间中。可以知道,undo log必然发生在事务执行之前,所以事务操作执行开始了,undo log必然已经存在了。

redo log与binlog的区别

mysql只有innodb支持事务,redo log和undo log都是innodb的产物。binlog也可以用作数据恢复,不过它是整个mysql的日志,对于所有存储引擎都生效。

binlog存储的是逻辑sql,这一点与redo log中的物理格式不同。

binlog在事务结束后才写进文件,redo log在事务执行中写进文件。

redo log参数设置

执行show global variables like '%innodb%log%';查看参数

mysql事务(一)——redo log与undo log

1、innodb_log_file_size:redo log大小,单位字节

2、innodb_log_files_in_group:redo log group大小,日志组中存在多少个redo log文件

3、innodb_log_group_home_dir:redo log路径,上图表示同数据文件路径

4、innodb_log_buffer_size:重做日志缓存大小

5、innodb_flush_log_at_trx_commit:事务从redo log buffer刷新到redo log file策略

默认值为1,表示redo log事务提交时,立即将操作从buffer刷入file中(commit ->redo log buffer->os buffer->redo log file)。

0表示每innodb_flush_log_at_trx_commit秒钟将redo log buffer刷入redo log file一次。数据库宕机,最多丢失innodb_flush_log_at_trx_commit秒操作。

2表示每次事务提交,都会将redo log buffer写入os buffer,每innodb_flush_log_at_trx_commit秒钟将os buffer同步到redo log file中。这种情况下,数据库宕机,服务器没有宕机,数据库恢复后,已经写入os buffer的事务操作还可以写到redo log file中。

6、innodb_flush_log_at_timeout:配合innodb_flush_log_at_trx_commit使用,表示redo log多久从buffer刷入file中。