我的编程空间,编程开发者的网络收藏夹
学习永远不晚

mysql事务可重读技术实现 - 学习摘要

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

mysql事务可重读技术实现  - 学习摘要

mysql事务可重读技术实现  - 学习摘要

MySQL中有4个事务隔离级别

MySQL中有4个事务隔离级别:读未提交,读已提交,可重复读和串行化。 事务的四大特性ACID(Atomicity原子性、Consistency一致性、Isolation隔离性、Durability持久性。 隔离级别的设定为数据库服务器的并发,可靠性和性能之间提供了选择。隔离级别越高,性能越低,ACID的完成度越高。 而不同的级别设定,一般带来如下图所列的问题:

可重复读的技术实现

MVCC

Mysql mvcc行更新过程: https://yq.aliyun.com/articles/283418?spm=a2c4e.11153940.0.0.4b3224eb4hoiqb。 重点: 每个事务做update的时候,copy原始数据到undo log中,然后会修改DB_TRX_ID为当前事务ID,及修改数据本身,如果存在更老版本的数据会更新回滚指针DB_ROLL_PTR。 MVCC只解决了阻塞读的问题,事务以排他锁的形式修改原始数据。

Innodb的实现真算不上MVCC ,因为并没有实现核心的多版本共存,undo log中的内容只是串行化的结果,记录了多个事务的过程,不属于多版本共存。但理想的MVCC是难以实现的,当事务仅修改一行记录使用理想的MVCC模式是没有问题的,可以通过比较版本号进行回滚;但当事务影响到多行数据时,理想的MVCC据无能为力了。 多行数据修改时, 会遇到2pc相同的问题。多行数据的情况下, 会遇到部分失败下,无法完美回滚。

Read View

read view其实就是一个保存事务ID的list列表。记录的是本事务执行时,MySQL还有哪些事务在执行。readview是记录的当前活跃的事务列表。 因为undo log链表中,存在过时的事务log, 需要等待purge线程定期清理。 而readview可以快速响应用户的read request,副本中保存的是系统当前不应该被本事务看到的其他事务id列表。当用户在这个事务中要读取该行记录的时候,innodb就会从根据 read view,来决定是读取该行记录的当前版本,还是需要从undo-log中去寻找更早的版本。 大致过程是: 根据readview中up_id 和low_id判断,如cur_id>up_id,可以读取, cur_id

  • Read Repeatable对应的是在每个事务启动的时候创建 一个Read View。每个事务生成一个read view。
  • Read Commit对应的是每次执行SQL statement时候创建。 每条只读语句生成一个Read View。
  • Read view创建之后,读数据时比较记录最后更新的trx_id和view的high/low water mark和读写事务数组即可判断可见性。

回滚段

(之前网上摘抄部分博客, 没记录原文地址. 原作者看到有问题联系我) 在undo log中记录的老版本的数据。 但一个长事务,需要读取老版本的数据时,需要顺着undo log链表找到老版本的数据。(查找条件是什么?DB_ROLL_PTR指针进入到undo log 的链表中) undo log存储在ibdata表空间中,或者独立的undo tablespace中。

  • Undo log <— undo slot. 每个回滚段的段头页中维护1024个slot。 因此mysql默认支持96 * 1024个普通事务。
  • 记录的DB_ROLL_PTR指向最近一次更新所创建的回滚段;每条undo log也会指向更早版本的undo log,从而形成一条更新链。通过这个更新链,不同事务可以找到其对应版本的undo log,组成old version记录,这条链就是记录的history list。
  • 在innodb中,创建一个新事务的时候,innodb会将当前系统中的活跃事务列表(trx_sys->trx_list)创建一个副本(read view),副本中保存的是系统当前不应该被本事务看到的其他事务id列表。当用户在这个事务中要读取该行记录的时候,innodb会将该行当前的版本号与该read view进行比较。 具体的算法如下:
  1. 设该行的当前事务id为trx_id_0,read view中最早的事务id为trx_id_1, 最迟的事务id为trx_id_2。
  2. 如果trx_id_0< trx_id_1的话,那么表明该行记录所在的事务已经在本次新事务创建之前就提交了,所以该行记录的当前值是可见的。跳到步骤6.
  3. 如果trx_id_0>trx_id_2的话,那么表明该行记录所在的事务在本次新事务创建之后才开启,所以该行记录的当前值不可见.跳到步骤5。
  4. 如果trx_id_1<=trx_id_0<=trx_id_2, 那么表明该行记录所在事务在本次新事务创建的时候处于活动状态,从trx_id_1到trx_id_2进行遍历,如果trx_id_0等于他们之中的某个事务id的话,那么不可见。跳到步骤5.
  5. 从该行记录的DB_ROLL_PTR指针所指向的回滚段中取出最新的undo-log的版本号,将它赋值该trx_id_0,然后跳到步骤2.

大事务带来的影响

定义:运行时间比较长,操作的数据比较多的事务 2.大事务风险: a)锁定太多的数据,造成大量的阻塞和锁超时,回滚所需要的时间比较长。 b)执行时间长,容易造成主从延迟 3.如何处理大事务 a)避免一次处理太多大数据 b)移出不必要在事务中的select操作

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

mysql事务可重读技术实现 - 学习摘要

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

mysql事务可重读技术实现 - 学习摘要

MySQL中有4个事务隔离级别MySQL中有4个事务隔离级别:读未提交,读已提交,可重复读和串行化。 事务的四大特性ACID(Atomicity原子性、Consistency一致性、Isolation隔离性、Durability持久性。 隔离级别的设定为数据库
mysql事务可重读技术实现  - 学习摘要
2014-12-13

MySQL脏读幻读不可重复读及事务的隔离级别和MVCC、LBCC实现

目录前言事务因并发出现的问题有哪些 脏读不可重复读幻读不可重复读与幻读的区别事务的四个隔离级别InnoDB默认的隔离级别是RRRead UnCommited 读未提交 RURead Commited 读已提交 RCRepeatable Re
2022-07-11

编程热搜

目录