MySQL深入浅出

  1. MySQL版本特征
  2. Schema与数据类型优化
    1. 原则
    2. Schema设计中的陷阱
    3. 数据类型
      1. 整数类型
      2. 实数类型
      3. 字符串类型
      4. BLOB和TEXT类型
      5. 枚举ENUM
      6. 日期和时间
      7. 位数据类型
      8. 选择标识符(主键)
        1. 整数类型
        2. 字符串类型
        3. 类型
        4. 问题
    4. 范式和反范式
      1. 范式
      2. 反范式
      3. 混用
      4. 汇总表
        1. 适用场景
      5. 缓存表
        1. 适用场景
    5. 加快ALTER TABLE操作的速度
      1. 注意修改列的区别
      2. 不会重建表的情况
  3. 高性能索引
    1. 索引基础、类型
      1. B-tree
        1. 类型
          1. MyISAM
          2. InnoDB
        2. 适用类型
        3. 限制
      2. 哈希索引
        1. 限制
        2. InnoDB “自适应哈希索引”
      3. 空间索引R-Tree
      4. 全文索引
    2. 索引的优点
    3. 如何评价一个索引
    4. 高性能的索引策略
      1. 独立的列
      2. 前缀索引和索引选择性
      3. 联合索引
        1. 选择合适的索引列顺序
      4. 聚簇索引
        1. 优点
        2. 缺点
        3. 叶子节点
        4. UUID插入的问题
        5. 顺序主键什么时候会造成更坏的结果
      5. 覆盖索引
      6. 使用索引扫描来做排序
        1. 可以使用使用索引做排序的查询
        2. 不能使用索引做排序的查询
      7. 压缩索引
        1. MyISAM压缩索引(空间换时间)
      8. 关于冗余和重复索引
        1. 重复索引(去除)
        2. 冗余索引(适当)
      9. 未使用索引
      10. 索引和锁的关系
    5. 维护索引和表
      1. 找到损坏的表
      2. 更新索引统计信息
      3. 减少索引和数据碎片
        1. 常见的碎片
        2. 解决方法
        3. 存储引擎实现
    6. 索引总结
      1. 原则
      2. 如何判断索引合理
        1. 检查设计是否合理
        2. 判断执行是否符合预期
  4. 查询性能优化
    1. 为什么查询会慢
      1. 执行任务
      2. 时间花费
    2. 慢查询的基础:优化数据访问
      1. 是否检索大量超过需要的数据
      2. 分析为何检索大量超过需要的行
        1. 相关指标指标
          1. 响应时间
          2. 扫描行数
          3. 返回行数
        2. WHERE条件
        3. 优化
    3. 重构查询方式
      1. 分解关联查询
    4. 查询执行的基础
      1. 一次SQL查询做了什么
      2. MySQL客户端/服务器通信协议
        1. 通信协议
        2. 通信过程
        3. 查询状态
      3. 查询缓存(Query Cache)
      4. 查询优化处理
        1. 语法解析器和预处理
          1. 解析器
          2. 预处理器
        2. 查询优化器
          1. 基于成本的优化器
          2. 导致选择错误执行计划的原因
          3. 优化策略
          4. 能够处理的优化类型
          5. 数据和索引的统计信息
          6. MySQL如何执行关联查询
          7. 执行计划
          8. 关联查询优化器
          9. 排序优化
      5. 查询执行引擎
      6. 返回结果给客户端
    5. 查询优化器的局限
    6. 优化特定类型的查询
      1. 优化COUNT查询
      2. 优化关联查询
  5. Mysql 日志
  6. mysql锁
  7. 详细架构 存储
  8. 写流程
  9. mvcc实现原理

image-20190604220256224

MySQL版本特征

  • 2001 , 3.23

    • 诞生, MyISAM代替ISAM ,引入全文索引和复制
  • 2003 , 4.0

    • 新语法的支持 UNION、多表DELETE语法
    • 复制优化 , 两个线程来实现复制
    • InnoDB成为标准配备 行级锁、外键
    • 查询缓存
  • 2005 , 4.1

    • 新语法支持 子查询、INSERT ON DUPLICATE KEY UPDATE
    • 支持UTF-8字符集
    • 支持新的二级协议和prepared语句
  • 2006 , 5.0

    • 企业级特征 视图、触发器、存储过程、函数
  • 2008 , 5.1

    • 分区
    • 基于行复制
    • plugin API
  • 2010 , 5.5

    • InnoDB成为默认引擎
    • 半同步插件
    • 线程池
  • 2013, 5.7

    • JSON支持
  • 2016, 8.0

    https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html


