数据库基础: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、返回符合规则的数据
相关推荐
MXsoft6181 分钟前
监控易对各类服务器硬件的广泛支持和深入监控能力
大数据·数据库·信息可视化
就改了11 分钟前
MySQL进阶——DQL语句日常优化建议(详细版!)
数据库·sql·mysql
Elastic 中国社区官方博客1 小时前
拆解 “ES 已死“ 伪命题:Agentic RAG 时代搜索引擎的终极形态
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
懒大王爱吃狼2 小时前
Python + Qt Designer构建多界面GUI应用程序:Python如何调用多个界面文件
开发语言·数据库·python·qt·mysql·python基础·命令模式
梦尘啊2 小时前
存储引擎详解:LSM-Tree与B+树比较
数据库·后端
jay丿2 小时前
Django 集成 Redis 数据库指南
数据库·redis·django
用户4099322502122 小时前
FastAPI性能优化指南:参数解析与惰性加载
前端·数据库·后端
boJIke4 小时前
分库分表与NewSQL数据库的区别及适用场景
数据库·new sql
Moshow郑锴4 小时前
基于SpringBoot3+Druid数据库连接池与外部PostgreSQL的Kubernetes Pod YAML全解析
数据库·容器·kubernetes