diff --git a/mysql/mysql文档/mysql_事务.md b/mysql/mysql文档/mysql_事务.md index df18058..85040f5 100644 --- a/mysql/mysql文档/mysql_事务.md +++ b/mysql/mysql文档/mysql_事务.md @@ -250,5 +250,37 @@ page(2,4), offset 64, value 2; # 辅助索引页 ``` 由上述示例可知,redo log为物理日志,记录的是对页的物理修改,故而`redo log是幂等的`。 +### undo +redo log记录了对页的物理操作,可以用于进行`redo`。而undo和redo不同,undo主要用于对事务的回滚。 + +undo的存放位置和redo不同: +- redo log存放在redo log file中 +- undo log存放在数据库内部的segment中,该segment被称为`undo segment`。`undo段位于共享的表空间内` + +#### undo log和redo log差异 +- redo log为物理日志,记录的是对页的修改;而undo log则是逻辑日志,对每个insert操作,undo log会生成一个相反的delete,对update也会生成另一个逆向的update +- redo log是全局的,innodb中所有事务都会`向同一个redo log交叉写入`;而undo log则是针对事务的,每个事务都有其自己的undo log chain + +#### 非锁定读 +除了用于事务回滚外,undo log还可以用于MVCC。当事务A尝试读取一条记录R时,如果记录R已经被另一个事务B占用,那么事务A可以通过undo log读取行数据之前的版本。 + +上述实现被称为`非锁定读`。 + +#### undo log的产生会伴随redo log的产生 +`undo log其本质仍然是数据`。undo log其存放在表空间的undo segment中,仍然可被可做是数据,而`WAL(write-ahead logging)要求变更被应用到数据库之前,需要先写入日志`。 + +故而,在生成undo log时,对于undo页的修改也会被记录到redo log中。 + +#### 存储管理 +innodb通过segment来管理undo log,其管理方式如下: +- innodb包含rollback segment +- 每个rollback segment会记录1024个undo log segment +- undo log segment中会进行undo页的申请 +- 共享表空间偏移量为5的页会记录所有rollback segment header所在的页 + - 偏移量为5的页类型为FIL_PAGE_TYPE_SYS + +##### innodb_undo_directory +该参数用于设置rollback segment文件所在的路径,默认为`./`,代表`datadir`。 +