Schema与数据类型优化

原则

  • 最小的通常更好 占用更少的磁盘、内存和CPU缓存

  • 简单就好 简单数据类型的操作通常需要更少的CPU周期

  • 尽量避免NULL

    NULL columns require additional space in the row to record whether their values are NULL.
    For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte

Schema设计中的陷阱

  • 太多的列

  • 从行缓冲中将编码过的列转换成行数据结构的操作代价非常的高

  • 太多的关联

  • 限制 最多只能61张表,经验法则单个查询最好在12个表以内

  • 过度枚举

  • NULL

数据类型

整数类型

  • TINYINT(8)

  • SMALLINT(16)

  • MEDIUMINT(32)

  • INT(64)

  • BIGINT(128)

    属性 UNSIGNED、宽度

实数类型

  • FLOAT
  • DOUBLE
  • DECIMAL

字符串类型

  • VARCHAR
    • 需要使用1或2个额外字节记录字符串的长度,会保留末尾空格
    • 字符串列的最大长度比平均长度大很多,列的更新很少,碎片少

  • CHAR
    • 适合存储很短的字符串,或者所有值都接近同一个长度,会删除末尾空格
    • 经常变更的数据

BLOB和TEXT类型

  • BLOB 二进制

  • TEXT 字符方式存储

    当值太大时候,InnoDB会使用专门的“外部”存储区域进行存储,行内存储指针

枚举ENUM

  • 优势

    存储枚举非常紧凑
    在列表中保存为整数,在表.frm文件中保存”数字-字符串”映射关系表

  • 劣势

    字符串列表是固定的,修改必须使用ALTER TABLE

日期和时间

  • DATETIME

    存储范围 从1001年到9999年、精度为秒 ,格式 YYYYMMDDHHMMSS、使用8个字节、与时区无关

  • TIMESTAMP

    存储范围 从1970到2038年、保存了从1970年以来的秒数 和UNIX时间戳相同、只使用4个字节、和时区有关

    如果需要保存更小粒度的时间,可以使用BIGINT存储

位数据类型

​ BIT、SET( 不常用 )

选择标识符(主键)

整数类型

​ 很快,并且可以使用AUTO_INCREMENT

字符串类型

​ 消耗空间、比较计算速度慢

类型
  • MD5 SHA1
  • UUID 分布不均,但有一定顺序

问题
  • INSERT变慢
    • 磁盘随机访问
    • 页分裂
    • 磁盘碎片
  • SELECT变慢
    • 随机I/O
    • 导致缓存效果差

范式和反范式

范式

​ 是什么 :每个数据会出现并且只有一次
​ 优点
​ 更新操作比反范式快
​ 修改更少数据
​ 更少的DISTINCT或者GROUP BY
​ 缺点
​ 需要表关联
​ 分散了索引

反范式

​ 是什么
​ 信息是冗余的,可能会存储在多个地方
​ 优点
​ 不需要表关联,数据比内存大时,有时候全表扫描会更快,避免了随机I/O
​ 更有效的索引策略
​ 缺点
​ 对应范式的优点

混用

​ 最常见的反范式化数据的方法
​ 复制
​ 缓存
​ 高效获取,排序的需要

​ ——>其实这种类型的建议使用redis

汇总表

保存使用GROUP BY语句聚合数据的表、逻辑上非冗余

适用场景

​ 准实时数据
​ 局部热点
​ 最活跃用户
​ 最常见标签

缓存表

来存储可以比较简单从schema表获取的、逻辑上冗余

适用场景

​ 查询语句需要特殊的表和索引结构
​ 适用不同的存储引擎,适用MyISAM做全文搜索

加快ALTER TABLE操作的速度

注意修改列的区别

​ 如MODIFY COLUMN ,会引起表重建 ALTER COLUMN,会直接修改.frm文件

不会重建表的情况

​ 移除一个列的AUTO_INCREMENT属性
​ 增加、移除,或更改ENUM和SET常量

