扫码订阅《 》或入驻星球,即可阅读文章!

GOLANG ROADMAP

阅读模式

  • 沉浸
  • 自动
  • 日常
首页
Go友会
  • 城市
  • 校园
Go学院
  • Go小课
  • Go小考
  • Go实战
  • 精品课
Go求职
  • 求职辅导🔥
  • Offer收割社群
  • 企业题库
  • 面试宝典
Go宝典
  • 在线宝典
  • B站精选
  • 推荐图书
  • 每日博文
Go仓库
实验区
  • Go周边
  • Go下载
  • Go月刊
消息
更多
  • 用户中心

    • 我的信息
    • 推广返利
  • 玩转星球

    • 星球介绍
    • 角色体系
    • 星主权益
  • 支持与服务

    • 联系星主
    • 成长记录
    • 常见问题
    • 吐槽专区
  • 合作交流

    • 渠道合作
    • 课程入驻
    • 友情链接
author-avatar

GOLANG ROADMAP


首页
Go友会
  • 城市
  • 校园
Go学院
  • Go小课
  • Go小考
  • Go实战
  • 精品课
Go求职
  • 求职辅导🔥
  • Offer收割社群
  • 企业题库
  • 面试宝典
Go宝典
  • 在线宝典
  • B站精选
  • 推荐图书
  • 每日博文
Go仓库
实验区
  • Go周边
  • Go下载
  • Go月刊
消息
更多
  • 用户中心

    • 我的信息
    • 推广返利
  • 玩转星球

    • 星球介绍
    • 角色体系
    • 星主权益
  • 支持与服务

    • 联系星主
    • 成长记录
    • 常见问题
    • 吐槽专区
  • 合作交流

    • 渠道合作
    • 课程入驻
    • 友情链接
  • 面试宝典系列

    • MySQL面试题汇总
  • 宝典内容

    • 1.主键 超键 候选键 外键是什么?
    • 2.数据库事务的四个特性及含义?
    • 3.视图的作用,视图可以更改么?
    • 4.drop,delete与truncate的区别?
    • 5.索引的工作原理及其种类?
    • 6.连接的种类?
    • 7.数据库范式?
    • 8.数据库优化的思路?
    • 9.存储过程与触发器的区别
    • 10.解释 SQL 的 left join 和 right join?
    • 11.Mysql索引用的是什么算法?
    • 12.Mysql的存储引擎?
    • 13.Mysql事务隔离级别
    • 14.Mysql高可用方案有哪些?
    • 15.Mysql中utf8和utf8mb4区别?
    • 16.Mysql中乐观锁和悲观锁区别?
    • 17.Mysql索引主要是哪些?
    • 18.Mysql联合索引最左匹配原则?
    • 19.聚簇索引和非聚簇索引区别?
    • 20.如何查询一个字段是否命中了索引?
    • 21.Mysql中查询数据什么情况下不会命中索引?
    • 22.Mysql中的MVCC是什么?
    • 23.Mvcc和Redolog和Undolog以及Binlog有什么不同?
    • 24.Mysql读写分离以及主从同步?
    • 25.InnoDB的关键特性?
    • 26.Mysql如何保证一致性和持久性?
    • 27.为什么选择B+树作为索引结构?
    • 28.InnoDB的行锁模式?
    • 29.哈希(hash)比树(tree)更快,索引结构为什么要设计成树型?
    • 30.为什么索引的key长度不能太长?
    • 31.Mysql的数据如何恢复到任意时间点?
    • 32.Mysql为什么加了索引可以加快查询?
    • 33.Explain命令有什么用?

扫码订阅《 》或入驻星球,即可阅读文章!

22.Mysql中的MVCC是什么?


GOLANG ROADMAP
Mysql中的MVCC是什么?

数据库并发控制——锁, Multiversion (version) concurrency control (MCC or MVCC) 多版本并发控制 ,它是数据库管理系统一种常见的并发控制。

并发控制常用的是锁,当线程要对一个共享资源进行操作的时候,加锁是一种非常简单粗暴的方法(事务开始时给 DQL 加读锁,给 DML 加写锁),这种锁是一种 悲观 的实现方式,也就是说这会给其他事务造成堵塞,从而影响数据库性能。

其中在数据库中最常见的就是悲观锁和乐观锁:

  • 悲观锁

当一个线程需要对共享资源进行操作的时候,首先对共享资源进行加锁,当该线程持有该资源的锁的时候,其他线程对该资源进行操作的时候会被阻塞.

  • 乐观锁

当一个线程需要对一个共享资源进行操作的时候,不对它进行加锁,而是在操作完成之后进行判断。 比如乐观锁会通过一个版本号控制,如果操作完成后通过版本号进行判断在该线程操作过程中是否有其他线程已经对该共享资源进行操作了,如果有则通知操作失败,如果没有则操作成功,当然除了版本号还有CAS,如果不了解的可以去学习一下,这里不做过多涉及。

MVCC的两种读形式:

  • 快照读

读取的只是当前事务的可见版本,不用加锁。而你只要记住 简单的 select操作就是快照读(select * from table where id = xxx)。

  • 当前读

读取的是当前版本,比如 特殊的读操作,更新/插入/删除操作.

比如:

 select * from table where xxx lock in share mode,
 select * from table where xxx for update,
 update table set....
 insert into table (xxx,xxx) values (xxx,xxx)
 delete from table where id = xxx
1
2
3
4
5

MVCC的实现原理:

MVCC 使用了“三个隐藏字段”来实现版本并发控制,MySQL在创建建表的时候 innoDB 创建的真正的三个隐藏列吧。

RowID DB_TRX_ID DB_ROLL_PTR id name password
自动创建的id 事务id 回滚指针 id name password
  • RowID:隐藏的自增ID,当建表没有指定主键,InnoDB会使用该RowID创建一个聚簇索引。

  • DB_TRX_ID:最近修改(更新/删除/插入)该记录的事务ID。

  • DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本。

其实还有一个删除的flag字段,用来判断该行记录是否已经被删除。

而 MVCC 使用的是其中的 事务字段,回滚指针字段,是否删除字段。

我们来看一下现在的表格(isDelete是我自己取的,按照官方说法是在一行开头的content里面,这里其实位置无所谓,你只要知道有就行了)。

isDelete DB_TRX_ID DB_ROLL_PTR id name password
true/false 事务id 回滚指针 id name password