数据库事务特性的实现原理

一、原子性实现原理 Undo Log(引擎层特有)

  1. Undo Log 是为了实现事务的原子性,在MySQL 数据库InnoDB 存储引擎中,还用Undo Log 来实现多版本并发控制(简称MVCC)。
  2. 在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方叫做Undo Log),然后进行数据的修改。 如果出现了错误或者用户执行了ROLLBACK 语句,系统可以利用Undo Log中的备份数据将事务恢复到事务开始之前的状态。
  3. Undo Log 是逻辑日志,可以这样子理解:
    3.1 当delete 一条记录时,undo log 会记录对应的insert 记录。
    3.2 当insert 一条记录时,undo log 会记录对应的delete 记录。
    3.3 当update 一条记录时,它记录一条对应的update 记录。

为啥叫逻辑日志?:内存在和磁盘产生交互的时候是以页为单位的,页是一个逻辑上的概念,一般操作系统规定是4kb 或者8kb,InnoDB在读取数据的时候一次性读取16kb。undo log 实际上执行的是一整行数据的更新信息而不是一整页的数据更新信息,所以叫做逻辑日志不叫物理日志。
redo log 是记录的整个页的数据。
怎样实现多版本并发控制?:多个数据对同一条记录进行查询更新处理,一个是查询一个是更新,那更新想查询数据是没法直接查到被更新的结果的,只能查到更新之前的结果,所以只能根据undo log 进行存储。

二、持久性实现原理Redo Log(引擎层特有)

  1. 和Undo Log 相反,Redo Log 记录的是新数据的备份。在事务提交前,只是将Redo Log 持久化即可,不需要数据持久化。当系统崩溃时,虽然数据没有持久化,但Redo Log 已经持久化了。系统可以根据Redo Log 将数据更新到最新的状态。
    innodb_flush_log_at_trx_commit:1/2/3 默认如下图的2.



    show variables like 'innodb_flush_log_at_trx_commit';
    set global innodb_flush_log_at_trx_commit=2;

三、隔离性

事务具有隔离性,理论上说事务之间的执行不应该相互影响,其读数据库的影响应该和他们串行时执行一样。
完全的隔离性会导致系统并发性能很低,降低对资源的利用率,因而实际上会对隔离性的要求会有所放松。
SQL 标准为事务定义了不同的隔离级别,从低到高依次是:

  1. 读未提交 脏读、幻读、不可重读读
  2. 读已提交 幻读、不可重读(Oracle 的默认隔离界别)
  3. 可重读读 幻读(MySQL的默认隔离级别)
  4. 序列化

四、隔离性实现原理:锁

  1. 基于锁的并发控制流程:
    1.1 事务根据自己对数据项进行的操作类型申请相应的锁(读申请共享锁,写申请排它锁)。
    1.2 申请锁的请求被发给锁管理器。锁管理器根据当前页是否已经有锁以及申请的和持有的锁是否冲突决定是否为该请求授予锁。
    1.3 若锁被授予,则申请锁的事务可以被继续执行;若被拒绝,则申请锁的事务将进行等待,直到锁被其它事务释放。
  2. 可能出现的问题:
    2.1 死锁:多个事务持有锁并循环等待其它事务的锁导致所有的事务都无法继续执行。
  3. 扩展:除了锁可以实现并发控制外,还有其它策略:
    3.1 基于时间戳的并发控制
    3.2 基于有效性检查的并发控制
    3.3 基于快照的隔离并发控制

五、事务的特点

  1. 一致性是事务的根本追求,而在某些情况下会对事务的一致性造成破坏:
    1.1 事务的并发性
    1.2 事务故障或系统故障
  2. 数据库系统通过并发控制和日志恢复技术来避免这种情况的发生。
    2.1 并发控制技术保证了事务的隔离性,使数据库一致性不会因为并发执行操作被破坏。
    2.2 日志恢复技术保证了事务的原子性,使一致性状态不会因为事务或系统故障或系统故障而被破坏。同时使已提交的对数据库的修改不会因为系统崩溃而丢失,保证了事务的持久性。

你可能感兴趣的:(数据库事务特性的实现原理)