​ MYSQL会在没必要的时候也重建表 , 为想要的表结构创建一个新的.frm文件,然后用它替换掉已经存在的那张表的.frm文件


高性能索引

索引基础、类型

B-tree

类型
MyISAM

​ 通过物理位置引用被索引的行

  • 优点

          使用前缀压缩技术,索引更小
          存储物理位置(指针),空间占用更少
    
  • 缺点

          物理位置变化,需要修改二级索引指针地址
    
InnoDB

​ 根据主键引用被索引的行

  • 优点

      数据位置变换时,不需要修改二级索引
      额外拥有主键,不需要回表
    
  • 缺点

      占用内存空间多
    
适用类型
  • 全值匹配
  • 匹配最左前缀
  • 匹配列前缀
  • 匹配范围值
  • 精确匹配某一列并范围匹配另外一列
  • 只访问索引的查询
限制
  • 不按照最左列开始查找,无法适用索引
  • 不能跳过索引的列
  • 如果查询某个列的范围查询,其右边的所有列都无法使用索引优化

哈希索引

只有Memory引擎显示支持(如果在InnoDB创建时指定索引类型,会自动转换为b-tree)

优点 命中快

限制
  • 不能通过索引来避免读取行
  • 不是顺序存储,无法用于排序
  • 不支持部分索引列查找
  • 只能支持等值比较查询
  • 哈希冲突
InnoDB “自适应哈希索引”

​ 某些索引值被使用非常频繁时,会在内存中基于B-Tree索引上再创建哈希索引,这样让B-Tree也具有哈希索引的一些优点

空间索引R-Tree

​ GIS支持并不完善

全文索引

适用于MATCH AGAINST ,可以使用 Elastic Search

索引的优点

  • 大大减少了服务器需要扫描的数据量
  • 帮助服务器避免排序和临时表
  • 将随机I/O变为顺序I/O

如何评价一个索引

一星 索引将相关的记录放到一起
二星 索引中的数据顺序和查找中的排列顺序一致
三星 索引中的列包含了查询中需要的全部列

高性能的索引策略

​ 索引的作用 ,一般用于快速检索数据,通常还用于排序,限制重复数据

独立的列

​ 是指所有列不能是表达式的一部分,也不能是函数的参数

前缀索引和索引选择性

​ 不重复的索引值和数据表的记录总数的比值,如何计算合适的前缀长度就是关键
类型

  • BLOB
  • TEXT
  • VARCHAR

前缀索引的问题无法使用GROUP BY、ORDER BY

联合索引

一定程度上可以使用表上的多个单列索引来定位指定的行

img

如图所示:

  1. 先根据Alice索引查找到所有Alice的叶子节点
  2. 然后根据clo2进行排序

因此查找的时候,想走clo3和clo2的联合索引就得有clo3,单单依靠clo2是没有办法去走联合索引的。

最左匹配原则的成因:

1.Mysql创建联合索引是首先会对最左边,也就是第一个索引字段进行排序

2.在第一个排序的基础上,再对第二个索引字段进行排序,其实就像是实现了Order by字段1,再Order by 字段2这样一种排序规则

3.所以第一个字段是绝对有序的,而第二个字段就是无序的了

4.因此通常情况下,直接使用第二个字段进行条件判断是用不到索引的。这就是为什么mysql要强调最左匹配原则的成因。

选择合适的索引列顺序

将选择性最高的列放再所有的最前列,在不考虑分组和排序时

聚簇索引

如果没有定义主键,会选择一个唯一的非空索引代替,如果没有,则会隐式定义一个主键来作为聚簇索引

优点
  • 可以把相关数据保存在一起,只需从磁盘读取很少的数据页
  • 数据访问更快,索引和数据保存在同一个B-Tree
  • 使用覆盖索引扫描的查询可以直接使用页节点中的主键值
缺点
  • 最大限度提高I/O密集型应用性能,但是如果数据全部加载在内存中,顺序就没那么重要了
  • 插入速度依赖插入顺序,按照主键顺序插入最快
  • 更新索引代价很高,会将更新的行移动到新位置
  • 页分裂,导致占用更多空间
  • 可能导致全表扫描变慢,行稀疏,或页分裂导致数据存储不连续
  • 二级索引包含主键,占用空间可能会很大
  • 二级索引需要两次查找,自适应哈希
