1.认识事务
1.1 概述
InnoDB在事务完全符合ACID的特性。
- 原子性(atomicity):要么都全部执行,要么全部不执行,没有中间态;
- 一致性(consistency):指事务将数据库从一种状态转变为下一种一致性的状态;
- 隔离性(isolation):要求每个读写事务的对象对其它事务的操作对象互相分离;
- 持久性(durability):事务一旦提交,其结果就是永久性的。
1.2. 分类
- 扁平事务
- 带有保存点的扁平事务
- 链事务
- 嵌套事务
- 分布式事务
2.事务的实现
事务隔离性由锁来实现。原子性、一致性、持久性通过数据库的redo log和undo log来完成。
redo log称为重做日志,用来保证事务的原子性和持久性。undo log用来保证事务的一致性。
redo和undo的作用都可以视为是一种恢复操作,redo恢复提交事务修改的页操作,而undo回滚行记录到某个特定版本。因此两者记录的内容不同,redo通常是物理日志,记录的是页的物理修改操作。undo是逻辑日志,根据每行记录进行记录。
2.1 redo
- 1.基本概念
重做日志用来实现事务的持久性,即事务ACID中的D。其由两部分组成:一是内存中的重做日志缓冲(redo log buffer),其是易失的;二是重做日志文件(redo log file),其是持久的。
InnoDB是事务的存储引擎,其通过Force Log at Commit机制实现事务的持久性,即当事务提交时,必须先将该事务的所有日志写入到重做日志文件进行持久化,待事务的COMMIT操作完成才算完成。redo log基本上都是顺序写的,在数据库运行时不需要对redo log的文件进行读取操作。而undo log是需要随机读写的。
为了确保每次日志都写入重做日志文件,在每次重做日志缓冲写入重做日志文件后,InnoDB都需要调用一次fsync操作。由于重做日志文件打开并没有使用O_DIRECT选项,因此重做日志缓冲先写入文件系统缓存。为了确保重做日志写入磁盘,必须进行一次fsync操作。由于fsync的效率取决于磁盘的性能,因此磁盘的性能决定了事务提交的性能,也就是数据库的性能。
InnoDB允许用户手工设置非持久化的情况发生,以此提高数据库的性能。即当事务提交时,日志不写入重做日志文件,而是等待一个时间周期后再执行fsync操作。但宕机会丢失一部分数据。
参数innodb_flush_log_at_trx_commit用来控制重做日志刷新到磁盘的策略。默认值是1,表示事务提交时必须调用一次fsync操作, 0表示事务提交时不进行写入重做日志操作,这个操作仅在master thread中完成,而在master thread中每1s会进行一次重做日志文件的fsync操作。2表示事务提交时将重做日志写入重做日志文件,但仅写入缓存,不进行fsync操作。
- log block
在InnoDB中,重做日志都是以512字节进行存储的。这意味着重做日志缓存、重做日志文件都是以块(block)的方式进行保存的,称之为重做日志块(redo log block),每块的大小为512字节。
- log block
若一个页中产生的重做日志数量大于512字节,那么需要分割为多个重做日志块进行存储。此外,由于重做日志块的大小和磁盘扇区大小一样,都是512字节,因此重做的日志的写入可以保证原子性,不需要doublewrite技术。
- log group
log group为重做日志组,其中有多个重做日志文件。
- log group
2.2 undo
- 1.基本概念
重做日志记录了事务的行为,可以很好地通过其对页进行重做操作。但是事务有时还需要进行回滚操作。这时候就需要undo。因此在对数据库进行修改时,InnoDB不但会产生redo,还会产生一定量的undo。这样如果用户执行的事务或语句由于某种原因失败了,又或者用户用一条ROLLBACK语句请求回滚,就可以利用这些undo信息将数据回滚到修改之前的样子。
redo存放在重做日志文件中,与redo不同,undo存放在数据库内部的一个特殊段(segment)中,这个段称为undo段(undo segment)。undo段位于共享表空间内。可以通过py_innodb_page_info.py工具来查看当前共享表空间中undo的数量。
- undo存储管理
InnoDB对undo的管理同样采用段的方式。但是这个段和之前介绍的段有所不同。首先InnoDB有rollback segment,每个回滚段种记录了1024个undo log segment,而在每个undo log segment段中进行undo页的申请。共享表空间偏移量为5的页(0,5)记录了所有rollback segment header所在的页,这个页的类型为FIL_PAGE_TYPE_SYS。
- undo存储管理
3 undo log 格式
分为:insert undo log;
update undo log;
- 查看undo信息