Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

用以保护StorageGroupProcessor中的内存结构,如当前的workingTsFileProcessor、latestTimeForEachDevice、partitionLatestFlushedTimeForEachDevice、newlyFlushedPartitionLatestFlushedTimeForEachDevice、globalLatestFlushedTimeForEachDevice、partitionMaxFileVersions等等

compactionMergeLock in TsFileManagement

用以保护TsFileManagement中管理的顺序和乱序的TsFileResource的List,所有对TsFileResource的List的写操作(比如写入时,创建新的TsFileResource,compact时删除旧的TsFileResource,并产生新的TsFileResource)需要获得其写锁,所有对TsFileResource的List的读操作(如查询时获得满足此次查询条件的所有TsFileResource)需要获得其读锁

resourceListLock in TsFileResourceManager

用以保护TsFileResourceManager中管理的顺序和乱序的TsFileResource的双向链表,所有对TsFileResource的List的写操作(比如写入时,创建新的TsFileResource,compact时删除旧的TsFileResource,并产生新的TsFileResource)需要获得其写锁,所有对TsFileResource的List的读操作(如查询时获得满足此次查询条件的所有TsFileResource)需要获得其读锁

tsFileLock in TsFileResource

...

insertLock → compactionMergeLock → tsFileLock

查询获取和释放锁的流程

首先调用StorageEngine.mergeLock,根据每个查询涉及的序列,获得这些序列所属的所有StorageGroupProcessor,按照StorageGroupProcessor的name的字母序排序后,依次对每个StorageGroupProcessor进行加锁,这个加锁过程先获取insertLock的读锁,再获得compactionMergeLock的读锁。

然后,对每个涉及的序列调用QueryResourceManager.getInstance().getQueryDataSource,获得该序列满足查询条件的所有的TsFileResource,并对所有的TsFileResource调用QueryFileManager.

...


  • 在各种查询 Executor 的初始化方法中
  • 调用StorageEngine.mergeLock
    • 根据每个查询涉及的序列,获得这些序列所属的所有StorageGroupProcessor,按照StorageGroupProcessor的name的字母序排序
    • 对于每个查询涉及的 StorageGroupProcessor
      • 对 insertLock 加读锁,对 compactionMergeLock 加读锁
    • 对每个涉及的序列所在的 StorageGroupProsessor
      • 对 insertLock 加读锁,对 compactionMergeLock 加读锁
      • 筛选待查的 TsFileResource 列表,对于待查的每个 TsFileResource
        • 对 TsFileLock 加读锁
      • 释放 insertLock 和 compactionMergeLock 的读锁
  • 调用StorageEngine.mergeUnlock,对每个涉及的序列所在的 StorageGroupProsessor
    • 释放 insertLock 和 compactionMergeLock 的读锁
  • 直到查询结束,释放所有 TsFileLock 的读锁
    • 查询正常结束,则会在 fetchResult() 没有下一组数据时,调用 releaseQueryResourceNoExceptions() 方法释放读锁
    • 查询正常进行,但未取到最后一组数据时,dataSet 被关闭,也会调用 releaseQueryResourceNoExceptions() 方法释放读锁
    • 查询正常进行,此时 session 连接调用 close()方法,会对此连接执行的每个未被释放查询,调用 releaseQueryResourceNoExceptions() 方法释放读锁
    • 查询遇到异常,则会在异常捕获内调用 releaseQueryResourceNoExceptions() 释放读锁


写入获取和释放锁的流程


写入获取锁的流程较为简单,在StorageGroupProcessor中,每一个insert接口都会直接获取该SGP的insert lock的写锁,直至写入完成,返回StorageEngine后再释放写锁,具体写入接口如下:

...

public void asyncClose() 

写入过程中还会拿resourceListLock

...


  • 写入过程中,新建一个文件,并把 TsFileResource 加到 list 时
    • compactionMergeLock.writeLock()
    • 修改resourceList

...

    • compactionMergeLock.writeUnlock()


合并获取和释放锁的流程

合并对锁的获取主要分为两部分:

外部获取及修改TsFileResource列表:

都是针对于compactionMergeLock的锁

所有对TsFileResource的List的读操作(如查询时获得满足此次查询条件的所有TsFileResource)需要获得其读锁

所有对TsFileResource的List的写操作(比如写入时,创建新的TsFileResource)需要获得其写锁

即,对于每一个文件列表相关操作,其锁的获取和释放格式为

...


  • 选择文件时
    • compactionMergeLock.readLock()
    • 拷贝 resourceList
    • compactionMergeLock.readUnlock()


  • 合并文件结束时
    • compactionMergeLock.writeLock()

...

    • 修改 resourceList,移除要删除的 TsFileResource
    • compactionMergeLock.readUnlock()

...

    • 对于每个待删除的 TsFileResource
      • 拿 TsFileLock 的写锁
      • 删文件
      • 释放 TsFileLock 的写锁



提交合并任务:

1、resourceListLock.readLock()

...

  3、释放TsFileResource的tsFileLock写锁

...


数据删除操作

在StorageGroupProcessor中,每一个删除接口都会直接获取该SGP的insert lock的写锁,直至删除完成、或者捕获异常后释放写锁。

...