TiDB索引

一.TiDB索引设计

1.索引设计原则

TiDB最初的设计目的是在兼容MySQL的前提下,提供横向扩展能力,以解决分库分表的问题。在后续不断的发展中,需要满足高并发读写,多副本的一致性与高可用,支持分布式事务等。
依据上述条件,选择合适的索引数据结构。

2.LSM-Tree(Log Structured Merge Tree)

在这里插入图片描述

数据分为两部分,一部分在内存,一部分在磁盘中
内存部分由Memtable和Immutable Memtable

磁盘部分由多层的SSTable组成,从 上到下,级数level越大,数据越老
WAL日志先行 在尾部以Append Only方式追加记录的日志结构文件,它用来当系统崩溃重启时重放操作,使MemTable和Immutable MemTable中未持久化到磁盘中的数据不会丢失
SSTable:
键值存储,有序,内部包含了一系列可配置大小的Block块,典型的大小是64KB,关于这些Block块的index存储在SSTable的尾部,用于帮助快速查找特定的Block。当一个SSTable被打开的时候,index会被加载到内存,然后根据key在内存index里面进行一个二分查找,查到该key对应的磁盘的offset之后,然后去磁盘把响应的块数据读取出来。当然如果内存足够大的话,可以直接把SSTable直接通过MMap的技术映射到内存中,从而提供更快的查找。
MemTable往往是一个跳表(Skip List)组织的有序数据结构
写入:对比B+树,当数据量特别大时,由于B+树更新和删除数据时需要沿着B+树逐层进行页分裂和页合并,严重影响数据写入性能。
对于LSM-Tree,它将数据切分成一系列的SSTable(Sorted String Table),是有序的,写入磁盘中,就像日志一样不能再修改。
修改现有数据时,LSM Tree并不直接修改旧数据,而是直接将新数据写入新的SSTable中。同样的,
写入速度与数据总量无关,因为一方面是追加日志,一方面是写memtable ,且其大小控制的很小,所以写入速度是很稳定的
删除数据,LSM Tree也不直接删除旧数据,而是写一个相应数据的删除标记的记录到一个新的SSTable中。这样一来,LSM Tree写数据时对磁盘的操作都是顺序块写入操作,而没有随机写操作。
在MemTable中写入一条删除标记。当MemTable的大小达到设定的大小(典型值是64KB)时,LSM Tree会把当前MemTable冻结为一个不可修改的Immutable MemTable

写入过程:
1.写入WAL log 作为故障恢复
2.同时写入内存 到Memtable中
最新写入的数据都会保存到 mem_ 中当 mem_ 的大小超过 write_buffer_size 时,LevelDB 就会将其切换成 imm_,并生成新的 mem_ LevelDB 的后台线程会将 imm_ compact 成 SSTable 保存在磁盘上。 如果前台的写入速度很快,有可能出现 mem_ 的大小已经超过 write_buffer_size,但是前一个 imm_ 还没有被 compact 到磁盘上,无法切换 MemTable,此时就会出现 stall write(阻塞写请求)。
3.把内存里面不可变的Memtable给dump到到硬盘上的SSTable层中,此步骤也称为Minor Compaction
4.当每层的磁盘上的SSTable的体积超过一定的大小或者个数,也会周期的进行合并。此步骤也称为Major Compaction,这个阶段会真正 的清除掉被标记删除掉的数据以及多版本数据的合并,避免浪费空间

读取:先在内存MemTable中查找,然后在内存中的Immutable MemTable中查找,然后在level 0 SSTable中查找,最后在level N SSTable中查找,前一个SSTable的最大数据值小于后一个SSTable的最小数据值
同时 合并多个SSTable为一个,把修改前的数据或删除的数据真正从SSTable中删除,减少SSTable的数量
如果目标数据在最底层level N的SSTable中,我们需要读取和查找所有的SSTable!LSM Tree把这种读取和查找了无关SSTable的现象叫做读放大

优化方式
压缩数据block
布隆过滤器 快速确定数据不在SSTable中
SSTable是不可变的,非常适合缓存到内存中
多个SSTable合并为一个SSTable

SSTable:
合并需要将合并涉及的SSTable读入内存,并把合并后产生的新的SSTable写入磁盘,会增加磁盘IO和CPU的消耗,这种写入磁盘的数据量大于实际数据量现象成为写放大

每层数据大小设置阈值
在这里插入图片描述
sst文件结构

File format
<beginning_of_file>
[data block 1]
[data block 2]
...
[data block N]
[meta block 1: filter block]                  (see section: "filter" Meta Block)
[meta block 2: index block]
[meta block 3: compression dictionary block]  (see section: "compression dictionary" Meta Block)
[meta block 4: range deletion block]          (see section: "range deletion" Meta Block)
[meta block 5: stats block]                   (see section: "properties" Meta Block)
...
[meta block K: future extended block]  (we may add more meta blocks in the future)
[metaindex block]
[Footer]                               (fixed size; starts at file_size - sizeof(Footer))
<end_of_file>

二.TiDB与MySQL索引区别

在这里插入图片描述
LSMtree 拆分数据为多个小数组 顺序写入 近似o(1)
B+Tree则是将数据拆分为固定大小的Block或Page, 一般是4KB大小,和磁盘一个扇区的大小对应 写入o(logN) 随着insert的操作,为了维护B+树结构,节点会不断的分裂和合并。操作磁盘的随机读写概率会变大,故导致性能降低
数据的更新和删除方面,B+Tree可以做到原地更新和删除,这种方式对数据库事务支持更加友好,因为一个key只会出现一个Page页里面
LSM-Tree只能追加写,并且在L0层key的rang会重叠,所以对事务支持较弱,只能在Segment Compaction的时候进行真正地更新和删除

RocksDB 将存储在磁盘上的文件都按照一定大小切分成 block(默认是 64KB),读取 block 时先去内存中的 BlockCache 中查看该块数据是否存在,存在的话则可以直接从内存中读取而不必访问磁盘。

支持:主键索引 唯一索引 普通索引

  • 不支持 FULLTEXT,HASH 和 SPATIAL 索引
  • 不支持降序索引
  • 尚不支持在一条中同时添加多个索引

3.与MySQL不同处

1.AUTO_INCREMENT

自增编号是系统批量分配给每台 TiDB 服务器的值(默认 3 万个值)
每个 TiDB 节点在分配 ID 时,都申请一段 ID 作为缓存,用完之后再去取下一段,而不是每次分配都向存储节点申请
值的顺序不具有全局单调性

2.DDL

不能在单条 ALTER TABLE 语句中完成多个操作。例如,不能在单个语句中添加多个列或索引,否则,可能会输出 Unsupported multi schema change 的错误
不支持修改分区表上的列类型

3.分区表

分区表支持 Hash、Range 和 Add/Drop/Truncate/Coalesce。其他分区操作将被忽略,可能会报 Warning: Unsupported partition type, treat as normal table 错误。不支持以下分区表语法:
PARTITION BY LIST
PARTITION BY KEY
SUBPARTITION
{CHECK|EXCHANGE|TRUNCATE|OPTIMIZE|REPAIR|IMPORT|DISCARD|REBUILD|REORGANIZE} PARTITION

4.锁

TiDB 当前不支持 gap locking(间隙锁)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值