undo log回滚日志原理
执行事务的时候,里面很多INSERT、UPDATE和DELETE语句都在更新缓存页里的数据,但是万一事务回滚,你必须有每条SQL语句对应的undo log回滚日志,根据回滚日志去恢复缓存页里被更新的数据。
undo log的存储机制
undo log的存储由InnoDB存储引擎实现,数据保存在InnoDB的数据文件中。在InnoDB存储引擎中,undo log是采用分段(segment)的方式进行存储的。rollback segment称为回滚段,每个回滚段中有1024个undo log segment。在MySQL5.5之前,只支持1个rollback segment,也就是只能记录1024个undo操作。在MySQL5.5之后,可以支持128个rollback segment,分别从resg slot0 - resg slot127,每一个resg slot,也就是每一个回滚段,内部由1024个undo segment 组成,即总共可以记录128 * 1024个undo操作。
undo log日志里面不仅存放着数据更新前的记录,还记录着RowID、事务ID、回滚指针。其中事务ID每次递增,回滚指针第一次如果是insert语句的话,回滚指针为NULL,第二次update之后的undo log的回滚指针就会指向刚刚那一条undo log日志,依次类推,就会形成一条undo log的回滚链,方便找到该条记录的历史版本。
undo log的工作原理
1、事务A执行update操作,此时事务还没提交,会将数据进行备份到对应的undo buffer,然后由undo buffer持久化到磁盘中的undo log文件中,此时undo log保存了未提交之前的操作日志,接着将操作的数据,也就是Teacher表的数据持久保存到InnoDB的数据文件IBD。
2、此时事务B进行查询操作,直接从undo buffer缓存中进行读取,这时事务A还没提交事务,如果要回滚(rollback)事务,是不读磁盘的,先直接从undo buffer缓存读取。
undo log能同时保证原子性和持久化
更新数据前记录undo log;
为了保证持久性,必须将数据在事务提交前写到磁盘,只要事务成功提交,数据必然已经持久化到磁盘;
undo log必须先于数据持久化到磁盘,如果在数据【持久化---->事务提交】之间发生系统崩溃,undo log是完整的,可以用来回滚;
如果在【事务开始---->undo log日志持久化】之间发生系统崩溃,因为数据没有持久化到磁盘,所以磁盘上的数据还是保持在事务开始前的状态;
undo log的相关参数
代码语言:javascript复制innodb_undo_directory:指定undo log日志的存储目录,默认值为./。
innodb_undo_logs :通过此参数自定义多少个rollback segment,默认值为128。
innodb_undo_tablespaces:指定undo log平均分配到多少个表空间文件中,默认值为0,
即全部写入一个文件中。不建议修改为非0值,我们直接使用默认值即可