InnoDB存储引擎(七)事务

目录

 

7.1 概述

7.1.1 ACID

7.1.2 分类

7.2.1 redo

基本概念

log block

重做日志格式

LSN(Log Sequence Number)

恢复

7.2.2 undo

基本概念

存储管理

格式

purge

group commit

7.3 事务控制语句

7.4 隐式提交的SQL语句

7.5 不好的事务习惯


7.1 概述

7.1.1 ACID

  1. 原子性:要么都做,要么都不做

  2. 一致性:数据库从一种一致性状态转变为下一种一致性状态

  3. 隔离性:每个读写事务的对象对其它事务的操作对象能相互分离,即:该事务提交前对其他事务都不可见

  4. 持久性:事务一旦提交,其结果就是永久性的

7.1.2 分类

1. 扁平事务

最简单,所有操作都处于同一层次,由begin开始,由commit或者rollback结束,其间操作都是原子的

2. 带有保存点的扁平事务

允许在事务执行过程中回滚到同一事务中较早的一个状态

保存点:通知系统应该记住事务当前的状态,以便当之后发生错误时,事务能回到保存点当时的状态;使用 SAVE WORK 函数建立,通知系统记录当前的处理状态;保存点在事务内部单调递增

当系统发生崩溃时,所有的保存点都将消失。当进行恢复时,事务需要从最开始处重新执行,而不能从最近的一个保存点继续执行

案例:出门旅游

3. 链事务

可视为保存点模式的一种变种。

在提交一个事务时,释放不需要的数据对象,将必要的处理上下文隐式地传给下一个要执行的事务。注意,提交事务操作和开始下一个事务操作将合并为一个原子操作,也就是下一个事务将看到上一个事务的结果。

回滚仅限于当前事务,即只能恢复到最近的一个保存点

4. 嵌套事务(不原生支持)

是一个层次结构框架,由一个顶层事务控制着各个层次的事务

所有子事务都在顶层事务提交后才真正的提交,任意事务的回滚都会引起它的所有子事务的回滚

5. 分布式事务

在分布式环境下运行的扁平事务,需要根据数据所在位置访问网络中的不同节点

案例:银行转账,从一张卡转到另外一张卡

7.2.1 redo

基本概念

  1. 重做日志缓存和重做日志文件

  2. 顺序写

  3. fsync操作:重做日志缓存 -> 文件系统缓存 -> 文件系统,因此,磁盘的性能决定了事务提交的性能,即数据库性能

  4. 重做日志刷新到磁盘的策略,事务提交时、master thread每秒操作或者事务提交时,将重做日志写入文件系统缓存

  5. 与二进制日志(进行POINT IN TIME的恢复及主从复制的建立)的区别

log block

重做日志缓存、重做日志文件都是以块(block)的方式进行保存的,称之为重做日志块(redo log block),每块的大小为512字节。

若一个页中产生的重做日志数量大于512字节,那么需要分割为多个重做日志块进行存储。

由于重做日志块的大小和磁盘扇区大小一致,都是512字节,因此重做日志的写入可以保证原子性,不需要doublewrite技术。

重做日志块的结构:日志块头(12字节)、日志(492字节)、日志块尾(8字节)

重做日志格式

重做日志格式是基于页的,虽然有着不同的重做日志格式(InnoDB 1.2 有51种),但是它们有着通用的头部格式。

通用的头部格式由以下3部分组成:

  1. redo_log_type:重做日志的类型

  2. space:表空间的ID

  3. page_no:页的偏移量

LSN(Log Sequence Number)

日志序列号,占8个字节,并且单调递增,其表示的含义有:

1. 重做日志写入的字节的总量

LSN=1000;事务1写入100字节,LSN=1100;事务2写入200字节,LSN=1300

LSN存在于重做日志和每个页中,在每个页的头部,有一值FIL_PAGE_LSN,记录了该页的LSN,表示该页最后刷新时LSN的大小,可以用来判断页是否需要进行恢复操作,若在页中的LSN=1000,数据库启动时,LSN=1300,并且该事务已经提交,那么需要进行恢复操作,反之,则不需要。

通过show engine innodb status查看LSN的情况。

LOG
---
Log sequence number 381727521755   -- 当前的LSN
Log flushed up to   381727521755   -- 刷新到重做日志文件的LSN
Pages flushed up to 381727306352   -- 当前最旧的脏页数据对应的LSN
Last checkpoint at  381727304797   -- 刷新到磁盘的LSN
0 pending log flushes, 0 pending chkp writes
11035274 log i/o's done, 0.98 log i/o's/second

