TIDB 开启clustered_index会占用很大的存储空间么

【 TiDB 使用环境】:生产
【 TiDB 版本】 :7.1.0
【遇到的问题:问题现象及影响】 :TIDB 开启clustered_index会占用很大的存储空间么,这个索引是在TIKV中的writeCF存储么

clustered_index,指的是数据存储的时候kv对的key就是表的主键id的值。
nonclustered_index,指得是数据存储的时候kv对的key是自动生成的不重复的_tidb_rowid。主键索引会单独建立。

即,clustered_index要比nonclustered_index紧凑,如果主键查询会少一次回表。

https://docs.pingcap.com/zh/tidb/stable/clustered-indexes#聚簇索引

文档位置。

问题一:那默认开启clustered_index后,数据会膨胀么?
问题二:从监控上看writeCF占的空间是defaultCF的1/3了,为何会占用这么大的存储呢?

问题1,答案是不会,参考上个回复。

问题2:每个引擎的列簇作用,

TiKV 使用了 RocksDB 的 `Column Families` (CF) 特性。

* 默认 RocksDB 实例将 KV 数据存储在内部的 `default`、`write` 和 `lock` 3 个 CF 内。
  * `default` CF 存储的是真正的数据,与其对应的参数位于 `[rocksdb.defaultcf]` 项中;
  * `write` CF 存储的是数据的版本信息 (MVCC) 以及索引相关的数据,相关的参数位于 `[rocksdb.writecf]` 项中;
  * `lock` CF 存储的是锁信息,系统使用默认参数。
* Raft RocksDB 实例存储 Raft log。
  * `default` CF 主要存储的是 Raft log,与其对应的参数位于 `[raftdb.defaultcf]` 项中。

https://docs.pingcap.com/zh/tidb/stable/tune-tikv-memory-performance#tikv-内存参数性能调优

所以writeCF是索引数据+mvcc,那么这个CF变大就有几个可能,1,是更新频繁。mvcc数据多.2,gc时间设置的长,保留的mvcc数据多。3,就是索引建立的多。索引数据多。

2个问题结合一下,如果你想问clustered_index数据是否占用writeCF?答案是会,因为clustered_index虽然可以少建立一条索引,但是mvcc信息还是会存在writeCF里面。
但clustered_index肯定不会导致数据膨胀,起码应该比nonclustered_index的占用小。如果大了,造成这种问题的原因应该从更新频率和gc长度设置这两个方面去查查。

我们之前用的是RocksDB引擎,默认只有defaultCF,数据和索引都应该在defaultCF保存,在表结构和数据量都一样的场景下,迁移到TIDB后发现,数据膨胀了40%,想定位一下原因,这块能提供一些思路么?大体上分析发现是因为writeCF这个增长了40% :grin:

难怪,也就是你以前是纯kv使用rocksdb,现在也是使用tikv-client直接调用tikv的是吧?
大概率是gc的问题。在单独使用tikv的场景下是个常见问题。

因为单独部署tikv,gc需要手动从tikv-client调用一下的,或者单独部署一个tidb用以gc。

https://github.com/tikv/client-go/wiki/Garbage-Collection

go-client的gc文档。你可以参考一下。

有视图或者工具能看到writeCF中MVCC和INDEX各自的容量占比么? 这样就好定位到底是GC导致的空间放大还是INDEX空间占用大导致的,目前我们是在做全量数据迁移,所以我个人感觉不是GC问题导致的

tikv有自己的key格式,虽然底层也是rocksdb,但不能直接这么比啊,另外不超一定长度的行(应该是255字节吧)会放到write cf,另外mvcc/信息也是写到writecf,这是rocksdb没有的

我不太清楚你怎么使用的tikv。

如果是原来kv操作rocksdb,现在kv操作tikv。没有tidb,大概率是gc。
如果是原来kv操作rocksdb,现在通过sql操作tikv。那writeCF大了,我觉得没啥问题。

我们直接部署的TIDB集群,然后把MYSQL ROCKSDB的数据导入过来了,发现数据膨胀了、对了,GC相关的优化配置有具体的链接么? 最好是最佳实战那种的,辛苦帮忙看看

那就不是使用tikv-client直接调用tikv的场景。

GC的safepoint推进情况,可以看grafana下的tikv-details下的GC里面,有个TiKV Auto GC SafePoint
图,只要是跟着时间按照GC interval往前推进的就行。

我现在感觉,可能就是rocksdb纯kv存储->带事务的存储的数据增大。

还有你上面提到的那个writeCF占比的监控,我也是没啥头绪,看看其他大佬是否知道。

GC相关的内容:【SOP 系列 25】GC 常见问题排查 可以看这个汇总贴

非常感谢您的回答,TIDB社区做的确实很牛,后续有问题在继续请教您,对于存储膨胀的问题我进行一下测试
步骤一:去掉表中INDEX灌入数据看看writeCF容量变化
步骤二:优化GC的配置

1 个赞

tidb社区确实非常棒。深有同感。 :joy:
假设, 你一定要从rocksdb到tikv的存储/性能差不多的话,个人感觉,可能直接使用tikv-client的rawkv api。可能是最低成本迁移改造。
从tidb的sql层绕一圈,性能和存储都可能和原来比有较大变化。
不管怎么样,多尝试找个适合方案确实是费心的事。祝你好运。 :fist:

数据膨胀你是怎么查的

:+1: :+1: :+1:

原生MySQL rocksdb引擎总数据存储1TB,迁移到TIDB后发现存储容量变成1.4TB了 :sweat_smile:

数据不同,差别不同。

tidb目前版本默认是聚簇表,数据是按主键排序的有序数据组织格式,如果只有主键索引那应该实际上物理上不存在额外索引

tidb是3副本的,你是3个tikv部署一个tikv1.4TB吗

TIKV单副本是1.4,如果是三副本就是1.4T*3了,近期我验证一下把表索引去掉后导一下数据对比一下