Movatterモバイル変換


[0]ホーム

URL:


MySQL 的 MVCC机制

原创已于 2024-10-15 10:41:28 修改·805 阅读
· 7
· 15·
CC 4.0 BY-SA版权
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
文章标签:

#mysql#数据库

于 2024-09-20 09:31:19 首次发布

MySQL 的 MVCC(多版本并发控制,Multi-Version Concurrency Control)机制是为了在多个事务并发访问时,确保数据一致性,同时尽可能提升数据库的并发性和性能。它主要通过为数据的每个操作保留多个版本,从而避免加锁的竞争,实现高效的并发处理。下面将详细说明 MVCC 的工作原理、事务隔离级别下的表现、回滚日志机制,以及它的优缺点。

1.MVCC 的核心原理

MVCC 的核心是通过数据版本化(versioning)来实现事务的并发控制。每次更新数据时,MySQL 不直接覆盖旧的数据,而是生成一个新版本的记录,这样每个事务可以看到一个与其隔离级别相符合的数据快照

1.1隐藏列

在 InnoDB 存储引擎中,每一行数据都有两个隐藏列:

  • trx_id: 记录最后一次修改该行的事务的 ID。
  • roll_pointer: 指向 Undo Log(回滚日志)的指针。通过该指针,可以找到该行数据的历史版本。
1.2Undo Log(回滚日志)

每当事务修改某行数据时,InnoDB 会将该行数据的旧版本存储在 Undo Log 中。Undo Log 通过roll_pointer 与数据记录相连。当其他事务需要读取数据时,可以通过trx_id 确定它应该看到哪个版本的数据。如果数据已经被修改,那么通过roll_pointer 可以找到该行的旧版本数据。

回滚日志不仅用于 MVCC 读取历史数据,还用于事务回滚操作。当事务回滚时,MySQL 可以利用 Undo Log 将数据恢复到修改前的状态。

1.3版本控制与事务隔离

每个事务都有一个唯一的事务 ID(trx_id),由系统递增分配。事务开始时,它会记录此时数据库中所有已提交数据的快照。在查询时,事务通过与trx_id 的比较来确定应该看到的数据版本:

  • 对于已经提交的事务,事务可以看到它们的最新数据版本。
  • 对于未提交的事务,它只能看到这些事务开始时的快照数据(即历史版本),避免了读取未提交的数据。

2.MVCC 与事务隔离级别

MySQL 提供四种事务隔离级别,它们通过 MVCC 的不同实现来提供一致性和性能之间的权衡。

2.1读未提交(Read Uncommitted)
  • 在读未提交级别,事务可以读取其他事务未提交的数据。这意味着事务可能会读到脏数据(Dirty Read),即读到其他事务已经修改但尚未提交的内容。
  • 在这种隔离级别下,MVCC 机制不会生效,读取操作直接读取当前最新的数据版本,可能产生并发问题。
2.2读已提交(Read Committed)
  • 读已提交级别允许事务只能读取已提交的数据,每次查询都会看到最新的已提交数据版本。这意味着事务不会读到其他事务未提交的数据,避免了脏读。
  • 但不同的查询可能会看到不一致的数据快照,导致不可重复读(Non-repeatable Read)。因为每次查询都可能看到其他事务在此期间提交的新数据版本。

在这个隔离级别,事务在每次执行SELECT 时,都会重新生成一个快照,因此不同查询看到的数据可能不同。

2.3可重复读(Repeatable Read)
  • 可重复读级别确保在同一个事务中,事务的每次查询看到的数据快照是一致的,即使其他事务在期间提交了数据更新,当前事务也不会看到变化的数据。这避免了不可重复读。
  • 该隔离级别通过 MVCC 实现了快照一致性,事务开始时创建一个数据快照,直到事务结束,读操作总是基于这个快照。

此外,InnoDB 的可重复读级别还避免了幻读(Phantom Read)问题,通过 Gap 锁(间隙锁)来避免新插入的数据对查询产生影响。

2.4串行化(Serializable)
  • 在串行化级别,事务之间通过加锁机制完全串行化执行。这是最高级别的隔离,但性能较差,因为每个事务执行时都会锁定相关数据表,阻止其他事务并发操作。
  • 在这个隔离级别下,MVCC 不会发挥作用,所有的读写操作都会加锁,从而实现最强的一致性保证。

3.回滚日志(Undo Log)的作用

Undo Log 是 MVCC 机制的核心,负责存储数据的历史版本,用于支持读操作以及事务回滚。

3.1Undo Log 的生成

每当事务修改数据时,InnoDB 会将数据的旧版本写入 Undo Log,新的数据版本会记录在表的物理存储中。此时,旧版本数据通过roll_pointer 与新版本关联,形成一个链表结构。

3.2Undo Log 的回收

当没有事务需要访问 Undo Log 中的历史版本时,InnoDB 的后台线程会定期清理这些不再需要的日志。这一过程称为Purge,通过回收旧数据版本,避免系统中的存储开销过大。

4.MVCC 的优点和缺点

4.1优点
  1. 高并发性:通过快照读,多个事务可以并发执行读操作,而不需要加锁,减少了读写锁竞争,显著提高并发性能。
  2. 避免锁等待:由于读操作不需要加锁,减少了读写事务之间的锁等待,提高了系统吞吐量。
  3. 一致性保证:在较高的事务隔离级别(如可重复读)下,MVCC 保证了读到的数据的一致性,同时不会牺牲并发性。
4.2缺点
  1. 存储开销:由于需要存储多个版本的数据以及回滚日志,可能会导致存储空间的浪费,尤其是在长时间运行的事务中,旧版本数据占用的空间越来越大。
  2. 回滚日志的管理:回滚日志的生成和清理会增加系统负担,影响数据库的性能。特别是在长事务下,回滚日志可能会变得很大,影响系统的正常运行。
  3. 长事务的影响:如果一个事务持续时间过长,它持有的快照和 Undo Log 会阻止系统清理旧数据版本,导致数据库性能下降。

总结

MySQL 的 MVCC 机制是为了在高并发环境下提高性能和一致性的一种实现方案。它通过维护数据的多个版本和使用回滚日志,实现读写事务的并发操作,避免加锁的性能瓶颈。虽然 MVCC 在大多数场景下能提供高效的事务管理,但也有其局限性,特别是在长事务或大量修改操作的场景下,需要合理的事务管理策略和性能调优。

确定要放弃本次机会?
福利倒计时
::

立减 ¥

普通VIP年卡可用
立即使用
参与评论您还未登录,请先登录后发表或查看评论

博客等级

码龄12年
180
原创
2449
点赞
2150
收藏
1423
粉丝
关注
私信

热门文章

分类专栏

展开全部收起

上一篇:
sychronized
下一篇:
ReentrantLock原理及详细的使用方法

最新评论

大家在看

最新文章

目录

展开全部

收起

目录

展开全部

收起

上一篇:
sychronized
下一篇:
ReentrantLock原理及详细的使用方法

目录

评论
被折叠的  条评论为什么被折叠?到【灌水乐园】发言
查看更多评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

yymagicer

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

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

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

打赏作者

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

抵扣说明:

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

余额充值

[8]ページ先頭

©2009-2025 Movatter.jp