innodb数据库事务

1. 事务:将数据库从一种一致状态转换为另一种一致状态
A(Atomic):原子性,数据库事务是不可分割的工作单位,事务中的操作只有全成功才算整个事务成功。
C(consistency):一致性,事务将数据库从一种状态变为下一种一致的状态,事务开始和结束时,数据库的完整性没有破环。
I(isolation):隔离性,一种事务未提交前不能对另一事务产生影响,一般通过锁来实现。
D(durability):一致性,事务一旦提交,其结果是永久性的。通过redo log可以来保证,一致性保证的是数据库的高可靠性,对于高可用性则需要采用分布式等来保证。
事务的隔离性由锁来实现,原子性、一致性、持久性通过redo log和undo log来实现

2. 事务的分类:
1)扁平事务:所有操作处于同一层次
2)带保存点的扁平事务:允许事务在执行过程中回滚到任何一个保存点的状态
3)链事务:将提交事务操作和开始下一个事务操作合并为一个原子操作,这意味者下一个事务可以看到上一个事务的结果,就好像同一个事务中。
4)嵌套事务:顶层事务控制着各层事务,子事务可以提交也可以回滚,但它的提交并不会马上生效,必须等到父事务提交;同时,如果父事务回滚,则其子事务都回滚
5)分布式事务:在分布式环境下运行扁平事务。
(对于innodb来说,其并不原生支持嵌套事务)

3. 事务的实现:
3.1 redo:当事务提交时,必须先将事务日志写到重做日志文件,这样保证了持久性(C)
重做日志缓存先写到文件系统缓存,然后进行fsync操作,刷新到文件中
1).二进制文件是数据库层的,因此任何引擎都有二进制文件;而redo是innodb层的
2).内容形式不同,二进制日志是一种逻辑日志,记录的是对应的sql语句;而redo是物理格式日志,记录的是对每页的修改
3).写入磁盘的,时间不同,二进制日志只在事务提交完成后一次写入;而redo在事务进行中不断写入

3.1.1 在innodb中,重做日志是以512字节为单位进行存储,称为log block,由于重做日志的大小和磁盘扇区大小一样,因此重做日志的写入是原子操作,不需要doublewrite技术
在log block中重做日志头占12字节,重做日志尾占8字节,故每个log block实际可存储492字节

3.1.2 log group
重做日志组中有多个重做日志文件,重做日志的写入采用round-robin形式

其中checkpoint是交替写入,避免因介质失败而无法找到可用的checkpoint,同时在每个组中只有第一个log file文件才有2kb的头部分信息,其它的文件头部分为空

3.1.3 重做日志格式(每条记录的格式)


注:重做日志记录的物理日志,即每个页的变化
对于下表

3.1.4 LSN(log sequence number)
日志序列号,在innodb中占8字节,单调递增,其代表的含义为:
1)重做日志写入的总量(单位是字节)
2)checkpoint的位置 :表示刷新到磁盘的LSN
3)页的版本号:在每个页的头部有一个值FIL_PAGE_LSN,记录该页的LSN,表示该页最后刷新时LSN的大小,因为重做日志记录的是每个页的日志,因此页的LSN可以用来判断页是否需要进行恢复。例如,页P1的LSN为10000,而数据库启动时,innodb检测到写入到重做日志的LSN已经到了13000,并且事务已经提交了,那么数据库将进行恢复操作,将重做日志应用到P1页中。同样,如果重做日志中LSN小于P1页的LSN,不需要重做。

3.2 undo
innodb对undo的管理采用段的方式,在系统表空间中存在rollback segement(innodb1.1之前只有一个rollback segment,之后支持最大128个)
,每个rollback segement含1024个undo log segement,而在每个undo log segement段中进行undo页的申请 (管理),因此同时在线事务数最多为128*1024

当事务提交时,innodb引擎会做如下两件事:
1)将undo log放入表中,以供之后的purge操作
2)判断undo log所在页是否可以重用,若可以则分给下个事务使用

对于1)而言,undo log可分为两类,一类是insert操作产生的undo log,因为insert操作只对事务本身起作用,对其他事务不可见,因此undo log可以在提交后直接删除。另一类是delete和unpdate产生的undo log,该undo log可能提供mvcc机制,因此提交后需放入undo log链表,等待purge删除

对于2)而言,若为每个事务分配一个单独的undo页在某些情况下会浪费空间 (由于事务提交后不能马上释放页),因此当事务提交时,判断undo页的使用空间是否少于3/4,若是则可重用,之后新的undo log记录在其后面。

3.3 purge
对于delete和update操作并不是直接删除undo log,而是将记录的delete flag设置为1,随后由purge操作来删除

4. 事务操作语句
在mysql中默认事务都是自动提交的,因此要显式开启一个事务要通过命令来执行
start transaction | begin(显式开启一个事务)
commit
rollback
savepoint identifier
。。。
如果是commit work,若completion_type为0,则和commit是一样;若为1则表示开启一个链事务,即提交之后不需要在输入begin等命令,直接开启下一个事务;当其为2是,则表示提交后自动断开与服务器的连接。

猜你喜欢

转载自blog.csdn.net/yzc11111111/article/details/78941313