叶子节点
  • 主键值
  • 事务ID
  • 用于事务和MVCC的回滚指针
  • 非主键列
UUID插入的问题

​ 写入的目标页可能已经被刷到磁盘上并从缓存中移除,或者还没有加载到缓存,插入之前不得不先从磁盘读取目标页到内存

写入乱序,频繁分裂页,导致大量的移动操作和空间占用

页分裂会导致页变得稀疏并被不规则填充,会有碎片

必要使用OPTIMIZE TABLE 重建表(删除并不会回收数据存储空间,以及索引位,会锁表),和优化页的填充

顺序主键什么时候会造成更坏的结果

并发插入导致间隙锁竞争、AUTO_INCREMENT锁机制

覆盖索引

img

​ 如果索引不能覆盖查询的全部列,那就不得不每扫描一条索引记录就都回表查询一次对应的行,通常比顺序地全表扫描慢

所以,使用覆盖索引有以下好处

  • 索引条目小于数据行大小,减少数据量访问

  • 无需回表,顺序I/O

  • 对于MyISAM内存中只缓存索引,数据依赖操作系统缓存,访问数据需要系统调用

优化index condition pushdown(ICP) , 发送查询数据到引擎层

使用索引扫描来做排序

可以使用使用索引做排序的查询

​ 只有当索引的列顺序和ORDER BY字句的顺序完全一致,并且所有列的排序方向都一样,才能使用索引对结果做排序
​ 如果关联表,则只有当ORDER BY字句引用的字段全部为第一个表时,才能使用索引做排序

不能使用索引做排序的查询

​ 使用不同排序方向
​ OREDR BY子句引用了一个不在索引的列
​ WHERE 和 OREDR BY中的列无法组成索引的最左前缀
​ 第一个列上是范围条件,无法使用索引其他列

压缩索引

MyISAM压缩索引(空间换时间)

​ 压缩块使用更少的空间 十分之一 存在的问题, 操作更慢 无法使用二分查找

关于冗余和重复索引

重复索引(去除)
冗余索引(适当)

​ 应该尽量扩展已有的索引而不是创建新索引(冗余)
​ 需要使用新索引的场景
​ 避免已有索引变大
​ 排序、分组需要

未使用索引

​ 有可能是唯一约束,用于避免重复数据

索引和锁的关系

​ 索引能够减少锁的数量,InnoDB只有在访问行的时候才会对其加锁
​ 相关细节(InnoDB) 二级索引共享锁、主键索引排他锁

维护索引和表

找到损坏的表

​ CHECK TABLE

更新索引统计信息

innoDB 5.5 随机索引访问进行评估并存储在内存中
基数(Cardinality)
​ SHOW INDEX FROM
​ 存储引擎估算索引列有多少个不同的取值

减少索引和数据碎片

常见的碎片
  • 碎片, 数据行被存储在多个地方,多个片段中
  • 行碎片, 逻辑上顺序的页或者行,在磁盘上不是顺序存储
  • 剩余空间碎片,数据页存在大量剩余空间(删除会导致这种问题)
解决方法
  • OPTIMIZE TABLE(锁表)
  • 导出再导入
存储引擎实现
  • InnoDB 通过删除、再添加索引功能
  • MyISAM 通过排序算法重建索引消除碎片

索引总结

原则

  • 单行访问效率低
  • 顺序访问范围数据快

顺序IO、无需排序操作

  • 覆盖索引,无需回表,避免单行访问

如何判断索引合理

检查设计是否合理
  • schema , 数据结构是否合理
  • SQL语句是否存在问题
  • 索引设计是否合理
判断执行是否符合预期
  • 是否扫描了太多的行
  • 是否做了很多额外排序
  • 使用了临时表
  • 随机I/O
  • 太多回表查询

查询性能优化

为什么查询会慢

执行任务

  • 消除无用子任务

  • 减少子任务查询次数

  • 加快子任务查询速度

时间花费

  • 网络
  • CPU计算
  • 生成统计信息和执行计划
  • 锁等待

慢查询的基础:优化数据访问

是否检索大量超过需要的数据

  • 查询不需要的记录
  • 多表关联时返回全部的列
  • 总是取出全部列
  • 查询重复的数据

分析为何检索大量超过需要的行

相关指标指标
响应时间
  • 服务时间
  • 排队时间
