MySQL事务机制

       事务会把数据库从一种一致状态转换为另一种状态。在数据库提交工作时,可以确保要么所有修改都已经保存了,要么所有修改都不保存。事务具有ACID这四个特性,分别为原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。

       事务是由一条非常简单的SQL语句组成,也可以由一组复杂的SQL语句组成。事务是访问并更新数据库中各种数据项的一个程序执行单元。在事务中的操作,要么都做修改,要么都不做,这就是事务的目的。

事务的ACID

原子性:同一个事务是不可分割的单元,要么全部完成,要么全部失败。

一致性:数据库从一个状态转变成下一种一致的状态,在事务开始之前和事务结束之后,数据库的完整性约束没有被破坏。例如A向B转了100,那么A的账户少了100,这时,B的账户必须多了100,不然就是不一致的。另外一个例子就是能量守恒定律。

隔离性:主要针对并发的情况,要求每个读写事务的对象对其他事务的操作对象是相互分离,即该事务提交之前对其他事务不可见。一般通过锁实现,在相关文章中有详细的介绍。

持久性:事务一旦提交,其结果就是永久性的。即使发生宕机等故障,数据库也能恢复数据。

rodo与undo

       对于MySQL的InnoDB引擎来说,事务的隔离性是通过锁来实现的,在锁的相关文章已经详细说明。原子性、一致性、持久性是通过数据的redo log和undo log来完成的。

        redo恢复提交事务修改的页操作,而undo回滚行记录到某个特定版本。因此两者记录的内容不同,redo通常是物理日志,记录的是页的物理修改操作。undo是逻辑日志,根据每行记录进行记录。

        redo log用来实现事务的持久性和一致性,它由两部分组成:一是内存中的重做日志缓冲(redo log buffer),其是易失的;二是重做日志文件(redo log file),其是持久的。事务开启时,事务中的操作,都会先写入存储引擎的日志缓冲中,在事务提交之前,这些缓冲的日志都需要提前刷新到磁盘上持久化,这就是DBA们口中常说的“日志先行”(Write-Ahead Logging)。当事务提交之后,在Buffer Pool中映射的数据文件才会慢慢刷新到磁盘。此时如果数据库崩溃或者宕机,那么当系统重启进行恢复时,就可以根据redo log中记录的日志,把数据库恢复到崩溃前的一个状态。未完成的事务,可以继续提交,也可以选择回滚,这基于恢复的策略而定。

       undo主要用于回滚和实现MCVV,它是在用户执行事务时,由于某种原因失败,又或者有一个rollback语句请求回滚,就可以利用这些undo信息将数据回滚到修改前的样子。undo存放在数据库内部的一个特殊字段中,这个段叫做undo段,位于共享表空间中。注意undo是逻辑日志,因此只是将数据库逻辑地恢复到原来的样子。所有的修改都被逻辑地取消了,但是数据结构和页本身在回滚之后可能大不相同。

       前面还说到MCVV是通过undo来完成的。当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过undo读取之前的行版本信息,以实现非锁定读取。

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

MVCC是如何工作的 

       InnoDB的MVCC是通过在每行记录后面保存两个隐藏的列来实现。这两个列一个保存了行的创建时间,一个保存行的过期时间(删除时间)。当然存储的并不是真实的时间而是系统版本号(system version number)。每开始一个新的事务,系统版本号都会自动新增。事务开始时刻的系统版本号会作为事务的版本号,用来查询到每行记录的版本号进行比较。

https://www.zhihu.com/search?type=content&q=%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8B%E5%8A%A1

《MySQL技术内幕》

你可能感兴趣的:(数据库)