TiDB-从0到1-MVCC

2024-05-29 13:04
文章标签 tidb mvcc

本文主要是介绍TiDB-从0到1-MVCC,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
TiDB从0到1系列

  • TiDB-从0到1-体系结构
  • TiDB-从0到1-分布式存储
  • TiDB-从0到1-分布式事务
  • TiDB-从0到1-MVCC

一、MVCC

Multi-Version Concurrency Control 多版本并发控制,其主要解决了读并发的问题。
其维持一个数据的多个版本使读写操作没有冲突。也就是说数据元素X上的每一个写操作产生X的一个新版本,为X的每一个读操作选择一个版本。由于消除了数据库中数据元素读和写操作的冲突,从而具有更好的性能。特别是对于数据库读和写两种方法,他们不用等待其他同时进行的相同数据写和读的完成。在并发事务中,数据库写只等待正在对同一行数据进行更新的写,这是现有的行级锁的弱点。同时MVCC回收不需要的和长时间不用的内存,防止内存空间的浪费。

在传统关系型数据库中,MVCC的实现方式通常还与事务的隔离级别有关。如MySQL中

  • RC隔离级别下,事务中可以立即读取到其他事务commit过的readview数据(通过redo产生最新的read view)
  • RR级别下,事务中从第一次查询开始,生成一个一致性readview,直到事务结束(通过undo历史链表)

二、TiDB中的MVCC

通过判断列簇中是否有主锁决定是否要读历史版本数据。

1、场景

假设test表中现在有三行数据

id:1,name:Tom
id:2,name:Andy
id:4,name:Tony

事务一:

Begin(start_ts=100)
update test set name='Jack' where id=1;
update test set name='Candy' where id=2;
Commit;(commit_ts=110)

事务二:

Begin(start_ts=115)
update test set name='Tim' where id=1;
update test set name='Jerry' where id=4;
未执行Commit;

此时TSO来到120,并分别读取test表中id=1、2、4的数据,TiDB内部是如何处理的呢?

2、数据存储逻辑

首先来看下目前TiKV中数据、锁是什么样了
在这里插入图片描述

可以看到,在默认列簇中存储的是最新的Commit过的数据。
而写列簇中记录了这些数据的start_ts和commit_ts以及主键信息。
在锁列簇中记录了所有(当前、之前)的锁信息。

3、读取数据(id=1)

读取id=1的数据行 (从又向左,依次读取写列簇、锁列簇、默认列簇)
首先在写列簇中找到id=1的最新一条数据,这里主要目的是拿到id=1数据最后一次操作的两个TSO (可能id=1的有很多,之前说过,TiDB中数据的更新都是以插入的形式存在)
接着去锁列簇中看是否有id=1的相关锁信息:发现确实有一条,在start_ts=115时加的主锁,但是没有锁释放的数据,说明start_ts=115的事务还没有提交。这里也符合我们设立的场景(事务二未提交)。
当找到start_ts=115且没有提交锁信息,最后去默认列簇中找到TSO在115以前,id=1的最新数据 (再次强调可能id=1的有很多,因为TiDB中数据的更新都是以插入的形式存在)
最终读取到id=1的数据,name=Jack。
结果符合预期。
在这里插入图片描述

4、读取数据(id=2)

首先在写列簇中找到id=2的最新一条数据的两个TSO;
接着去锁列簇中看是否有id=2的相关锁信息:发现并没有。
所以直接去默认列簇中找到start_ts=100的id=2的数据即可.
最终读取到id=2的数据,name=Candy。
结果符合预期。
在这里插入图片描述

5、读取数据(id=4)

首先在写列簇中找到id=4的最新一条数据;
接着去锁列簇中看是否有id=4的相关锁信息:发现确实有一条,在start_ts=115时加的跟随锁,但是没有锁释放的数据,说明start_ts=115的事务还没有提交。这里也符合我们设立的场景(事务二未提交)。
当找到start_ts=115且没有提交锁信息,最后去默认列簇中找到TSO在115以前,id=4的最新数据
最终读取到id=4的数据,name=Tony。
结果符合预期。
在这里插入图片描述

彩蛋

