innodb存储引擎-事务

1:认识事务

1.1:概述

事务的目的就是在一个事务中操作,要么都做修改,要么都不做。

ACID特性

innodb存储引擎完全支持。
ACID特性

  • A 原子性
    一个操作过程如果被定义为原子操作,那么这些操作要么都做,要么都不做。
    原子性是指整个数据库事务是不可分割的工作单位。事务中的所有操作都执行成功才算成功。事务中任何一个sql失败,都要回滚到事务开始的状态。
  • C 一致性
    一致性即在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
  • I 隔离性
    要求每个读写事务的操作对象可以相互分离,即该事务未提交前对其他事务不可见,通常使用锁来实现。
  • D 持久性
    持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

事务的分类

  • 扁平事务
  • 带有保存点的扁平事务
  • 链事务
  • 嵌套事务
  • 分布式事务

事务的分类

扁平事务:
无法有计划的回滚,只能将事务的所有操作全部回滚

带保存点的扁平事务:
能够通过设置保存点,有计划的回滚到保存点的位置。

扁平事务咋爱开始时会隐式的设置一个保存点。

可以设置多个保存点,并且可以选择回滚到哪一个保存点。

但是如果系统崩溃了,保存点会丢失。

链事务:
保存点模式得到一个变种

多个事务连续执行,而且是原子的

只能回滚当前事务,就相当于只能回滚到最近的保存点。

嵌套事务:
层次结构框架,像是一棵树,上一层事务可以调用下一层事务。

  • 子事务既可以是嵌套事务,因为可以是扁平事务

  • 叶子节点的事务时扁平事务

  • 子事务可以提交或者回滚,但是提交操作不会马上生效,而是要等待父事务提交。

  • 任何一个事务回滚,它的子事务都会回滚,故子事务没有 持久性

innodb不支持原生嵌套事务,只能通过保存点来模拟

分布式事务:
分布式环境下运行的扁平事务。

需要调用多台数据库才能完成任务。

2:事务的实现

在innodb存储引擎中,事务的日志由两部分构成:redo log和undo log

redo时重做日志。

undo用于回滚。

redo log存在在重做日志文件中,undo 存放在数据库内部的一个特殊段中,undo段。位于共享表空间内。

2.1:redo

基本概念

重做日志用来实现事务的持久性。包括两部分:

  • 内存中的重做日志缓冲,是易失的
  • 磁盘的重做日志文件,是持久的。

在innodb中,当事务提交时,必须先将该事务的所有日志写入到重做日志文件中进行持久化,再待事务的commit操作完成事务才算完成。这里的日志由redo log和undo log构成。

redo log保证事务的持久性,undo log用来帮助事务回滚及mvcc的功能。

为了确保每次日志文件写入到重做日志文件中,innodb存储引擎每次都会调用一次fsync操作,因为在innodb中重做日志缓冲先是写入到文件系统缓存。需要进行fsync操作再写入到重做日志文件当中。

手动设置非持久性:
innodb中可以设置非持久性的情况,以提高数据库的性能。即当事务提交时,不写入重做日志文件,而是等待一个时间后再执行fsync操作。这样可以提高数据库性能,但是当数据库宕机时,会丢失最后一段时间的事务。

参数innodb_flush_log_at_trx_commit可以控制这种策略:

  • 默认值为1,即表示事务提交时必须进行一次fsync操作。还可以设置为0和2。
  • 0表示提交事务时不进行写入重做日志操作,这个操作仅再master thread中完成,再这个线程中每秒会进行一次写入重做日志文件并进行fsync操作。
  • 2表示事务提交时将重做日志写入重做日志文件,但仅写入文件系统的缓存中,不进行fsync操作。这种设置下数据库宕机而操作系统不宕机时,不会导致事务的丢失。操作系统宕机时,重启数据库会丢失未从文件系统缓存刷新到重做日志文件的那部分事务。

log block

在innodb中,重做日志的大小都是521字节大小。这样大小一个操作日志我们称为重做日志块(log block)

如果一个页中的重做日志大于512字节,重做日志就要分为多个重做日志块块进行存储。

由于重做日志块和磁盘扇区大小一样,所以重做日志的写入可以保证原子性。

重做日志缓存中存储的就是重做日志块

详细结构(p298)

log group

log group为重做日志组,其中有多个重做日志文件。innodb存储引擎实际只有一个重做日志组

只是逻辑上的一个概念。

将重做日志缓冲上的块写如到重做日志文件的时机:

  • 事务提交时
  • 当重做日志缓冲有一半内存空间被使用
  • log checkpoint时

重做日志格式

innodb中的重做日志格式是基于页的。

LSN

日志序列号

LSN的含义有:

  • 重做日志写入的总量
  • checkpoint的位置
  • 页的版本

当前重做日志的LSN为1000,一个新事务写入了100字节的重做日志,那么LSN就变成了1100。

LSN不仅存在于重做日志中,还存在于页中,而且检查点也有自己的LSN。页的LSN表示该页最后刷新时LSN的大小。

每一个页都会记录自己页的重做日志文件的一个LSN,当数据库可启动时,如果页的LSN小于重做日志文件中的LSN,那么就要使用重做日志文件进行恢复。

302页

恢复

检查点技术
重做日志在数据更改后肯定就保存到磁盘,但是脏页不会,所以会使用到重做日志来恢复数据。

检查点的LSN和页上的LSN时一样的。

p304

只需要恢复检查点之后的日志部分。检查点(页上的LSN)之前的页本来就持久化到了磁盘。

2.1:undo

基本概念

事务进行回滚操作就需要用到undo。

innodb 不仅会产生redo还会产生undo,当事务执行失败或者主动回滚的时候,就利用undo将事务回滚到修改之前的样子。

redo log存在在重做日志文件中,undo 存放在数据库内部的一个特殊段中,undo段。位于共享表空间内。

undo不是将数据库物理地恢复到事务开始的样子。而只是将数据库逻辑地恢复到原来的样子。因为一个事务在修改记录的同时,历一个事务可能也在修改。实际上比如事务执行了insert操作,回滚执行的就是delete操作。这样去执行一个反方向的更新来实现回滚。

除了回滚,undo的历一个作用时mvcc,innodb中的 mvcc是通过undo来实现的,当一个记录被其他事务占用时,当前事务可以通过undo来读取之前的行版本信息,以此实现非锁定读。

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

undo 存储管理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值