扫描行数
  • 全表扫描
  • 索引扫描
  • 范围扫描
  • 唯一索引扫描
  • 常数引用
返回行数

扫描的行数对返回的行数的比率 通常1:1到1:10之间

WHERE条件
  • 在索引中使用WHERE条件过滤不匹配记录,存储引擎层
  • 使用索引覆盖查询,直接从索引中过滤不需要的记录并返回命中结果,服务层,无需回表
  • 从数据表中返回,然后过滤不满足条件的记录,服务层
优化
  • 索引覆盖

  • 改变库表结果

  • 使用汇总表

  • 重写查询

重构查询方式

​ 一个复杂查询还是多个简单查询,减少锁的占有时间

分解关联查询

​ 让缓存效率更高
​ 执行单个查询可以减少锁的竞争
​ 在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和可扩展
​ 可以减少冗余记录的查询
​ 哈希关联,而不是嵌套循环关联

查询执行的基础

一次SQL查询做了什么

​ 简单来说就是, 先查询缓存,在再根据查询优化器解析成执行计划,交给执行引擎,最后将结果返回给客户端

更多可以参考另一篇文章中详细的介绍

MySQL客户端/服务器通信协议

通信协议

​ 半双工,只能一方发送消息,简单快速,但缺少流量控制,全部推送完成才释放链接

通信过程
  1. 客户端用一个单独的数据包将查询传给服务器,max_allowed_packet
  2. 服务器返回多个数据包,必须完整接收
  3. 多数连接MySQL的库函数都可以获得全部结果集并缓存到内存里
查询状态
  • Sleep
  • Query
  • Locked
  • Analyzing and statistics
  • Copying to tmp table[on disk]
  • Sorting result
  • Sending data

查询缓存(Query Cache)

​ 解析一个查询语句之前如果查询缓存是打开的,通过一个对大小写敏感的哈希查找实现的,缓存命中率

查询优化处理

​ 将一个SQL转换成执行计划,再按照执行计划和存储引擎进行交互

语法解析器和预处理

​ 通过关键字将SQL语句进行解析,并生成一颗对应的‘解析树’

解析器

​ 使用语法规则验证和解析查询

预处理器

​ 根据一些MySQL规则进一步解析树是否合法,验证权限(例如检查数据表和列是否存在,解析名字和别名)

查询优化器
基于成本的优化器

​ 尝试预测一个查询使用了某种执行计划时的成本,并选择其中成本最小的一个

导致选择错误执行计划的原因
  • 统计信息不准确
  • 执行计划汇总的成本估算不等同于实际执行的成本
  • 最优是基于成本,而有些时候并不是最快
  • 不考虑其他并发执行的查询
  • 并不是任何时候都基于成本的优化,有时会基于一些固定的规则
  • 不会考虑不受其控制的操作成本
优化策略

​ 静态优化 编译时优化,直接对解析树进行分析,并完成优化
​ 动态优化 和查询的上下文有关,每次查询都重新评估

能够处理的优化类型
  • 重新定义关联表的顺序
  • 将外连接转换成内连接
  • 使用等价变换规则
  • 优化COUNT() MIN() MAX()
  • 预估并转化为常数表达式
  • 覆盖索引扫描
  • 子查询优化
  • 提前终止查询
  • 等值传播
  • 列表IN()的比较
数据和索引的统计信息

​ 存储引擎提供给优化器

  • 每个表或者索引有多少个页面
  • 每个表的每个索引的基数是多少
  • 数据行和索引长度
  • 索引的分布信息
MySQL如何执行关联查询

​ 策略 对任何关联都执行嵌套循环关联操作
​ 泳道图

执行计划

​ 左侧深度优先的指令树

关联查询优化器

​ 通过评估不同顺序时的成本来选择一个代价最小的关联顺序
​ 当关联表超过optimizer_search_depth的限制选择‘贪婪’搜索模式

排序优化

排序算法

  • 两次传输排序

    • 读取行指针和需要排序的字段,对其进行排序
    • 再根据排序结果读取所要的数据行
  • 单次传输排序

    读取所需要的所有列,排序,直接返回排序结果

对于关联排序
如果关联操作中ORDER BY子句中所有列都来自关联的第一个表,则处理关联第一个表的时候就进行文件排序

否则,都会将关联结果存放到一个临时表,然后所有关联结束后,再进行文件排序

