一.什么是undo log ?
1.定义
undo,顾名思义“回滚日志”,是事务日志的一种。记录内存数据页修改之前的状态(类似于快照)在故障自动恢复过程中实现回滚的操作。
存储位置:默认存放在共享表空间中
如果开启了 innodb_file_per_table ,将放在每个表的.ibd文件中。在MySQL5.6中,undo的存放位置还可以通过变量 innodb_undo_directory 来自定义存放目录,默认值为"."表示datadir。
ibdata文件默认只有一个,默认大小为1024M
默认了话undo log是无法自动清除,数据库的上线时间越长,就会越来越大,可能会使磁盘空间使用越来越大,并且备份也会越来越长。
mysql 5.7支持设置ibdata自定义设置存储路径,已经指定数据量truncate
mysql的参数配置:
innodb_undo_log_truncate =on 开启自动清理undo log的功能
innodb_max_undo_log_size =1024M undo log达到多大时truncat
innodb_undo_tablespaces =3 至少指定三个,以防truncate日志的时候,ibdata无法使用
注意配置需要,在配置文件定义好之后,需要初始化安装的时候实现,直接修改配置文件,重启数据库会报错。
2.作用:
在事务ACID过程中,实现的是“ACI”原子性,一致性的作用。通过隔离级别实现
1)rollback
2)CSR过程中,实现回滚
3)多个行版本控制(MVCC)
3.undo记录了什么
数据页修改之前的状态,TXID
二.redo和undo日志的工作原理
1.需要被修改的数据从磁盘page调取到内存的buffer page进行处理,并且把修改前的数据存储到undo buffer中,以用于在commit前的数据进行回滚
2.redo buffer记录被修改数据的过程
3.直接把修改后的数据在commit后写入磁盘工作量太大,浪费磁盘的大量io ,所以把redo buffer写入到redo日志里去,用于突然地断电,内存丢失可以进行数据的恢复,而磁盘的数据真正的写入是在buffer pool达到上限的时候来进行一次性把数据写入磁盘中去。
4.突然地宕机导致内存数据丢失,可以根据磁盘的page原始数据和ib_logfile日志重回内存;来进行数据的恢复,保证数据的一致性。那么如何在宕机后确保宕机后redo日志的记录和page的记录一致呢?可以通过增加lsn ,日志序列号,在宕机后,对比redo日志和page的lsn是否相同,相同说明最后一条执行的语句已经commit,无需处理,如果redo日志的lsn大于page的lsn说明,最后一条语句没有commit,那么把page的数据和redo日志的数据再次提交到内存中来进行数据的恢复,恢复后再次commit,保证了断电后数据的一致性。这种技术就叫做WAL redo日志优先存入磁盘来保证数据的一致性。
5.redo日志先存入磁盘,数据后存入磁盘