MySQL InnoDB之事务

事务的四个特征

原子性

事务中所有的数据库操作要么不做,要么都做,如果其中任何一个sql执行失败,则必须撤销已经成功的sql语句。

一致性

指数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。例如对银行转帐事务,不管事务成功还是失败,应该保证事务结束后ACCOUNTS表中Tom和Jack的存款总额为2000元。

隔离性

由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

持久性

指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

事务的实现

隔离性由锁来实现,原子性、一致性、持久性通过redo log和undo log来实现。

redo log

用来保证事务的原子性和持久性。

记录物理页的修改,由两部分组成:重做日志缓冲(redo log buffer)和重做日志文件(redo log file)。

重做日志文件(存在文件系统缓存)写入磁盘用fsync。

innodb_flush_log_at_trx_commit=1 事务提交时写入重做日志,并进行fsync操作
innodb_flush_log_at_trx_commit=2 写入重做日志,但不进行fsync操作
innodb_flush_log_at_trx_commit=0 不写入重做日志

log block

重做日志缓存,重做日志文件都以block存放(512B)。

图7-7

log group

重做日志组,有多个重做日志文件,每个重做日志文件存储log block。

LSN

重做日志写入的总量

binlog与redo log区别:
1. binlog针对不同种存储引擎都产生,redo log仅innnodb引擎产生。
2. binlog记录对应操作的SQL语句,redo log是物理格式日志,记录对于每个页的修改。
3. binlog在事务提交完成后进行一次写入,redo log在事务进行不断地被写入,因此日志并不随事务的提交顺序产生。

undo log

用来保证事务的一致性。

undo log存放在undo segment中,位于共享表空间中。

对undo的管理采用段的方式,在innodb存储引擎中有rollback segment,每个rollback segment记录了1024个undo log segment,在每个undo log segment段中进行undo页的申请。

undo log分为insert undo log和update undo log。insert undo log对应insert操作,可以再事务提交后立即删除。update undo log对应delete和update操作,可以提供事务的MVCC机制,不能在事务提交时立即删除,需要等待purge线程进行最后的删除。

purge

用于最终完成delete和update操作,这是因为innodb存储引擎支持MVCC机制,记录不能在事务提交时立即处理,因为其他事务可能正在引用这行,故需要保存记录之前的版本。

group commit

多个事务日志通过一次fsync写入日志文件。

事务隔离级别

read uncommitted

read committed

repeatable read

innodb默认支持的隔离级别,使用next-key lock锁算法避免幻读的产生。

serializable