InnoDB 事务

2018-09-06  本文已影响26人  10xjzheng

本文摘自《MYSQL技术内幕(InnoDB存储引擎)》

1.认识事务

1.1 概述

InnoDB在事务完全符合ACID的特性。

1.2. 分类

2.事务的实现

事务隔离性由锁来实现。原子性、一致性、持久性通过数据库的redo log和undo log来完成。
redo log称为重做日志,用来保证事务的原子性和持久性。undo log用来保证事务的一致性。

redo和undo的作用都可以视为是一种恢复操作,redo恢复提交事务修改的页操作,而undo回滚行记录到某个特定版本。因此两者记录的内容不同,redo通常是物理日志,记录的是页的物理修改操作。undo是逻辑日志,根据每行记录进行记录。

2.1 redo

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操作。


image.png

若一个页中产生的重做日志数量大于512字节,那么需要分割为多个重做日志块进行存储。此外,由于重做日志块的大小和磁盘扇区大小一样,都是512字节,因此重做的日志的写入可以保证原子性,不需要doublewrite技术。


image.png

2.2 undo

redo存放在重做日志文件中,与redo不同,undo存放在数据库内部的一个特殊段(segment)中,这个段称为undo段(undo segment)。undo段位于共享表空间内。可以通过py_innodb_page_info.py工具来查看当前共享表空间中undo的数量。

上一篇下一篇

猜你喜欢

热点阅读