2. checkpoint的位置

3. 页的版本

恢复

重做日志记录的是物理日志,因此恢复速度比逻辑日志,如二进制日志,要快很多。

checkpoint机制表示已经刷新到磁盘页上的LSN,因此在恢复过程中仅需要恢复checkpoint开始的日志部分。如,当数据库在checkpoint的LSN为10,000发生宕机,恢复操作仅恢复LSN 10,000 ~ 13,000范围内的日志。

重做日志是幂等的,即:f(f(x)) = f(x)

案例:insert操作

7.2.2 undo

基本概念

可以被重用

作用:

  1. 回滚

  2. MVCC

 

对数据库进行修改时,不仅会产生redo,还会产生一定量的undo,利用undo信息可以将数据回滚到修改之前的样子。

undo存放在数据库内部的一个特殊段(segment)中,这个段称为undo段,位于共享表空间中。

存储的是逻辑日志,即SQL语句。回滚时,做的是与之前相反的工作,对于每个insert,InnoDB存储引擎会执行一个delete;对于每个delete,会执行一个insert;对于每个update,会执行一个相反的update,将修改前的行放回去。

undo log会产生redo log,也就是undo log的产生会伴随着redo log的产生,这是因为undo log也需要持久性的保护。

存储管理

InnoDB存储引擎有rollback segment,每个回滚段中记录了1024个undo log segment,而在每个undo log segment段中进行undo页的申请。

InnoDB 1.1版本开始,支持最大128个rollback segment,支持同时在线事务的限制提高到了128*1024。

从InnoDB 1.2开始,可通过参数对rollback segment做进一步的设置。这些参数包括:

  1. innodb_undo_directory:文件所在位置,可以存放在独立表空间中,默认为'.',表示当前InnoDB存储引擎目录

  2. innodb_undo_logs:rollback segment文件的个数

  3. innodb_undo_tablespaces:构成rollback segment文件的数量

mysql> SHOW VARIABLES LIKE 'innodb_undo%' ;
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| innodb_undo_directory   | .     |
| innodb_undo_logs        | 128   |
| innodb_undo_tablespaces | 0     |
+-------------------------+-------+
3 rows in set (0.01 sec)

事务提交后并不能马上删除undo log及undo log所在的页。这是因为可能还有其他事务需要通过undo log来得到行记录之前的版本。故事务提交时将undo log放入一个链表中,是否可以最终删除undo log及undo log所在页由purge线程来判断。

格式

  1. insert undo log

指在insert操作中产生的undo log。因为insert操作的记录,只对事务本身可见,对其他事务不可见,故该undo log可以在事务提交后直接删除,不需要进行purge操作。

  1. update undo log

对delete和update操作产生的undo log,该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。

格式图

purge

用于最终完成delete和update操作。

group commit

磁盘fsync的性能是有限的,为了提高磁盘效率,当前数据库都提供了group commit的功能,即一次fsync可以刷新确保多个事务日志被写入文件。对于InnoDB存储引擎来说,事务提交时会进行两个阶段的操作:

  1. 修改内存中事务对应的信息,并且将日志写入重做日志缓冲

  2. 调用fsync确保日志都从重做日志缓冲写入磁盘

在InnoDB 1.2版本之前,在开启二进制日志后,group commit功能会失效,从而导致性能的下降。MySQL 5.6采用Binary Log Group Commit(BLGC)解决。

7.3 事务控制语句

  1. start transaction|begin

  2. commit

  3. rollback

  4. savepoint identifier

  5. release savepoint identifier

  6. rollback to [savepoint] identifier

  7. set transaction

7.4 隐式提交的SQL语句

  1. DDL语句:alter、create、drop、rename table、truncate table(不能被回滚)

  2. 用来隐式地修改MySQL架构的操作:create user、drop user、grant、rename user、revoke、set password

  3. 管理语句:analyze table、cache index、check table、load index into cache、optimize table、repair table

7.5 不好的事务习惯

默认配置下,MySQL数据库总是自动提交的

  1. 在循环中提交

  2. 使用自动提交

  3. 使用自动回滚

  4. 长事务,执行时间长的事务,可以转换为小批量的事务来进行处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值