数据增删改

下面介绍四种常用数据操控操作,分别是插入,更新,删除和TTL设置

数据插入

单行数据(一个设备一个时间戳多个值)写入

  • 对应的接口

    • JDBC 的 execute 和 executeBatch 接口
    • Session 的 insertRecord 和 insertRecords
  • 总入口: public void insert(InsertRowPlan insertRowPlan) StorageEngine.java

    • 找到对应的 StorageGroupProcessor
    • 根据写入数据的时间以及当前设备落盘的最后时间戳,找到对应的 TsFileProcessor
    • 写入 TsFileProcessor 对应的 memtable 中
      • 如果是乱序文件,则更新tsfileResource中的endTimeMap
      • 如果tsfile中没有该设备的信息,或新插入数据的时间小于已存startTime,则更新tsfileResource中的startTimeMap
    • 记录写前日志
    • 根据 memtable 大小,来判断是否触发异步持久化 memtable 操作
      • 如果是顺序文件且执行了刷盘动作,则更新tsfileResource中的endTimeMap
    • 根据当前磁盘 TsFile 的大小,判断是否触发文件关闭操作

批量数据(一个设备多个时间戳多个值)写入

  • 对应的接口

    • Session 的 insertTablet
  • 总入口: public void insertTablet(InsertTabletPlan insertTabletPlan) StorageEngine.java

    • 找到对应的 StorageGroupProcessor
    • 根据这批数据的时间以及当前设备落盘的最后时间戳,将这批数据分成小批,分别对应到一个 TsFileProcessor 中
    • 分别将每小批写入 TsFileProcessor 对应的 memtable 中
      • 如果是乱序文件,则更新tsfileResource中的endTimeMap
      • 如果tsfile中没有该设备的信息,或新插入数据的时间小于已存startTime,则更新tsfileResource中的startTimeMap
    • 记录写前日志
    • 根据 memtable 大小,来判断是否触发异步持久化 memtable 操作
      • 如果是顺序文件且执行了刷盘动作,则更新tsfileResource中的endTimeMap
    • 根据当前磁盘 TsFile 的大小,判断是否触发文件关闭操作

数据更新

目前不支持数据的原地更新操作,即update语句,但用户可以直接插入新的数据,在同一个时间点上的同一个时间序列以最新插入的数据为准 旧数据会通过合并来自动删除,参见:

数据删除

  • 对应的接口
    • JDBC 的 execute 接口,使用delete SQL语句

每个 StorageGroupProsessor 中针对每个分区会维护一个自增的版本号,由 SimpleFileVersionController 管理。 每个内存缓冲区 memtable 在持久化的时候会申请一个版本号。持久化到 TsFile 后,会在 TsFileMetadata 中记录此 memtable 对应的 多个 ChunkGroup 的终止位置和版本号。 查询时会根据此信息对 ChunkMetadata 赋 version。

StorageEngine.java中的delete入口:

public void delete(String deviceId, String measurementId, long timestamp)

  • 找到对应的 StorageGroupProcessor
  • 找到受影响的所有 working TsFileProcessor 记录写前日志
  • 找到受影响的所有 TsFileResource,在其对应的 mods 文件中记录一条记录:path,version,startTime,endTime
    • 如果存在 working memtable:则删除内存中的数据
    • 如果存在 正在 flush 的 memtable,记录一条记录,查询时跳过删掉的数据(注意此时文件中已经为这些 memtable 记录了 mods)

Mods文件用来存储所有的删除记录。下图的mods文件中,d1.s1落在 [100, 200], [180, 300]范围的数据,以及d1.s2落在[500, 1000]范围中的数据将会被删除。

数据TTL设置

  • 对应的接口

    • JDBC 的 execute 接口,使用SET TTL语句
  • 总入口: public void setTTL(String storageGroup, long dataTTL) StorageEngine.java

    • 找到对应的 StorageGroupProcessor
    • 在 StorageGroupProcessor 中设置新的data ttl
    • 对所有TsfileResource进行TTL检查
    • 如果某个文件在当前TTL下失效,则删除文件

同时,我们在 StorageEngine 中启动了一个定时检查文件TTL的线程,详见

  • src/main/java/org/apache/iotdb/db/engine/StorageEngine.java 中的 start 方法