浅谈 Mysql 事务 由 ACID 到 MVCC

最近公司的技术分享一直在分享 mysql 事务,隔离级别,锁和 MVCC 方面的知识,但是都是基于单个点进行分析,没有一步一步来阐述,所以在这里我整理了一下 mysql 由 ACID 到 MVCC 这一块的知识准备分享给大家。

咱们开门见山先谈 事务
  • 首先思考事务有什么作用?
    • 事务是为了保证数据库中数据的完整性和一致性
  • 事务的四个基本要素 ACID ?这四要素是怎么实现的?
    • 原子性 Atomicity
      • 原子性通过 Innodb undo log 即回滚日志实现
    • 一致性 Consistency
      • 一致性通过 lock 锁来实现
    • 隔离性 Isolation
      • 隔离性通过 lock 锁和 MVCC 来实现
    • 持久性 Durability
      • 持久性通过 Innodb redo log 即重写日志实现 ,和 doublewrite 两次写技术来实现

现在我们开始谈 隔离级别
  • 什么是隔离级别 ?
    • 并发事务之间相互影响的程度,隔离级别越高影响程度就越低
    • 并发事务会造成的问题
      • 脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
      • 不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
      • 幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读
  • 隔离级别的种类
    • read-uncommitted 读未提交
      • 读数据时不加锁,写数据时加行级共享锁
    • read-committed 读已提交
      • 读数据使用 MVCC,写数据加行级排它锁
    • repeatable-read 可重复读
      • 读数据使用 MVCC,写数据加行级排它锁和 gap、next-key lock
        • 如果是用到了主键的话加锁
    • serializable 串行化
      • 读数据加表级共享锁,写数据加表级排它锁

在 Mysql 的并发控制中我们常常需要使用到 锁 和 MVCC,那么这两者的使用场景有什么区别呢,为什么有了锁还要引入 MVCC 呢?下面我将为大家娓娓道来这两者使用上的区别
基于锁的并发控制
  • LBCC (Lock-Based Concurrent Control) 即基于锁的并发控制
  • Mysql 的锁由 共享锁(读锁)排它锁(写锁) 组成
  • 按粒度也可以分为表锁和行锁
  • 加锁和解锁遵循 2PL两阶段锁原则
  • 2PL就是将加锁/解锁分为两个完全不相交的阶段。加锁阶段:只加锁,不放锁。解锁阶段:只放锁,不加锁
  • 若所有事务均遵守两段锁协议,则这些事务的所有交叉调度都是可串行化1

多版本的并发控制
  • MVCC 即 (Multi-Version Concurrency Control) 多版本的并发控制协议
  • MVCC 最大的好处可以概括为读不加锁,读写不冲突
  • MVCC 并发控制中,读操作可以分成两类:快照读 (snapshot read)当前读 (current read)
    • 快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁
      • 简单的select操作,属于快照读,不加锁。
        • SELECT * FROM user WHERE ?
    • 当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录
      • 特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。
        • 特殊读 (加锁读)
          • SELECT * FROM user WHERE ? LOCK IN SHARE MODE;
        • 插入/更新/删除
          • SELECT * FROM user WHERE ? FOR UPDATE;
          • INSERT INTO user VALUES (…);
          • UPDATE user SET ? WHERE ?;
          • DELETE FROM user WHERE ?;

  1. 当且仅当某组并发事务的交叉调度产生的结果和这些事务的某一串行调度的结果相同,则称这个交叉调度是可串行化 ↩︎

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值