TiDB以三个逻辑列簇+TSO版本号的方式实现了MVCC可以说非常的巧妙,但是带来的一大问题就是在高并发读写时可能存在历史版本堆积的情况,从而导致读写变慢。这时就需要控制好GC的时间来保证性能。

在这里插入图片描述

这篇关于TiDB-从0到1-MVCC的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1013715

相关文章

【笔记】事务隔离级别以及MVCC解决幻读

事务提交可能碰到的问题: (1)脏读:事务1对数据进行修改但还没提交,事务2读取修改后的数据,之后事务1执行错误,回滚了,此时事务2的数据是错误的脏数据。 (2)不可重复读:事务1读取数据1后,事务2对数据1进行修改,之后事务1的再次读取数据1时,发现前后读取结果不一致 (3)幻读:事务1根据条件查询到一批数据后,事务2删除或增加或修改了某些数据,之后事务1再次根据条件查询,发现读取的数据数量不对

mysql:简单理解mysql mvcc的可重复读

# 原理 假设有这样的sql beginselect(或update、insert、delete) ...commit 当执行【begin】的时候,标记有一个新事务要开始,但是事务还没有真正开始,事务id还没有产生当执行事务里面的第一个sql语句时(这里是select),该事务才真正开始,这时事务id才产生。后面所有的【快照读】查询都会基于这个事务id进行数据的查询,【其它事务id】大

星辰考古:TiDB v2.x 回忆杀

前情回顾 在上一篇文章 星辰考古:TiDB v1.0 再回首 中,我们“回忆”了 TiDB v1.0 的内容,本文将介绍 TiDB v2.x 的相关内容。 从 TiDB 2.x 开始,正式引入 TiSpark 大数据组件,用于解决用户复杂的 OLAP 需求,或者 OLTP 和 OLAP 混合场景。 TiDB 2.x 整体架构图“升级”如下。 主要时间线 TiDB 2.x 系列在 2 年时间

【MySQL】InnoDB引擎(MVCC)

https://www.bilibili.com/video/BV1Kr4y1i7ru/?p=141 https://blog.csdn.net/weixin_52574640/article/details/129961415 MVCC,全称Multo-Version Concurrentcy Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MyS

mysql中 事务的隔离级别与MVCC

大家好。今天我们来讲一下事务的隔离级别和MVCC。在讲之前,我们先创建一张表,方便我们的讲解: CREATE TABLE hero ( number INT, name VARCHAR(100), country varchar(100), PRIMARY KEY (number) ) Engine=InnoDB CHARSET=utf8; 创建完毕后我们在表中插入一条数据: INSER

爬虫场景,可以使用TiDB替代HBase吗?

爬虫场景是典型的写多读少,咱们先看看HBase和TiDB的架构,再做进一步判断。 一、 HBase主要分为Master Server,region Server的主服务,以及需要HDFS,ZooKeeper的支撑服务。 (1)Master Server用于协调Region Server,而Region Server对外提供自身大量Region单元和wals的读写访问,以及对Region的维护。一

MySQL MVCC机制深入

MySQL MVCC机制 什么是MVCC MVCC (Multiversion Concurrency Control) 中文全程叫多版本并发控制,是现代数据库(包括 MySQL、Oracle、PostgreSQL 等)引擎实现中常用的处理读写冲突的手段,目的在于提高数据库高并发场景下的吞吐性能。 如此一来不同的事务在并发过程中,SELECT 操作可以不加锁而是通过 MVCC 机制读取指定的

TiDB-从0到1-部署篇

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇 一、TiUP TiUP是TiDB4.0版本引入的集群运维工具,通过TiUP可以进行TiDB的日常运维工作,包括部署、启动、关闭、销毁、弹性扩缩容和升级TiDB集群,以及管理TiDB集群参数。相较二进制、yum等部署方式,Ti

MySQL:MVCC的理解

MVCC主要适用于Mysql的RC,RR隔离级别 MySQL数据库默认隔离级别:RR(Repeatable Read,可重复读) 什么是MVCC       Multi-Version Concurrency Control:多版本并发控制。 基本实现原理       MVCC的实现,通过保存数据在某个时间点的快照来实现的。       这意味着一个事务无论运行多长时间,在同一个事务里