我们专注攀枝花网站设计 攀枝花网站制作 攀枝花网站建设
成都网站建设公司服务热线:400-028-6601

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

MYSQL事务与MVCC-创新互联

Mysql事务的基本要素(ACID)

A:原子性:要么全部成功,要么全部失败

创新互联是专业的延平网站建设公司,延平接单;提供网站设计制作、成都网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行延平网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

C:一致性:事务开始前和结束后,数据库的完整性约束没有被破坏(保证数据的正确性)
I:隔离性:一个事务的执行影响另一个事务的运行

D:持久性:更新后的数据会永久的留存在数据库中

所有要素最终都是为了数据一致性

事务并发产生的问题

多事务并发有三种异常情况,违反了隔离性

  1. 脏读:一个事务读取到了另一个事务未提交的数据
  2. 不可重复读:一个事务中同一查询语句执行多次,存在一个记录却有两个不同的内容(一个事务做查询操作,另一个事务做更新操作)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9sFKat5Q-1672131122002)(https://secure2.wostatic.cn/static/hahJ1s8CWfjc17RS78NDqi/image.png?auth_key=1672130992-5yqaLQjdc89F9p4BTztdVq-0-fbd3e3401a0f2f2540dfbd2d4b3830e4)]  [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-phbQcSW0-1672131201314)(https://secure2.wostatic.cn/static/hahJ1s8CWfjc17RS78NDqi/image.png?auth_key=1672130992-5yqaLQjdc89F9p4BTztdVq-0-fbd3e3401a0f2f2540dfbd2d4b3830e4)]3. 第二类更新丢失(两个事务对同一条数据都在做更新操作)
    在这里插入图片描述

4.幻读:一个事务中同一查询语句的记录条数不一致(A事务做查询操作,B事务做新增操作)
在这里插入图片描述

在这里插入图片描述

幻读不不可重复读的区别(一个是由更新导致,一个是由新增或删除导致)

数据库是如何保证事务的隔离性的呢?

数据库可以通过加锁来保证事务的隔离性。但是加锁后性能问题影响过大。MYSQL使用MVCC解决脏读,不可重复读,幻读问题

MySQL的锁类型

SQL标准定义的隔离级别
  1. 未提交读:
  2. 已提交读:解决脏读问题
  3. 可重复读:解决不可重复度问题(mysql默认隔离级别)
  4. 序列化:解决幻读问题

MYSQL通过锁和MVCC实现以上隔离级别

MVCC原理(多版本并发控制)

MVCC是在并发访问数据库时,通过对数据做多版本管理,避免因为写数据时要加写锁而阻塞读取数据的请求,造成写数据时无法读取数据的问题。。MVCC解决的更多的是如何读的问题。并不能取代数据库的锁和数据不能和数据库中的锁混为一谈。当多个事务对数据资源做出并发修改时还是需要锁的控制

MVCC核心概念

了解MVCC之前我们需要知道以下概念

1. 事务版本号
每次事务开启前都会从数据库获得一个自增长的事务ID,可以从事务ID判断事务的执行先后顺序
2. 表格中的隐藏列
对于InnoDB存储引擎,每一行记录都有两个隐藏列**trx_id**(事务版本号)、**roll_pointer**(回滚指针,roll_pointer存储的是旧数据的地址),如果表中没有主键和非NULL唯一键时,则还会有第三个隐藏的主键列**row_id**。
3. Undo log
用于记录数据被修改前的信息

作用:
  - 当事务回滚的时候通过此日志还原数据
  - 通过读取undo log的历史版本数据可以实现**不同事务版本号都拥有自己独立的快照数据版本。**
4.版本链
多个事务并行操作某一行数据时,不同事务对该行数据的修改会产生多个版本,然后通过回滚指针(roll_pointer),连成一个链表,这个链表就称为**版本链**

在这里插入图片描述

详细介绍:

在这里插入图片描述

5. ReadView
它就是事务执行SQL语句时,产生的读视图。实际上在innodb中,每个SQL语句执行前都会得到一个Read View。它主要是用来做可见性判断的,即判断当前事务可见哪个版本的数据

在innodb 中每个事务开启后都会得到一个read_view。副本主要保存了当前数据库系统中正处于活跃(没有commit)的事务的ID号

**Read view 的几个重要属性:**
trx_ids: 当前系统活跃(未提交)事务版本号集合
low_limit_id: 创建当前read view 时“当前系统大事务版本号+1”
up_limit_id: 创建当前read view 时“系统正处于活跃事务最小版本号”
creator_trx_id: 创建当前read view的事务版本号
**Read view**可见性判断

1. 若事务ID< up_limit_id  || 事务ID=creator_trx_id 则显示

    表明read view产生后,事务就已经commit
2. 若事务ID ≥ low_limit_id 则不显示

    表明read view产生后事务才开始。不能显示
3. up_limit_id≤事务ID
通过ReadView、版本链、undo log来返回快照读数据

核心:判断版本链中的那个版本是当前事务是否可见来返回数据
在这里插入图片描述

MVCC实现已提交读
RC级别下事务开启后,在每次执行快照读时生成ReadView,根据**Read view可见性判断**和**版本链undo log**返回结果
MVCC实现可重复读
RR级别下事务开启后,只在第一次快照读时生成ReadView,根据**Read view可见性判断**和**版本链undo log**返回结果
快照读和当前读
快照读:只有select单纯的读取操作,会在读取的时候生成ReadView快照数据

当前读:读取的是最新版本,并且对数据加锁,会阻塞其他操作修改记录。比如select……lock in share mod(加共享锁,又称S锁),select……for update(加排它锁,又称X锁),update,delete,insert这类操作都是当前读
MVCC 在RR级别下 可以解决部分幻读
MVCC 在RR级别下 可以解决部分幻读, 但不能完全解决.

Mysql官方给出的幻读解释是:

只要在一个事务中,第二次select多出了row就算幻读。

1. a事务先select,b事务 insert确实会加一个gap锁,但是如果b事务commit,这个gap锁就会释放(释放后a事务可以随意dml操作)。
2. a事务再select出来的结果在MVCC下还和第一次select一样;这一步没有出现幻读。
3. 接着a事务不加条件地update,这个update会作用在所有行上(b事务已经提交,包括b事务新加的)。
4. a事务再次 select就会出现b事务中的新行(幻读出现),并且这个新行已经被 update修改了。

参考链接:https://zhuanlan.zhihu.com/p/421769708
https://zhuanlan.zhihu.com/p/52977862

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


当前标题:MYSQL事务与MVCC-创新互联
网站链接:http://shouzuofang.com/article/cdhsis.html