首页 > 数据库 > MySQL > 正文

mysql事务指的是哪些

2024-07-24 12:33:28
字体:
来源:转载
供稿:网友
  数据库的事务(Transaction)是一种机制、一个操作序列,是访问和更新数据库的程序执行单元,包含了一组数据库操作命令。
 
  首先回顾一下MySQL事务的基础知识。
 
  1. 逻辑架构和存储引擎
 
  mysql事务指的是什么
 
   MySQL服务器逻辑架构从上往下可以分为三层:
 
  (1)第一层:处理客户端连接、授权认证等。
 
  (2)第二层:服务器层,负责查询语句的解析、优化、缓存以及内置函数的实现、存储过程等。
 
  (3)第三层:存储引擎,负责MySQL中数据的存储和提取。MySQL中服务器层不管理事务,事务是由存储引擎实现的。MySQL支持事务的存储引擎有InnoDB、NDB Cluster等,其中InnoDB的使用最为广泛;其他存储引擎不支持事务,如MyIsam、Memory等。
 
  如无特殊说明,后文中描述的内容都是基于InnoDB。
 
  2. 提交和回滚
 
  典型的MySQL事务是如下操作的:
 
  start transaction;
  ……  #一条或多条sql语句
  commit;
  其中start transaction标识事务开始,commit提交事务,将执行结果写入到数据库。如果sql语句执行出现问题,会调用rollback,回滚所有已经执行成功的sql语句。当然,也可以在事务中直接使用rollback语句进行回滚。
 
  自动提交
 
  MySQL中默认采用的是自动提交(autocommit)模式,如下所示:
 
  mysql事务指的是什么
 
  在自动提交模式下,如果没有start transaction显式地开始一个事务,那么每个sql语句都会被当做一个事务执行提交操作。
 
  不过,常用的select、insert、update和delete命令,都不会强制提交事务。
 
  3. ACID特性
 
  ACID是衡量事务的四个特性:
 
  原子性(Atomicity,或称不可分割性)
  一致性(Consistency)
  隔离性(Isolation)
  持久性(Durability)
  按照严格的标准,只有同时满足ACID特性才是事务;但是在各大数据库厂商的实现中,真正满足ACID的事务少之又少。例如MySQL的NDB Cluster事务不满足持久性和隔离性;InnoDB默认事务隔离级别是可重复读,不满足隔离性;Oracle默认的事务隔离级别为READ COMMITTED,不满足隔离性……因此与其说ACID是事务必须满足的条件,不如说它们是衡量事务的四个维度。
 
  下面将详细介绍ACID特性及其实现原理;为了便于理解,介绍的顺序不是严格按照A-C-I-D。
 
  原子性
  1. 定义
 
  原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做;如果事务中一个sql语句执行失败,则已执行的语句也必须回滚,数据库退回到事务前的状态。
 
  2. 实现原理:undo log
 
  在说明原子性原理之前,首先介绍一下MySQL的事务日志。MySQL的日志有很多种,如二进制日志、错误日志、查询日志、慢查询日志等,此外InnoDB存储引擎还提供了两种事务日志:redo log(重做日志)和undo log(回滚日志)。其中redo log用于保证事务持久性;undo log则是事务原子性和隔离性实现的基础。
 
  以update操作为例:当事务执行update时,其生成的undo log中会包含被修改行的主键(以便知道修改了哪些行)、修改了哪些列、这些列在修改前后的值等信息,回滚时便可以使用这些信息将数据还原到update之前的状态。
 
  持久性
  1. 定义
 
  持久性是指事务一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
 
  2. 实现原理:redo log
 
  redo log和undo log都属于InnoDB的事务日志。下面先聊一下redo log存在的背景。
 
  InnoDB作为MySQL的存储引擎,数据是存放在磁盘中的,但如果每次读写数据都需要磁盘IO,效率会很低。为此,InnoDB提供了缓存(Buffer Pool),Buffer Pool中包含了磁盘中部分数据页的映射,作为访问数据库的缓冲:当从数据库读取数据时,会首先从Buffer Pool中读取,如果Buffer Pool中没有,则从磁盘读取后放入Buffer Pool;当向数据库写入数据时,会首先写入Buffer Pool,Buffer Pool中修改的数据会定期刷新到磁盘中(这一过程称为刷脏)。
 
  Buffer Pool的使用大大提高了读写数据的效率,但是也带了新的问题:如果MySQL宕机,而此时Buffer Pool中修改的数据还没有刷新到磁盘,就会导致数据的丢失,事务的持久性无法保证。
 
  于是,redo log被引入来解决这个问题:当数据修改时,除了修改Buffer Pool中的数据,还会在redo log记录这次操作;当事务提交时,会调用fsync接口对redo log进行刷盘。如果MySQL宕机,重启时可以读取redo log中的数据,对数据库进行恢复。redo log采用的是WAL(Write-ahead logging,预写式日志),所有修改先写入日志,再更新到Buffer Pool,保证了数据不会因MySQL宕机而丢失,从而满足了持久性要求。

(编辑:武林网)

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表