数据库基础:InnoDB MVCC实现原理图

数据库事物

  • 数据库事物是啥:由有限数据库操作序列构成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位

事物四大特性

  • 原子性(Atomicity)(事物操作要么全部执行,要么全部不执行)
  • 一致性(Consistency)(事物开始前到事物结束后,数据不被破坏)
  • 隔离性(Isolation)(事物之间是相互隔离的,事物不受其他多个事物的影响,多个并发事物需要互相隔离)
  • 持久性(Durability)(事物提交之后,事物对数据库所做操作应该是永久保存)

事物并发问题

  • 脏读:一个事物读取到另一个事物修改过的已提交的数据
  • 幻读:一个事物搜索读取,未提交之前,读取到其他事物insert、delete、update的数据
  • 不可重复读:同一个事物多次读取,读取到不同的数据内容

事物四大隔离级别

  • 读未提交 :只限制两个事物不能同时修改,一个事物修改后,即使未提交,任然能被另一个事物读取到
    • 脏读问题
    • 重复读问题
    • 幻读问题
  • 读已提交 :一个事物只能读取到其他事物已提交的数据,解决脏读
    • 重复读问题
    • 幻读问题
  • 可重复度 :读取数据,其他事物不可进行修改,解决重复读
    • 幻读问题
  • 串行化 :串行化顺序执行,解决脏读、重复度、幻读,加锁实现事物隔离性
    • 频繁加锁,导致数据无法修改,降低数据库性能

多版本并发控制(MVCC)

  • 定义:实现对数据库的并发访问
  • 事物版本号 :数据库自增长事物ID
    • 用来判断事物执行先后顺序
  • 隐式字段
    • trx_id:事物ID,必须的
    • row_id:递增行ID,非必须,6字节,没有主键,非null唯一键出现
    • roll_pointer:回滚指针,指向回滚段undo日志
  • undo_log(回滚日志) :记录数据被修改前的信息
    • delete数据,undo_log会记录insert数据
    • update数据,则记录相反update数据
    • 用途
      • 事物回滚时,保证原子性和一致性
      • 用于MVCC快照读
  • 版本链 :多个事物并行操作某一行数据,该行数据修改会产生多个版本,通过回滚指针(roll_pointer)形成一个链表
    • update user set name ="张三" where id = 1;
    • 1、获取一个事物ID:100
    • 2、修改user表前的数据,拷贝到undo_log
    • 3、修改user表中id为1,将name改成"张三"
    • 4、修改后事物ID:101改成当前版本号,并回滚指针(roll_pointer)指向undo_log日志
  • 快照读、当前读
    • 快照读:读取的是记录数据的可见版本,不加锁
    • 当前读:读取的是记录数据的最新版本,显示加锁
  • Read View :事物执行SQL产生的读视图。
    • 有何用:用来做可见性判断,即判断当前事物可见哪个版本的数据
    • 如何保证可见性:
      • m_ids:未提交的读写事物ID,数据结构是List
      • min_limit_id:生成Read View时,读写事物中最小的事物ID,即m_ids列表中的最小值
      • max_limit_id:生成Read View时,分配给下一个事物ID值
      • creator_trx_id:创建当前Read View的事物ID。
    • 匹配条件规则
      • trx_id<min_limit_id,生成该版本事物在Read View前,可被当前事物访问
      • trx_id>=max_limit_id,生成该版本事物在Read view后,不可被当前事物访问
      • min_limit_id=<trx_id<max_limit_id
        • m_ids包含trx_id,代表Read View生成时刻,事物还未提交,如果数据的trx_id = creator_trx_id,表明数据自己生成,可见
        • m_ids包含trx_id,代表Read View生成时刻,事物还未提交,数据的trx_id != creator_trx_id,表明数据不是自己生成,不可见
        • m_ids不包含trx_id,代表事物在Read View生成前已经提交,修改的结果,可见

MVCC实现原理

  • 查询一条记录,基于MVCC的流程
    • 1、获取事务版本号,即事务ID
    • 2、获取Read View
    • 3、查询得到的数据,跟Read View中的事物版本号进行比较
    • 4、不符合Read View可见性规则,需要对比undo_log中历史快照
    • 5、返回符合规则的数据
相关推荐
黑白极客1 分钟前
用动态的观点看加锁
java·数据库·oracle
Hoxy.R17 分钟前
【每日一错】Oracle 19c CDB中如何启动一个PDB
数据库·oracle
辰_砂20 分钟前
Rockylinux9系统安装KingBaseESV9
数据库
馨羽的玩具22 分钟前
查哪个程序一直登录sql server失败
运维·服务器·数据库
midsummer_woo22 分钟前
基于springboot的编程训练系统设计与实现(源码+论文)
数据库·spring boot·oracle
看天走路吃雪糕44 分钟前
墨者:SQL手工注入漏洞测试(Oracle数据库)
数据库·oracle·sql注入·墨者靶场
GreatSQL社区1 小时前
CTE查询数据量过大导致MySQL 8.0发生CORE问题解析
android·数据库·mysql
格发许可优化管理系统2 小时前
GTSuite许可证性能优化建议
大数据·运维·数据库·安全·性能优化·数据分析
lang201509282 小时前
Apache Ignite 中的分布式 JOIN 操作
数据库·分布式·ignite
字节高级特工2 小时前
【Linux篇】补充:消息队列和systemV信号量
linux·运维·服务器·c语言·数据库