白话-MVCC如何工作

MySQL中的MVCC机制主要在以下情况下起作用:

  1. 使用支持MVCC的存储引擎:MVCC主要是MySQL的InnoDB存储引擎中实现并发控制的一种方式,只有当使用InnoDB作为表的存储引擎时,MVCC机制才会生效。

  2. 非串行化事务隔离级别:MVCC在“读已提交(Read Committed)”和“可重复读(Repeatable Read)”这两种事务隔离级别下发挥作用。在“读未提交(Read Uncommitted)”隔离级别下,虽然也可能看到不同事务版本的数据,但这并非严格意义上的MVCC;而在“串行化(Serializable)”隔离级别下,为了保证事务之间的完全隔离,通常会放弃MVCC机制而采用更严格的锁策略。

    • 读已提交(Read Committed):每个查询语句执行前都会获取最新的数据快照,因此同一个事务内前后两次相同的查询可能返回不同的结果。

    • 可重复读(Repeatable Read):这是MySQL的默认事务隔离级别,在这个级别下,事务开始时会获取一个数据快照,并在整个事务期间都基于该快照进行读取操作,这样可以确保事务内的多次相同查询始终得到一致的结果。

  3. 非锁定读操作:MVCC主要针对的是不加锁的SELECT查询,即所谓的“快照读”。对于“当前读”操作,如SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODE以及INSERT、UPDATE、DELETE等写操作,通常不会通过MVCC来提供数据的一致性视图,而是直接应用行级锁或者间隙锁来避免并发问题。

在多个事务共同操作相同数据行时,MVCC(多版本并发控制)机制能够确保事务间的并发访问不会相互阻塞,同时保持事务的隔离性。以下是一个简化的描述:

假设我们有两个事务A和B,它们都在操作同一行数据row1。 

事务A的操作流程:
  • 事务A开始并获取一个事务ID(Transaction ID, trx_id)。
  • 事务A执行查询操作读取row1的数据。InnoDB存储引擎会根据事务A的视图(即当前已提交事务的快照)查找row1对应的时间戳或事务ID来决定哪些版本的数据对事务A可见。
  • 如果事务A需要更新row1,它并不直接覆盖原有数据,而是创建一个新的数据版本,并将这个版本标记为属于事务A的未提交状态。同时,旧版本的数据并不会立即删除,而是保留下来以供其他事务可能需要查看的历史版本。
  • 在事务A提交前,所有对row1的更改只对事务A自身可见;其他事务在此期间读取row1时,看到的是事务A开始之前已经提交的版本。
事务B的操作流程:
  • 同样,事务B开始并获取自己的事务ID。
  • 当事务B尝试读取row1时,它也会基于自己的事务视图去寻找合适的数据版本。
  • 如果事务B是在事务A提交之后开始读取row1,那么它将会看到事务A的最新提交版本(如果事务A已经提交了对row1的更改)。
  • 如果事务B尝试修改row1,即使在事务A还未提交的情况下,由于MVCC的存在,它同样可以进行无冲突的修改,生成新的版本。

通过这种方式,两个事务可以在不互相等待对方释放锁的情况下,独立地进行读写操作。当事务提交后,系统会清理不再需要的旧版本记录,以保证空间的有效利用。

总的来说,在MVCC中,每个事务都像是在操作自己特定版本的数据集,从而避免了传统锁定机制带来的潜在阻塞问题,提高了数据库系统的并发性能。

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JF Coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值