北京代做网站,花店o2o的特色,1688网站,wordpress文件填写目录 1. MySQL中的并发问题2. 数据库的隔离级别3. MVCC#xff08;多版本并发控制#xff09;机制3.1 MVCC的实现原理3.2 Read View详解3.3 当前读与快照读 4. MVCC在不同隔离级别下的工作方式5. MVCC解决幻读问题6. MVCC的优缺点优点#xff1a;缺点#xff1a; 7. MVCC在… 目录 1. MySQL中的并发问题2. 数据库的隔离级别3. MVCC多版本并发控制机制3.1 MVCC的实现原理3.2 Read View详解3.3 当前读与快照读 4. MVCC在不同隔离级别下的工作方式5. MVCC解决幻读问题6. MVCC的优缺点优点缺点 7. MVCC在实际应用中的注意事项 1. MySQL中的并发问题
在多用户数据库系统中并发操作是不可避免的。然而并发操作可能会导致一些问题主要包括 脏读一个事务读取了另一个未提交事务修改过的数据: A事务读取B事务修改后的数据返回然而B事务发生了回滚 不可重复读在同一事务内多次读取同一数据返回的结果有所不同
A事务多次读取同一个数据B事务修改了该数据A事务读到的数据不一样 幻读在同一事务内多次查询返回的结果集不一致
A事务多次读取某些数据比如查询表的数据总数B事务插入或者删除了数据A读取的数据数量发生了变更像幻觉一样 注意区分幻读和不可重复读
为了解决这些问题数据库系统引入了事务隔离级别的概念。
2. 数据库的隔离级别
SQL标准定义了四种隔离级别从低到高分别是
读未提交Read Uncommitted读已提交Read Committed可重复读Repeatable Read串行化Serializable
让我们用一个图表来展示这些隔离级别如何解决并发问题
MySQL的InnoDB存储引擎默认使用**可重复读Repeatable Read**隔离级别。他引入了MVCC来解决这个不可重复读的问题读已提交也有MVCC两者之间只是创建快照的时机不同后面再提
3. MVCC多版本并发控制机制
MVCC是MySQL InnoDB存储引擎用于提高并发性能的一种机制。它的核心思想是 保存数据在某个时间点的快照形成一个版本链使得事务可以看到在事务开始时数据的一致性视图。 3.1 MVCC的实现原理
InnoDB的MVCC主要通过以下几个部分来实现 隐藏列每行数据都有两个隐藏列 DB_TRX_ID最后一次插入或更新该行的事务IDDB_ROLL_PTR回滚指针指向该行的上一个版本存储在undo log中 Undo Log保存了数据被修改前的旧值用于回滚和MVCC的数据读取。可以认为undo log存储数据的历史版本通过指针会形成一个版本链。 Read View事务进行快照读操作时产生的读视图用于判断当前事务能够看到哪个版本的数据。
让我们用一个图表来展示MVCC的基本结构
3.2 Read View详解
Read View是MVCC实现的核心它包含以下重要信息
m_ids活跃事务列表在生成Read View时活跃的读写事务ID列表就是记录当前还未提交的事务列表m_low_limit_id/(m_min_limit_id)活跃事务的最小事务id就是活跃列表的最小值m_up_limit_id/(m_max_limit_id)下一个事务应该被分配的事务idm_creator_trx_id生成该Read View的事务ID
注意事务id是递增分配的
当一个事务要读取一行数据时InnoDB会将该行的DB_TRX_ID前面提到的表示这行数据最近一次发生修改的事务id与Read View中的信息进行比较以决定是否可以看到该版本的数据 1. DB_TRX_ID m_creator_trx_id:当前读取的事务就是创建快照读的事务说明就是该事务最近修改了这条数据因此是可读的 2. DB_TRX_ID m_low_limit_id:当这条数据最新更改的事务id小于最小活跃事务id就说明该事务id是已经提交的事务id该条数据就可读 3. DB_TRX_ID m_up_limit_id这条数据的最新记录是在快照建立之后执行的显然属于不可读根据回滚指针找到合适的历史版本数据进行返回 4. m_low_limit_id DB_TRX_ID m_up_limit_id:这条数据最新更改的事务id在最小活跃事务id和最大事务id下一次分配的事务id之间那就需要去扫描活跃事务列表判断是否有这个id存在
有就说明该数据还没有被提交是不可读的那么他就会根据DB_ROLL_PTR去找到该数据的历史版本同样会进行判断直至找到符合可读条件的数据返回如果列表没有就表明该事务已经被提交了就是可读的 3.3 当前读与快照读
在InnoDB中我们有两种读取数据的方式 当前读Current Read 读取的是记录的最新版本会对读取的记录进行加锁常见的当前读操作SELECT ... FOR UPDATE, SELECT ... LOCK IN SHARE MODE, UPDATE, DELETE等 快照读Snapshot Read 读取的是记录的快照版本不会对读取的记录进行加锁常见的快照读操作不带锁的SELECT
让我们用一个图表来说明当前读和快照读的区别 4. MVCC在不同隔离级别下的工作方式
MVCC主要工作在读已提交和可重复读这两个隔离级别下 读已提交 每次读取数据前都会生成一个新的Read View能看到其他事务已经提交的修改 可重复读 在事务开始时生成一个Read View并在整个事务过程中使用这个Read View保证在同一事务中多次读取数据时结果一致
让我们用一个例子来说明这两种隔离级别下MVCC的工作方式 5. MVCC解决幻读问题
虽然MVCC可以有效解决不可重复读问题但对于幻读它只能提供部分解决方案。在可重复读隔离级别下MVCC可以防止快照读出现幻读但无法完全阻止当前读的幻读问题。
为了进一步解决幻读问题InnoDB引入了Next-Key Lock临键锁机制它是记录锁Record Lock和间隙锁Gap Lock的组合。
Next-Key Lock不仅锁定查询涉及的索引记录还锁定这些记录之间的间隙有效防止了其他事务在查询范围内插入新记录从而解决了幻读问题。
6. MVCC的优缺点
优点
提高并发性允许读写并发读操作不会阻塞写操作写操作也不会阻塞读操作。解决一致性问题提供了一致性的数据视图避免了脏读和不可重复读问题。降低锁竞争通过版本链和快照读减少了锁的使用范围从而提高了系统的整体性能。支持时间点查询可以查询某个时间点的历史数据对于某些应用场景非常有用。
缺点
存储开销需要额外的存储空间来保存多个版本的数据。复杂性实现和维护MVCC机制相对复杂增加了数据库系统的复杂度。清理问题需要定期清理无用的历史版本否则可能导致存储空间的浪费。事务大小限制长事务可能会导致版本链过长影响性能。
7. MVCC在实际应用中的注意事项
合理设置隔离级别根据应用需求选择适当的隔离级别避免过度使用高隔离级别带来的性能开销。控制事务大小尽量使用短事务避免长事务导致的版本链过长问题。定期维护对于频繁更新的表需要定期进行维护操作如优化表结构、清理无用的历史版本等。索引优化合理设计索引可以提高MVCC的效率减少不必要的版本链遍历。监控与调优定期监控系统性能关注MVCC相关的指标如undo log的大小、长事务的数量等及时进行调优。