查询执行引擎

​ 根据执行计划给出的指令执行,调用存储引擎实现的接口来完成,查询中的每一个表由一个handler的实例表示
如果是所有存储引擎共有的特性则由服务器层实现

返回结果给客户端

不需要结果集,则返回影响到的行数, 如果查询缓存开启,将结果存放到查询缓存中

是一个增量、逐步的过程,服务器端无需存储太多的结果,客户端第一时间获得返回结果

  1. 每一行都以一个满足MySQL客户端/服务器端通信协议的封包发送
  2. 在通过TCP协议进行传输
  3. 可能会缓存封包,并批量传输

查询优化器的局限

  • 关联子查询
  • UNION的限制
  • 索引合并优化
  • 等值传递
  • 并行执行
  • 哈希关联
  • 松散索引扫描
  • 最大值和最小值的优化
  • 在同一个表上查询和更新

hint, 不建议使用,MySQL版本升级会让新版的优化策略失效

优化特定类型的查询

优化COUNT查询

count(*)>count(1)>count(id)>count(xxx)

  • 使用相似值 EXPLAIN出来的优化器估算的行数
  • 覆盖索引
  • 增加汇总表
  • 缓存

优化关联查询

​ 只需要在关联顺序中的第二个表的相应列上创建索引,确保任何的GROUP BY 和 ORDER BY中的表达式只涉及到一个表中的列
优化子查询
优化GROUP BY 和 DISTINCT
​优化GROUP BY WITH ROLLUP (转移到应用程序中处理)

参考:

高性能MySQL

Mysql 日志

https://www.cnblogs.com/wy123/p/8365234.html

mysql锁

https://tech.meituan.com/2014/08/20/innodb-lock.html

详细架构 存储

https://juejin.im/post/5d42f48cf265da03ab422e08

存储相关删除相关

1、drop table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM ;

2、truncate table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM 。truncate table其实有点类似于drop table 然后creat,只不过这个create table 的过程做了优化,比如表结构文件之前已经有了等等。所以速度上应该是接近drop table的速度;

3、delete from table_name删除表的全部数据,对于MyISAM 会立刻释放磁盘空间 (应该是做了特别处理,也比较合理),InnoDB 不会释放磁盘空间;

4、对于delete from table_name where xxx带条件的删除, 不管是innodb还是MyISAM都不会释放磁盘空间;

5、delete操作以后使用optimize table table_name 会立刻释放磁盘空间。不管是innodb还是myisam 。所以要想达到释放磁盘空间的目的,delete以后执行optimize table 操作。

6、delete from表以后虽然未释放磁盘空间,但是下次插入数据的时候,仍然可以使用这部分空间。

存储引擎

两种存储引擎的对比:从MyISAM和InnoDB的存储文件可看出,MyISAM注重的是对数据的快速读取,但由于MyISAM不支持事务,同时缺乏灵活性。而InnoDB支持事务和行级锁,因此在5.1之后MySQL的默认存储引擎为InnoDB。

写流程

事务ACID

https://blog.csdn.net/tangkund3218/article/details/47361705

logbuffer ->redolog (持久性保证)

 然后会通过以下三种方式将innodb日志缓冲区的日志刷新到磁盘
  1,Master Thread 每秒一次执行刷新Innodb_log_buffer到redolog。
  2,每个事务提交时会将Innodb_log_buffer刷新到redolog。
  3,当重做日志缓存可用空间 少于一半时,Innodb_log_buffer被刷新到redolog

Poolbuffer 脏数据

binlog

Redolog bingo 生成之后才能保证事务成功

undolog(原子性和一致性)

事务开始之前,将当前是的版本生成undo log,undo 也会产生 redo 来保证undo log的可靠性

保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读

隔离 其实就是几个级别 read uncommit\ unrepeat\r r\ serial

mvcc实现原理

https://www.jianshu.com/p/f692d4f8a53e

1、事务版本号

2、表的隐藏列。

3、undo log

4、 read view

https://zhuanlan.zhihu.com/p/52977862


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 951488791@qq.com

文章标题:MySQL深入浅出

字数:5.8k

本文作者:zhengyumin

发布时间:2019-06-04, 22:02:31

最后更新:2020-08-14, 13:00:28

原始链接:http://zyumin.github.io/2019/06/04/Overview_MySQL/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。