论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
ToB企服应用市场:ToB评测及商务社交产业平台
»
论坛
›
数据库
›
PostgreSQL
›
解决MySQL中的幻读题目
解决MySQL中的幻读题目
我爱普洱茶
金牌会员
|
2024-9-11 12:01:36
|
来自手机
|
显示全部楼层
|
阅读模式
楼主
主题
854
|
帖子
854
|
积分
2562
MySQL 利用InnoDB 存储引擎的默认支持的隔离级别是
REPEATABLE-READ(可重复读),通过MVCC和Next-key锁机制来防止幻读。
解决幻读的方法
1. 快照读
如果是普通的 select 语句
:利用
MVCC(快照读)
。
MVCC依靠利用Read View和聚簇索引纪录中的两个隐藏列工作。
Read View 四个紧张的字段:
creator_trx_id
:指的是
创建该 Read View 的事件的事件 id
。
m_ids
:指的是在创建 Read View 时,当前数据库中「活跃事件」的
事件 id 列表
,注意是一个列表,
“活跃事件”指的就是,启动了但还没提交的事件
。
min_trx_id
:指的是在创建 Read View 时,当前数据库中「活跃事件」中事件
id 最小的事件
,也就是 m_ids 的最小值。
max_trx_id
:这个并不是 m_ids 的最大值,而是
创建 Read View 时当前数据库中应该给下一个事件的 id 值
,也就是全局事件中最大的事件 id 值 + 1;
两个隐藏列
:对于利用 InnoDB 存储引擎的数据库表,它的
聚簇索引纪录中都包罗下面两个隐藏列:
trx_id
:当一个事件对某条聚簇索引纪录进行改动时,就会
把该事件的事件 id 纪录在 trx_id 隐藏列里
;
roll_pointer
:每次对某条聚簇索引纪录进行改动时,都会把旧版本的纪录写入到 undo 日记中,
这个隐藏列是个指针,指向每一个旧版本纪录
,于是就可以通过它找到修改前的纪录。
在事件启动创建 Read View 后,我们可以将纪录中的 trx_id 分别这三种环境:
一个事件去访问纪录的时间,除了自己的更新纪录总是可见之外,另有这几种环境:
如果纪录的
trx_id 值小于 Read View 中的 min_trx_id 值
,表示这个版本的纪录是在创建 Read View 前已经提交的事件天生的,以是该版本的
纪录对当前事件可见
。
如果纪录的
trx_id 值大于即是 Read View 中的 max_trx_id 值
,表示这个版本的纪录是在创建 Read View 后才启动的事件天生的,以是该版本的
纪录对当前事件不可见
。
如果纪录的
trx_id 值在 Read View 的 min_trx_id 和max_trx_id之间(min_trx_id <= trx_id < max_trx_id)
,需要判断 trx_id 是否在 m_ids 列表中:
如果纪录的
trx_id 在 m_ids 列表中
,表示天生该版本纪录的活跃事件依然活跃着(还没提交事件),以是该版本的
纪录对当前事件不可见
。
如果纪录的
trx_id 不在 m_ids列表中
,表示天生该版本纪录的活跃事件已经被提交,以是该版本的
纪录对当前事件可见
。
2. 当前读
如果实行的是下列语句,就是当前读(锁定读)
select ... lock in share mode、select ... for update
insert、update、delete 操纵
在当前读下,读取的是数据的最新版本,当前读会对读取到的纪录加Next-key Lock 锁,来防止其它事件在间隙间插入数据
:
select ... lock in share mode:对纪录加 S 锁,其它事件也可以加S锁,如果加 x 锁则会被壅闭。
select ... for update、insert、update、delete:对纪录加 X 锁,且其它事件不能加任何锁。
只管有以上两种方法,仍然不能完全解决幻读题目,两个发生幻读的场景
:
对于
快照读
, MVCC 并不能完全避免幻读征象。由于当事件 A 更新了一条事件 B 插入的纪录,那么事件 A 前后两次查询的纪录条目就不一样了,以是就发生幻读。
对于
当前读
,如果事件开启后,并没有实行当前读,而是先快照读,然后这期间如果其他事件插入了一条纪录,那么事件后续利用当前读进行查询的时间,就会发现两次查询的纪录条目就不一样了,以是就发生幻读。
T1 时刻:事件 A 先实行「快照读语句」:select * from t_test where id > 100 得到了 3 条纪录。
T2 时刻:事件 B 往插入一个 id= 200 的纪录并提交;
T3 时刻:事件 A 再实行「当前读语句」 select * from t_test where id > 100 for update 就会得到 4 条纪录,此时也发生了幻读征象。
以是,
MySQL 可重复读隔离级别并没有彻底解决幻读,只是很大程度上而不能完全避免幻读征象的发生
。要避免这类特殊场景下发生幻读的征象的话,就是尽量
在开启事件之后,马上实行 select … for update 这类当前读的语句
,由于它会对纪录加 next-key lock,从而避免其他事件插入一条新纪录。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
我爱普洱茶
金牌会员
这个人很懒什么都没写!
楼主热帖
事务
KAFKA EAGLE 监控MRS kafka之操作实践 ...
初学Vue(全家桶)-第16天(vue-router ...
大数据揭秘丨疫情影响下亚马逊女性夹克 ...
OpenHarmony轻量系统开发【1】初始Open ...
如何优雅的备份MySQL数据?看这篇文章 ...
time.sleep(6)!华为AI生成图片发布会 ...
Java 中怎样将 bytes 转换为 long 类型 ...
Welcome to YARP - 8.分布式跟踪
Taurus .Net Core 微服务开源框架:Adm ...
标签云
挺好的
服务器
快速回复
返回顶部
返回列表