哪些网站自己做宣传,网站兼容性,wordpress做博客,建筑网片厂家Mysql是如何实现隔离性的#xff1f;#xff08;锁MVCC#xff09;
隔离性是指一个事务内部的操作以及操作的数据对正在进行的其他事务是隔离的#xff0c;并发执行的各个事务之间不能相互干扰。隔离性可以防止多个事务并发执行时#xff0c;可能存在交叉执行导致数据的不…Mysql是如何实现隔离性的锁MVCC
隔离性是指一个事务内部的操作以及操作的数据对正在进行的其他事务是隔离的并发执行的各个事务之间不能相互干扰。隔离性可以防止多个事务并发执行时可能存在交叉执行导致数据的不一致。
MySQL 对隔离性的保证主要有两个方面
--用锁机制来保证一个事务写操作对另一个事务写操作的隔离性
---用 MVCC 机制来保证一个事务写操作对另一个事务读操作的隔离性。
MySQL 中按照锁的粒度可以分为全局锁表锁和行锁。
全局锁会使整个数据库处于只读状态在做全库逻辑备份时经常用到。表级锁在操作数据时会锁定整张表并发性能一般而行锁可以做到只锁定需要操作的记录行并发性能很好。但是由于加锁本身需要消耗资源因此某些在锁定数据较多的情况下可以使用表锁来减少开销。
MVCC 主要解决的是读写冲突的问题它是由 undo log read view 实现的。其中 undo log 可以为每条记录保存多个历史版本MySQL 在执行快照读的时候会根据事务的 read view 里的信息顺着 undo log 的版本链找到满足可见性的记录。 MVCC-Multi-Version Concurrency Control 多版本并发控制
是指维护一个数据的多个版本使得读写操作没有冲突快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现还需要依赖于数据库记录中的三个隐藏字段、undo log日志、readView。
数据库记录中的三个(两个)隐藏字段 undo log日志 多个事务 提交事务之后undo log不会立即删除.原因是有活动的事务,正在用到这个undo log,结合ReadView..
undo log版本链:
在不同事务/相同事务对同一记录进行修改修改过程中会记录 该记录的undo log日志。会导致该记录的uodo log生成一条记录版本链表。链表的头部是最新的旧记录尾部是最早的旧记录!undo log日志中记录了当前记录(行数据)的历史版本。 查询时应该返回哪一个版本呢?? 具体返回哪个版本要取决于MVCC实现原理中的readview ReadView读视图
ReadView 是 快照读 SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务未提交的id。 版本链数据访问规则 不同的隔离级别生成ReadView的时机不同 - RC: 在事务每次快照读的时候都会产生一个新的ReadView....里面维护着当前活动的事务ID - RR: 在事务第一次快照读的时候会产生一个新的ReadView后续的每次快照读都会复用第一个ReadView..里面维护着当前活动的事务ID 这是造成 不可重复读 和 幻读的本质原因 RC隔离级别下 每次快照读的时候会从当前记录的最新版本开始和ReadView中的字段通过版本链数据访问规则开始对比。如果符合就返回当前 版本记录如果不符合就按照版本链的链表往下继续做对比直到找到符合规则的那个版本返回。。 因为RC读已提交隔离级别下每次快照读都是新的ReadView所以维护的活动事务ID集合m_ids都可能不一样所以会有不可重复读的现象出现问题根源 比如上图一次快照读是{3,4,5}一次快照读是{4,5} RR隔离级别下 第一次快照读会产生一个ReadView分别记录四个属性接下来第二个快照读的时候不会再生成一个ReadView了 直接复用第一个所以匹配规则也都 一样在undo log版本链中查找时查出来的数据 也都一样这就保证了 可重复读 所以MVCC-- 它的主要作用就是在 快照读 的时候决定我们提取的到底是哪一个版本
总结
扩展
1、当前读 当前读就是读取到的是最新的数据通过select .. lock in share mode共享锁实现或通过select ...for update、update、insert、delete排它锁等实现! 2、快照读 3、在InnoDB存储引擎下的RR隔离级别下
快照读会使用MVCC. (select * ... 普通sql语句)当前读会采用Next-Key-Lock,是行锁 间隙锁的方式来处理(锁机制). (select ..lock in share mode/for ..update update insert delete)
4、 RR级别下 快照读 使用了MVCC一定能避免幻读吗? - 能但不完全能 - 因为MVCC并不是采用锁的方式完全的对事务数据进行了隔离而是通过版本控制变相的实现了解决幻读的功能 特例当两次快照读之间存在当前读ReadView会重新生成会导致产生幻读。 MVCC在快照读的情况下可以解决幻读问题但是在当前读的情况下是不能解决幻读的 5、RR可重复读隔离下为什么会产生幻读
在可重复读隔离级别下普通的查询是快照读是不会看到别的事务插入的数据的因为复用同一个 ReadView。因此幻读在 当前读 下才会出现。 SELECT * FROM player LOCK IN SHARE MODE;
SELECT * FROM player FOR UPDATE;
INSERT INTO player values ...
DELETE FROM player WHERE ...
UPDATE player SET ... 6、什么是幻读在可重复读的数据隔离级别下在同一个事务中使用当前读读到了其他事务新插入的数据的现象叫做幻读。这里有几个定语可重复读的事务隔离级别当前读插入的新数据。只有在这些定语的约束下才能形成幻读。
我们知道可重复读的数据隔离级别下一个事务无法查询到另外一个事务对数据表进行的变更不过这个结论的前提是这个查询是一个普通查询也就是快照读如果查询的方式是当前读(select * from table for update)那么就可以查询到另外一个事务的变更结果的。但是幻读的定义对变更又做了更严格的限制幻读只仅仅针对 insert 的变更而对 update 的变更虽然查询也可以感知到但这不会被称为幻读。虽然这里说的有点啰嗦但是幻读的定义就是那么严格所以我要多强调一遍。
我们在使用MVCC的时候一般是根据业务场景选择组合搭配乐观锁或悲观锁。
MVCC用来解决读写冲突问题乐观锁或者悲观锁用来解决写和写的冲突。从而最大程度的提高数据库的并发性 。