瑞安网站开发,申请网站域名多少钱,网页制作设计课设报告,wordpress 酒在MySQL中#xff0c;MVCC#xff08;多版本并发控制#xff09;是InnoDB存储引擎使用的并发控制机制。它提供对数据的并发访问#xff0c;并确保多用户环境中数据的一致性和隔离性。
InnoDB通过“Undo log”存储每条记录的多个版本#xff0c;提供历史记录供读取#x…在MySQL中MVCC多版本并发控制是InnoDB存储引擎使用的并发控制机制。它提供对数据的并发访问并确保多用户环境中数据的一致性和隔离性。
InnoDB通过“Undo log”存储每条记录的多个版本提供历史记录供读取并允许不同的事务访问不同的数据版本。在事务期间客户端只能看到当前事务开始之前提交的记录以及当前事务内所做的修改。MVCC的具体实现还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView。
隔离级别
MySQL中有4种隔离级别
READ UNCOMMITED
当前事务可以读取未提交的数据。这些数据可能会回滚所以我们将未提交的数据称为脏数据这种问题称为脏读。
READ COMMITED
当前事务确实可以读取已提交的数据因此不存在脏读问题。但是如果当前事务多次读取同一条记录则可能检索到不同的数据。这是因为在当前事务期间可能有其他事务修改并提交了该记录。此问题称为不可重复读。
REPETABLE READ
事务多次读取特定的记录集即使其他事务在事务过程中修改或提交对这些记录的更改它也始终会获得这些记录的相同值。但是如果我们在当前事务中多次执行“SELECT COUNT(*) FROM {table_name}”我们可能会看到不同的结果这个问题称为幻读。
REPEATABLE READ 是 MySQL InnoDB 中的默认隔离级别。
SERIALIZABLE
所有事务都强制排序解决了脏读、不可重复读、幻读等问题。但Serialized隔离级别性能较差因此在实际中很少使用。
MVCC 仅适用于 READ COMMITTED 和 REPEATABLE READ 隔离级别因为 READ UNCOMMITTED 始终读取最新记录而 SERIALIZABLE 会为其读取的所有记录添加锁。
概念
TRANSACTION ID
当一个新的事务开始时它会得到一个自增的事务ID通过它InnoDB可以知道每个事务的执行顺序。
隐藏列
InnoDB中的每条记录都有两个隐藏列“db_trx_id”和“db_roll_pointer”如果表中没有主键或非空唯一键InnoDB将生成一个隐藏的自增列“db_row_id”。
字段名称描述db_trx_id记录操作该行的事务的事务iddb_roll_pointerundo指针指向该行的undo日志
InnoDB 在撤消日志中记录“插入”、“更新”和“删除”操作。然而对于“删除”操作InnoDB实际上将其记录为“更新”操作即通常所说的“软删除”。InnoDB 不是物理删除该行而是更新“已删除标志”来指示该行已被逻辑删除。此方法允许检索该行的先前版本如果该行被永久删除则无法检索先前版本。
当前读
一些 SQL 语句例如“SELECT * ... LOCK IN SHARE MODE(共享锁)”、“SELECT * ... FOR UPDATE(独占锁)”、“UPDATE”、“DELETE”和“INSERT” 考虑当前的读取操作。这些操作读取该行的最新版本。在读取过程中InnoDB通过对当前记录加锁来确保没有其他事务可以修改当前记录。
快照读
没有加锁的 SELECT 语句被视为快照读取操作通过 MVCC 读取所需的版本。快照读取无锁有效提升事务性能。
本质上快照是一种以空间换取时间的方式。
Undo log
Undo log存储修改行的先前版本。在行被修改之前InnoDB会将当前版本复制到Undo log中Undo log具有以下功能 如果事务回滚InnoDB可以找到以前的版本来恢复。 如果当前版本对于当前事务不可见则会通过undo log查找可见版本。
前面提到InnoDB将删除操作记录为更新操作因此Undo Log中只有两种操作 Insert undo log由insert操作产生仅用于事务回滚事务提交后可立即丢弃。 更新undo log由更新操作生成不仅用于事务回滚还用于快照读取。
版本链
当多个事务同时操作同一条记录时每个事务都会生成一个新的版本这些版本通过 db_roll_pointer 形成一个链表称为版本链。 Read View
ReadView是事务执行快照读取时生成的记录快照。
读取视图存储当前事务开始之前的所有活动事务。有 4 个重要属性 trx_ids活动事务ID不包括当前事务和已提交事务。 low_limit_id分配的下一个交易ID。 up_limit_idtrx_ids中的最小交易id如果trx_ids为空则up_limit_id等于low_limit_id。 Creator_trx_id生成读取视图的事务ID。
以下规则用于检查记录是否对当前事务可见 如果访问版本的事务IDcreator_trx_id则表示当前事务访问了自己修改过的记录则该版本对当前事务可见。 如果访问版本的事务ID up_limit_id则说明生成该版本的事务在当前事务生成ReadView之前已经提交因此该版本可以被当前事务访问。 如果访问版本的事务ID low_limit_id 值则说明生成该版本的事务是在当前事务生成ReadView之后打开的因此当前事务无法访问该版本。 如果访问版本的事务ID在up_limit_id和m_low_limit_id之间则需要判断该版本的事务ID是否在trx_ids列表中。如果是说明该版本生成的事务在ReadView创建时仍然处于活动状态该版本无法访问。 如果没有说明创建ReadView时生成该版本的事务已经提交可以访问该版本。
MVCC实现原理
了解了上面的概念后MVCC的实现就很好理解了。
查询流程 获取交易自己的交易ID称为trx_id。这不是在 SELECT 语句期间获得的而是在事务开始时获得的即执行 BEGIN 时获得的。 检索 ReadView仅在 SELECT 语句期间生成。 在数据库表中如果找到数据则将其与ReadView中的事务版本号进行比较。4、如果不符合ReadView的可见性规则则需要Undo Log中的历史快照直到返回符合规则的数据。
InnoDB通过ReadView和Undo Log的结合来实现MVCC。Undo Log 存储历史快照而 ReadView 的可见性规则有助于确定当前版本数据的可见性。