关于 skiplist 和 sstable 的两个问题

请问TiDB采用lsmtree架构,memtable用的跳表,那么意味着每增加一个索引,memtable里都要维护一个skiplist吗?

既然immutable和memtable里的数据结构为跳表,也就是有序的,那么从imumutable落盘到L0层时,也是顺序写入吧?那么可不可以理解为,L0层的单个sstable里key值是有序的,但多个sstable之间的key值是非顺序的?

希望能得到指点解答,感谢感谢。

上层数据具体编码对底层屏蔽,没有多一个 index 就多一个 skiplist 之说。

这段理解是对的

感谢回复,本人小白,还是没理解“上层数据具体编码对底层屏蔽”啥意思:dizzy_face:试着用例子表达下我的疑问。比如有user表,表中有两列(uid,email),uid是整型主键,那么现在这个表的kv对简单表示为uid–>email,现在我对email建了一个二级索引,那么在tikv里是不是得存email–>uid的kv对?那么在进行写入时,email–>uid这个kv对也要遵循memtable->immutable->sstable这个过程吗?在通过二级索引email进行查询时,又是在哪一层定位到email对应的主键或rowid呢?

感谢指点

整体上所有的 sstable 是一个大的 key map,单个 sstable 里面是有序的,L0 层不同 sstable 之间可能存在一些 key 重叠;每增加一个索引,如果索引被打散到在不同的 region(key 范围) 里面,可能独立存储在另一个 sstable 中,也会遵循 memtable->immutable->sstable 这个过程;在通过二级索引email进行查询时,会先去 memtable,block-cache 中查找,如果没找到到,会将 sst 文件中的文件读到 block cache 进行缓存。

我的理解:

  1. 不是增加一个索引, 而是说增加一个字段吧。。
  2. 每个region都维护自己的sstable吧, skiplist与sstable是一一对应的

我发现sstable有十几层, 写放大问题会不会比较严重?
sstable十几层的目的是什么?

没有十几层呀, 6 层呢。写放大情况是存在的,不过这块随着存储层的写入优化,性能和存储这部分问题会解决的。另外对于大的 values 我们提供了 titan 存储影响。https://docs.pingcap.com/zh/tidb/stable/titan-overview

可能是我看错了吧。 谢谢

请问 sstable 十几层是通过什么观察到的,可以贴下相应的信息或截图吗?

我之前查配置, 记错了应该; 昨天又查了一下 是6层

谢谢回复,您回复中提到“在通过二级索引email进行查询时,会先去 memtable,block-cache 中查找”

这里去block-cache读我比较容易理解,但”先去memtable“我比较迷惑。memtable中我个人理解里面是一个以主键(或rowid)排序的skiplist,还是拿上面提到的(uid,email)表,考虑一下这个场景:

  1. 用户1首先对这个表进行一个插入操作
    insert into table values (10,‘email@123.com’);
  2. 假设这条记录现在已写入memtable和wal(返回给用户成功),但还未落盘到sstable。这时用户2发起一个读请求
    select * from table where email=‘email@123.com’;

请问,这时用户2是如何在memtable中找到email=‘email@123.com’这个key的?(因为memtable中只有主键顺序的跳表嘛,通过主键uid查询的话可以用二分法定位,那么通过二级索引email怎么定位我就很迷惑)

不知道我表达清楚没有,感谢感谢

二级索引存储上也是一个 kv 映射,定位需要两次请求,第一次通过 email 定位到 rowid,第二次通过 rowid 再回表查询记录

对,是要两次定位,因为二级索引做kv映射编码时,已经把二级索引对应的主键值编码进二级索引的key值里去了,只要能定位到二级索引email='email.123.com’,自然就能拿到主键rowid的值,我就是不明白怎么在memtable中定位到二级索引email='email.123.com‘这个key的,或者这个步骤不是在memtable完成的?

这个和通过主键定位到 value 操作是类似的吧,应该是通过 memtable 提供的 Get 接口完成

此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。