Press "Enter" to skip to content

Category: MySQL技术内幕~InnoDB存储引擎

MySQL的事务

事务(Transaction)是数据库区别于文件系统的重要特性之一。事务会把数据库从一种一致状态转换为另一种一致状态。在数据库提交工作时,可以确保要么所有修改都已经保存了,要么所有修改都不保存。


InnoDB存储引擎中的事务完全符和ACID的特性:
1. A原子性(Atomicity)
原子性指整个数据库事务是不可分割的工作单元。只有使事务中所有的数据库操作都执行成功,才算整个事务的成功。事务中任何一个SQL语句执行失败,已经执行成功的SQL语句也必须撤销,数据库状态应该退回到执行事务前的状态。
2. C一致性(Consistency)
一致性指事务将数据库从过一种状态转变为下一种一致性的状态。事务是一致性的单位,如果事务中某个动作失败了,系统可以自动撤销事务——返回初始化的状态。
3. I隔离性(Isolation)
隔离性还有其他称呼,如并发控制、可串行化、锁等。事务的理性要求每个读写事务的对象对其他事务的操作对象能相互分离,即该事务提交前对其他事务都不可见,通常这是用锁来实现。
4. D持久性(Durability)
事务一旦提交,其结果就是永久性的。及时发生宕机等故障,数据库也能将数据恢复。注意,只能从事务本身的角度来保证结果的永久性。如果因为外部原因,比如raid卡损坏、不可抗力等原因导致数据库损坏,所提交数据仍然有可能丢失。因此,持久性保证事物系统的高可靠性,而不是高可用性。

认识事务

事务是访问并更新数据库中各种数据项的一个程序执行单元。在事务中的操作,要么都做修改,要么都不做。这就是事务的目的,也是事务模型区别与文件系统的重要特性之一。

分类

  • 扁平事务
    扁平事务中,所有操作都处于同一层次,由begin work开始,由commit work或者rollback work结束,期间的操作是原子的,要么执行,要么回滚。
  • 带有保存点的扁平事务
    除了支持扁平事务支持的操作外,允许在事务执行过程中回滚到同一事务中较早的一个状态。保存点用来通知系统应该记住事务当前的一个状态。
  • 链事务
    带有保存点的扁平事务,当发生系统崩溃时,所有的保存点都将小时,因为其保存点是易失的,而非持久的。链事务的思想是:在提交一个事务时,释放不需要的数据对象,将必要的处理上下文隐式的传给下一个要开始的事务。提交事务操作和开始下一个事务操作将合并为一个原子操作。
  • 嵌套事务
    嵌套事务是一个层次结构框架,由一个顶层事务控制各个层次的事务。顶层事务之下嵌套的事务被成为子事务。
  • 分布式事务
    在分布式环境下运行的扁平事务,需要根据数据所在位置访问网络的不同节点。

实现

事务的隔离性由锁来实现。原子性、一致性和持久性通过数据库的redo log和undo log来完成。redo log成为重做日志,用来保证事务的原子性和持久性。undo log用来保证事务的一致性。
redo和undo的作用都可以视为一种恢复操作,redo恢复提交事务修改的页操作,而undo回滚行记录到某个特定版本。redo通常是物理日志,记录的是页的物理修改操作。undo是逻辑日志,根据每行记录进行记录。

redo

重做日志用来实现事务的持久性。其由两部分组成:一是内存中的重做日志缓冲(redo log buffer),其实易失的;二是重做日志文件(redo log file),其是持久的。
InnoDB是事务的存储引擎,当事务提交时,必须先将该事务的所有日志写入到重做日志文件进行持久化,待事务的commit操作完成才算完成。
为了确保每次日志都写入redo log,在每次将redo log buffer写入redo log之后,InnoDB都需要调用fsync操作。因此,磁盘性能决定了事务提交的性能,也就是数据库的性能。
参数innodb_flush_log_at_trx_commit用来控制重做日志刷新到磁盘的策略。该参数的默认值为1,表示事务提交时必须调用一次fsync操作。开可以设置该参数的值为0和2.0表示事务提交时不进行写入redo log操作,这个操作仅在master thread中完成,而在master thread中每一秒会进行重做日志文件的fsync操作。2表示事务提交时将redo log buffer写入redo log,不进行fsync操作。在这个设置下,当MySQL数据宕机而操作系统未宕机时,并不会丢失事务。

undo

事务的回滚操作需要由undo来实现。与redo不同,undo存放在数据库内部一个特殊的字段中,这个段被成为undo段,它位于共享表空间内。可以通过py_innodb_page_info.py来查看。

事务的隔离级别

SQL标准定义的四个隔离级别由低到高为:
* read uncommitted——浏览访问
* read commited——游标稳定
* repeatable read——隔离,没有幻读的保护,为InnoDB默认级别
* serializable——隔离,串行化