问题与目标

TsFile中的Version是一个递增的Long类型字段,由VersionController生成并在每个memtable被写入到磁盘时被序列化,主要用于标记每个memtable中chunk的写入次序。 这个version字段目前主要用于以下两方面:

  1. 用于确定每个modification记录是否对当前chunk生效。
  2. 查询时对于多个chunk内时间戳相同的数据点,version更大的chunk中数据点会被当做较新的数据。

本次修改针对于删除TsFile中记录的MemTable version,同时去掉TsFileMetadata中所有的VersionInfo。 去掉version记录后对以上删除和查询流程的处理如下:

  1. Mods文件中记录的delete信息中versionNum被替换为tsFileOffset,用于表示delete对于相应的Tsfile文件生效的文件位置,如果TsFile中一个chunk的offset小于等于tsFileOffset,则表示delete对这个chunk生效。
  2. 每个chunk记录所属tsFileResource的version,即resource文件命名中的version。对于多个chunk内时间戳相同的数据点,首先比较这个所属tsFileResource的version,如相同,再比较多个chunk的offset,以确定chunk之间的更新次序。


Delete流程修改

1.删除working memory table中的数据

working memory table存在于内存中,在delete语句执行过程中可以直接删除满足条件的数据。该情况与version无关,因此无需更改。


2.删除flushing memory table中的数据


修改前:

正在处于flushing状态中的memtable是不可变的。每做一次删除操作,memtable将这个deletion对象添加到自己的modifications当中,对flushing memtable的查询会用到这个modifications列表。同时生成一个version number构建一个deletion记录,写入到mods 文件中。


修改后:

在记录Deletion时,offset设为当前TsFile文件的大小:TsFileResource.getTsFileSize()。在tsFileProcessor中维护一个modsToMemtable的列表用来存储<deletion, flushing_memtable>,表示会对对应的flushing memtable及其之前的flushing memtable起作用的deletion。

在一个flushing memtable 成功落盘后,TsfileProcessor调用releaseFlushedMemTable()之前拿到落盘后的fileSize。从TsfileProcessor的modsToMemtable中删除包含这个memtable的记录,并将这些deletions记入mods文件。




具体流程参照上图,TsFileProcessor中存在三个flushing memtable。其中对memtable1起作用的是deletion0和deletion1,对memtable2起作用的包括deletion0,deletion1和deletion2。当memtable1被写入到磁盘中后,deletion0和deletion1被写入到mods文件;memtable2被写入到磁盘后deletion2被写入到mods文件中。



3.删除TsFile中Chunk的数据

对于已存在于tsfile中的数据,查询时会以chunkmetadata的形式被load到内存中。查询这些chunkmetadata时从mods文件中提取删除记录即可。


Query流程修改

  1. 修改modifyChunkMetaData(),将应用Deletion修改的条件改为比较Deletion的offset和chunkMetadata的offset。
  2. 查询过程中将每个tsFile的命名version记录到TsfileResource中,在deletion被写入到mods文件时用这个version更新deletion记录。在SeriesReader中使用{ tsFileVersion, offset }作为代替version的metric,用于merge reader的中排序。
  3. Last查询需要获取每个序列的最新数据点时,比较多个chunk中的最大时间戳。如果出现最大时间戳相等的情况,则首先比较chunk所属的tsFile的文件version,再比较chunk的offset,最新数据点取offset更大的chunk数据。


Recover流程修改

重启后Recover流程需要关注对于flushingMemtable的处理。如果有flushingMemtable的情况下重启server,会导致该flushingMemtable对应的TsfileResource处于crashed状态,需要通过WAL进行恢复。

LogReplayer的replayDelete()方法中,新建一个memtable用以重复对之前tsFile的恢复。当前memtable还未被写入到磁盘中,deletion操作可以直接对此memtable进行删除。之后创建一个deletion记录,其offset记为未flush memtable之前tsFileResource的大小,使用之前tsFileResource的大小是因为deletion已经对未刷磁盘前的memtable进行过删除处理了。















  • No labels

2 Comments

  1. 所以这个优化的好处是什么?

    1. 可以在不影响现有功能的前提下节约一些TsFile内的字节