当前位置: 首页 > news >正文

MVCC和日志

MVCC是一种并发控制的方法,在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存

主要是为了提高数据库并发性能,更好的处理读写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读

  • 当前读
    • select lock in share mode(共享锁),select for update;update,insert,delete(排他锁)
    • 读取的是记录的最新版本,读取时要保证其他事务不能修改当前记录,会对读取的记录进行加锁
  • 快照读
    • 不加锁的select操作就是快照读,即不加锁的非阻塞的
    • 前提是隔离级别不是串行级别,串行级别下的快照读回退化为当前读
    • 基于提高并发性能的考虑,快照读的实现是基于多版本并发控制
    • mvcc是行锁的一个变种,在很多情况下,避免可加锁操作,降低开销
    • 基于多版本,即快照读可能读到的并不一定是最新数据版本,可能是历史版本

MVCC多版本并发控制指“维持一个数据的多个版本,使得读写操作没有冲突”的概念

MySQL中快照读就是实现MVCC理想模型其中一个非阻塞读功能,相对而言,当前读就是悲观锁的具体功能实现

快照读本身也是抽象概念。MVCC模型在MySQL中实现由3个隐式字段:undo日志,read view等完成

优势

mvcc是用来解决读-写冲突的无锁并发控制,为事务分配单向长时间的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库快照

  • 在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能
  • 同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题

MVCC+悲观锁:MVCC解决读写冲突,悲观锁解决写写冲突

MVCC+乐观锁:MVCC解决读写重读,乐观锁解决读写冲突

实现原理

Rollback Segments 用来临时保存当数据库发生改变时的先前值

  • 因某种原因或其他用户想要通过ROLLBACK声明取消一个数据操作,数据就会复原到之前改变时的值
    • 只在transaction过程中有效,用户执行COMMIT命令,Rollback Segment里面的值就会标识为失效的,数据改变为永久化
  • 当有并发session访问一个数据值改变但事务还没有提交的表
    • select语句开始读取一个表同时一个事务也在修改这个表值,修改前的值就保存到Rollback Segment中
    • select语句也是从Rollback Segment里读取表的值

隐式字段

  • DB_TRX_ID:6byte,最近修改(update/insert/delete)事务ID;记录创建/最后一次修改该记录的事务ID

  • DB_ROLL_PTR:7byte,回滚指针,指向这条记录的上一个版本(存储在rollback segment中)

  • DB_ROW_ID:6byte,隐含的自增ID(隐藏主键),如果数据表没有主键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引

  • 实际还有一个删除flag隐藏字段,既记录被更新或删除并不代表真的删除,而是删除的flag改变(软删除字段)

img

undo日志

  • insert undo log
    • 代表事务在insert新纪录时产生的undo log
    • 只在事务回滚时需要
    • 在事务提交后立即丢弃
  • update undo log
    • 事务在进行update或delete时产生的undo log
    • 在事务回滚和快照读时需要
    • 不能随便删除,只有在快照读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一删除

purge

  • 实现InnoDB的MVCC机制,更新或删除操作都只是设置老记录的deleted_bit,不是真正将过时的记录删除
    • deleted_bit是一个标志位
    • 当执行删除操作时,并不是将记录从数据页中物理删除,而是将deleted_bit设为1,表示记录被删除
    • 更新操作,会创建一个新的记录版本,并将旧记录的deleted_bit设为1,时旧记录类似删除,新纪录包含更新后数据
  • 节省磁盘空间,有purge线程来清理deleted_bit为true的记录,同时该线程自己维护一个read view
    • 当记录为true并DB_TRX_ID相对purge线程的read view可见,那么记录被安全清除
    • InnoDB中垃圾回收机制,当确认没有事务需要访问deleted_bit为1记录时,才被物理删除
http://www.lryc.cn/news/615850.html

相关文章:

  • Spring Boot整合knife4j实战
  • Mysql笔记-存储过程与存储函数
  • 【C#补全计划】万类之父中的方法
  • 前端开发的奇技淫巧 --- 持续更新中
  • 【Canvas与戳记】黑底金Z字
  • LwIP的内存管理(1)
  • 如何调节天线结构使得两个模式的相位差为90°?如何实现左旋圆极化或右旋圆极化?
  • 软件编程1-shell命令
  • 【话题讨论】GPT-5 发布全解读:参数升级、长上下文与多领域能力提升
  • SpringAi 通过大模型来实现调用自己的Api
  • 基于VuePress2开发文档自部署及嵌入VUE项目
  • vue如何监听localstorage
  • Vue 3 快速入门 第五章
  • vue2升级vue3:单文件组件概述 及常用api
  • Vue.js设计于实现 - 响应式(三)
  • (LeetCode 面试经典 150 题) 104. 二叉树的最大深度 (深度优先搜索dfs)
  • 深入解析微服务分布式事务的原理与优化实践
  • 双非二本如何找工作?
  • CPP继承
  • 40.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--集成网关--初始化网关
  • 【递归、搜索与回溯算法】递归算法
  • 【前端基础】14、CSS设置背景(background相关的)
  • Unity中实现自动寻路
  • 串口通信初始化过程是怎样的???
  • 每日五个pyecharts可视化图表-line:从入门到精通 (2)
  • go语言运算符
  • H3C(基于Comware操作系统)与eNSP平台(模拟华为VRP操作系统)的命令差异
  • GPT OSS深度解析:OpenAI时隔6年的开源模型,AI民主化的新里程碑?
  • 【递归、搜索与回溯算法】深度优先搜索
  • python Flask简单图书管理 API