不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • MySQL

  • Redis

  • Elasticsearch

  • Kafka

  • Etcd

  • MongoDB

  • TiDB

    • 01.TiDB语法
    • 02.TiDB架构原理 ✅
    • 03.TiDB存储引擎与Raft ✅
    • 04.TiDB MVCC
      • 01.TiDB 中 MVCC 原理
        • 0、概述
        • 1、MVCC 的核心思想
        • 2、快照读与当前读
        • 3、多版本存储结构
        • 4、可见性规则
      • 02.与 MySQL MVCC差异
        • 1、隐藏字段
        • 2、存储结构
        • 3、可见性判断
        • 4、事务模型
      • 03.MVCC 的并发控制流程
        • 1、MySQL 流程
        • 2、TiDB 流程
    • 05.TiDB分布式一致性
  • RabbitMQ

  • 数据库
  • TiDB
xiaonaiqiang
2023-10-15
目录

04.TiDB MVCC常识原理

TiDB 和 MySQL 都使用 MVCC 来实现事务并发控制,但实现方式不同

TiDB 基于分布式架构,使用 RocksDB 和时间戳实现多版本存储,更适合大规模分布式场景

而 MySQL 依赖集中式的 undo log 和隐藏字段(如 DB_TRX_ID)

TiDB 的 MVCC 通过时间戳选择历史版本,无需回滚日志,事务可见性也通过时间戳控制

TiDB 使用 2PC 保证分布式事务一致性,而 MySQL 基于锁机制管理事务并发

# 01.TiDB 中 MVCC 原理

# 0、概述

  • TiDB 和 MySQL 都通过 MVCC 来实现事务并发控制,避免了锁机制对性能的影响
  • 区别在于存储和实现方式:
    • MySQL 使用 undo log 和隐藏字段来管理多版本
    • 而 TiDB 直接通过时间戳和 RocksDB 的多版本存储来实现
  • 分布式架构:
    • TiDB 的 MVCC 是完全分布式的,基于时间戳的并发控制,更适合大规模分布式场景
    • 而 MySQL 仍然是集中式架构下的实现

# 1、MVCC 的核心思想

  • TiDB 使用 MVCC 来实现事务中的乐观并发控制,允许多个事务同时对数据库进行读写操作,避免冲突
  • 每个事务在读取数据时,不会阻塞其他写操作
  • 每次写入操作都会为数据生成一个新的版本,而读取操作则根据事务的时间戳决定读取哪个版本的数据

# 2、快照读与当前读

与 MySQL 类似,TiDB 也分为快照读和当前读

  • 快照读:读取的是数据的某个历史版本,这个版本是基于事务开始时的快照,不需要加锁
  • 当前读:读取的是最新的已提交版本,涉及到增删改操作,可能需要加锁来避免冲突

在 TiDB 中,默认的 SELECT 操作是快照读,而涉及到数据修改的操作(INSERT、UPDATE、DELETE)则是当前读

# 3、多版本存储结构

TiDB 中,每条记录实际上存储多个版本

每个版本包含:

  • Key:表示数据的主键
  • Value:存储每个版本的数据值
  • Timestamp:与每个版本关联的时间戳,由事务管理器(PD)生成的全局递增时间戳

当事务在进行写操作时,会为每次更新生成一个新版本,TiDB 会根据读取时的时间戳选择合适的版本进行返回

这通过快照机制实现了读写分离,避免了直接锁的使用

# 4、可见性规则

TiDB 通过时间戳(TSO)来决定事务读取的可见性

每个事务在开始时会获取一个逻辑时间戳,并使用它来确定哪些版本是可见的

  • 当读取数据时,TiDB 会比较每个版本的时间戳,只读取那些在当前事务开始之前已存在的版本
  • 如果发现该数据有比当前事务时间戳更新的版本,这些更新就会对该事务不可见,事务读取的仍是旧版本的数据

这与 MySQL 的 Read View 类似,用于确保事务读取的数据是符合一致性要求的

# 02.与 MySQL MVCC差异

# 1、隐藏字段

  • MySQL:
    • 在 InnoDB 引擎中,使用隐藏字段如 DB_TRX_ID(记录最近修改该行的事务ID)
    • 和 DB_ROLL_PTR(回滚指针)来实现多版本并发控制
  • TiDB:
    • TiDB 并不直接存储 DB_TRX_ID 等字段,而是通过每次写入数据时附加一个时间戳
    • 这个时间戳是通过 PD(Placement Driver)生成的唯一标识

# 2、存储结构

  • MySQL:
    • 使用 undo log 和 redo log 来管理多版本
    • 在快照读中,MySQL 通过 undo log 回滚到对应的历史版本来实现 MVCC
  • TiDB:
    • 使用 RocksDB 存储引擎,每条数据存储的多个版本会被物理上分布在不同的 TiKV 节点上,数据的历史版本通过时间戳区分
    • TiDB 直接通过时间戳来选择历史版本,而不需要像 MySQL 那样通过 undo log 回滚

# 3、可见性判断

  • MySQL:
    • 通过 Read View 和活跃事务列表来判断某个事务是否可见
    • MySQL 的 Read View 会维护一组当前活动的事务 ID 列表,来决定当前事务能看到哪些版本的数据
  • TiDB:
    • 使用时间戳直接决定事务的可见性
    • 当事务读取数据时,TiDB 会比较该版本的时间戳和当前事务的时间戳,以判断该数据是否对当前事务可见

# 4、事务模型

  • MySQL:
    • InnoDB 使用的是基于锁的事务管理模型
    • 虽然 MVCC 实现了读写并发,但在需要当前读时,仍然会使用锁来保证数据一致性
  • TiDB:
    • TiDB 完全基于分布式事务模型,并使用 2PC(二阶段提交)来保证数据的一致性
    • 在快照读中,不涉及锁机制,而是基于 MVCC 实现的时间戳版本控制

# 03.MVCC 的并发控制流程

# 1、MySQL 流程

  • 事务开启时生成 Read View,记录当前活跃事务列表
  • 对每条读取的数据,判断该数据是否对当前事务可见
    • 如果 DB_TRX_ID 小于或等于 Read View 中的最小事务 ID,则数据可见
    • 如果 DB_TRX_ID 在 Read View 活跃事务列表中,则数据不可见,继续读取 undo log 找到合适版本
  • 对于修改操作,生成新的版本并更新 DB_TRX_ID 和 DB_ROLL_PTR

# 2、TiDB 流程

  • 事务开始时从 PD 获取全局唯一时间戳
  • 读取数据时,TiDB 会选择所有小于当前事务时间戳的版本
    • 每条数据的不同版本根据其时间戳存储在 TiKV 中,读取时直接根据时间戳筛选合适的版本
  • 写操作时,TiDB 会为每次写入数据生成一个新的时间戳,并将新版本存储在 TiKV 中
上次更新: 2024/10/15 16:27:13
03.TiDB存储引擎与Raft ✅
05.TiDB分布式一致性

← 03.TiDB存储引擎与Raft ✅ 05.TiDB分布式一致性→

最近更新
01
04.数组双指针排序_子数组
03-25
02
08.动态规划
03-25
03
06.回溯算法
03-25
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式