层级合并日志记录流程
- 创建日志文件
- 选择源文件
- 记录源文件
- 记录 sequence 标志位
- 在内存中创建目标文件描述符
- 记录目标文件
- 以 device 为单位开始合并
- 合并完一个 device,就记录 device, writer.offset
- 如果合并结束了,就生成一个 *.resource 文件
- writer.endFile ,封口目标文件
- 删除源文件
- 删除合并日志文件
层级合并过程中可能中断的地方
以下以三个源文件 0-0-0.tsfile,1-1-0.tsfile,2-2-0.tsfile 以及 10 个设备(root.sg.d1, root.sg.d2,...,root.sg.d10)为例
第 1 步之前发生中断(尚未创建日志文件)
判断标志
日志文件不存在
日志文件
未创建
数据文件
源文件内容未发生改变,目标文件未创建
SGP 处理方式
将源文件加入到 resourceList 中
恢复过程
- 判断日志文件是否存在
- 退出
第 1 步 到第 3 步之间发生中断(尚未记录源文件)
判断标志
日志文件存在且为空
日志文件
创建了一个空的日志文件
数据文件
源文件内容未发生改变,目标文件未创建
SGP 处理方式
将源文件加入到 resourceList 中
恢复过程
- 判断文件日志是否存在
- 分析文件日志
- 从日志中获取 deviceSet
- 从日志中获取源文件列表 sourceFileList
- 从日志中获取 offset
- 从日志中获取目标文件名字 targetFile
- 获取是否 fullMerge
- 获取是否顺序 isSeq
- 如果 targetFile == null,退出
- 删除日志文件
第 3 步执行中发生中断(未将源文件记录完全)
判断标志
日志文件存在,记录了 source ,但是未记录是否是顺序合并
日志文件
创建了一个日志文件,记录了部分源文件
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/0-0-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/1-1-0.tsfile
数据文件
源文件内容未发生改变,目标文件未创建
SGP 处理方式
将源文件加入到 resourceList 中
恢复方式
- 判断文件日志是否存在
- 分析文件日志
- 从日志中获取 deviceSet
- 从日志中获取源文件列表 sourceFileList
- 从日志中获取 offset
- 从日志中获取目标文件名字 targetFile
- 获取是否 fullMerge
- 获取是否顺序 isSeq
- 如果 targetFile == null,退出
- 删除日志文件
第 3 步执行完在第 4 步执行前中断(未记录是否是顺序)
判断标志
日志文件存在,记录了 source ,但是未记录是否是顺序合并
日志文件
创建了一个日志文件,记录了所有的源文件
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/0-0-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/1-1-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/2-2-0.tsfile
数据文件
- 源文件内容未发生改变,目标文件未创建
SGP 处理方式
将源文件加入到 resourceList 中
恢复方式
- 判断文件日志是否存在
- 分析文件日志
- 从日志中获取 deviceSet
- 从日志中获取源文件列表 sourceFileList
- 从日志中获取 offset
- 从日志中获取目标文件名字 targetFile
- 获取是否 fullMerge
- 获取是否顺序 isSeq
- 如果 targetFile == null,退出
- 删除日志文件
第 4 步执行完在第 6 步执行前中断(尚未记录目标文件)
判断标志
日志文件存在,记录了 source 文件和是否是顺序合并的标志位,但是没有记录目标文件
日志文件
创建了一个日志文件,记录了所有的源文件和 sequence 标志位
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/0-0-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/1-1-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/2-2-0.tsfile
sequence
数据文件
源文件内容未发生改变,目标文件未创建
SGP 处理方式
将源文件加入到 resourceList 中
恢复方式
- 判断文件日志是否存在
- 分析文件日志
- 从日志中获取 deviceSet
- 从日志中获取源文件列表 sourceFileList
- 从日志中获取 offset
- 从日志中获取目标文件名字 targetFile
- 获取是否 fullMerge
- 获取是否顺序 isSeq
- 如果 targetFile == null,退出
- 删除日志文件
执行完了第 6 步,但未执行第 8 步(尚未记录 device 和 offset)
判断标志
日志文件存在,记录了 source 文件和是否是顺序合并的标志位,记录了目标文件的名称,未记录任何 device 和 offset;
日志文件
创建了一个日志文件,记录了所有的源文件、目标文件和 sequence 标志位
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/0-0-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/1-1-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/2-2-0.tsfile
sequence
target
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/0-0-1.tsfile
数据文件
- 源文件内容未发生改变,目标文件未创建
- 源文件内容未发生改变,目标文件已创建且写入了一个 Device 的部分数据
- 源文件内容未发生改变,目标文件已创建,且已经写入了一个 Device 的数据,但日志未记录
SGP 处理方式
将源文件加入到 resourceList 中,将目标文件加入到 recoverList 中
恢复方式
- 判断文件日志是否存在
- 分析文件日志
- 从日志中获取 deviceSet
- 从日志中获取源文件列表 sourceFileList
- 从日志中获取 offset
- 从日志中获取目标文件名字 targetFile
- 获取是否 fullMerge
- 获取是否顺序 isSeq
- 判断 targetFile 和 sourceFileList 是否为空,此处不为空,继续
- 判断 deviceSet.isEmpty(),此处成立,删除目标文件,退出
- 删除日志文件
执行了若干个第 8 步,但没有全部执行完(未将 device 和 offset 记录完全)
判断标志
日志文件存在,记录了 source 文件和是否是顺序合并的标志位,记录了目标文件的名称,记录若干个 device 和 offset;
target 文件存在,使用 RestorableWriter 判断 hasCrashed
为 true 。
日志文件
创建了一个日志文件,记录了所有的源文件、目标文件和 sequence 标志位,以及部分 device 和 device 在目标文件中的 offset
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/0-0-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/1-1-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/2-2-0.tsfile
sequence
target
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/0-0-1.tsfile
root.sg.d9
17535
root.sg.d0
35058
root.sg.d3
52581
数据文件
- 源文件内容未发生改变,目标文件已创建,写入了部分 Device 数据,目标文件中所有 Device 的日志都得到了记录
- 源文件内容未发生改变,目标文件已创建,写入了部分 Device 数据,目标文件中最后一个 Device 的数据未写完,也没有写进日志
- 源文件内容未发生改变,目标文件已创建,写入了部分 Device 数据,目标文件中最后一个 Device 的数据已经写完,但没有写进日志
SGP 处理方式
将源文件加入到 resourceList 中,将目标文件加入到 recoverList 中
恢复方式
- 判断文件日志是否存在
- 分析文件日志
- 从日志中获取 deviceSet
- 从日志中获取源文件列表 sourceFileList
- 从日志中获取 offset
- 从日志中获取目标文件名字 targetFile
- 获取是否 fullMerge
- 获取是否顺序 isSeq
- 判断 targetFile 和 sourceFileList 是否为空,此处不为空,继续
- 判断 deviceSet.isEmpty(),此处不成立,继续
- 从 recoverTsFileResourceList 获取目标文件的 TsFileResource
- 获取目标文件的时间分区
- 新建一个 RestorableWriter writer
- 使用 writer.hasCrashed() 来判断文件是否封口,此处文件没有封口,继续
- 将 writer 截到日志中最后记录的 offset(例如在上面这个日志中,将 52581 后的数据全部截去)
- 重新进行合并流程,跳过已经日志中记录过已经合并完成的 device
- 删除源文件
- 删除日志
所有第 8 步都执行完了(数据部分写入完成,但是没有对数据文件封口)
判断标准
日志文件存在,记录了 source 文件和是否是顺序合并的标志位,记录了目标文件的名称,记录若干个 device 和 offset;
target 文件存在,使用 RestorableWriter 判断 hasCrashed
为 true , resource 存在
日志文件
创建了一个日志文件,记录了所有的源文件、目标文件和 sequence 标志位,以及所有 device 和 device 在目标文件中的 offset
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/0-0-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/1-1-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/2-2-0.tsfile
sequence
target
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/0-0-1.tsfile
root.sg.d9
17535
root.sg.d0
35058
root.sg.d3
52581
root.sg.d4
70104
root.sg.d1
87627
root.sg.d2
105150
root.sg.d7
122673
root.sg.d8
140196
root.sg.d5
157719
root.sg.d6
175242
数据文件
- 源文件未发生改变,目标文件已创建并且写入了所有 Device 的数据,创建了 resource 文件,但未封口
SGP 处理方式
将源文件加入到 resourceList 中,将目标文件加入到 recoverList 中
恢复方式
- 判断文件日志是否存在
- 分析文件日志
- 从日志中获取 deviceSet
- 从日志中获取源文件列表 sourceFileList
- 从日志中获取 offset
- 从日志中获取目标文件名字 targetFile
- 获取是否 fullMerge
- 获取是否顺序 isSeq
- 判断 targetFile 和 sourceFileList 是否为空,此处不为空,继续
- 判断 deviceSet.isEmpty(),此处不成立,继续
- 从 recoverTsFileResourceList 获取目标文件的 TsFileResource
- 获取目标文件的时间分区
- 新建一个 RestorableWriter writer
- 使用 writer.hasCrashed() 来判断文件是否封口,此处文件没有封口,继续
- 将 writer 截到日志中最后记录的 offset(例如在上面这个日志中,将 52581 后的数据全部截去)
- 重新进行合并流程,跳过已经日志中记录过已经合并完成的 device
- 删除源文件
- 删除日志
所有第 8 步都执行完了(数据部分写入完成,且已经对数据文件封口)
判断标准
日志文件存在,记录了 source 文件和是否是顺序合并的标志位,记录了目标文件的名称,记录若干个 device 和 offset;
target 文件存在,使用 RestorableWriter 判断 hasCrashed
为 false , resource 存在
日志文件
创建了一个日志文件,记录了所有的源文件、目标文件和 sequence 标志位,以及所有 device 和 device 在目标文件中的 offset
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/0-0-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/1-1-0.tsfile
source
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/2-2-0.tsfile
sequence
target
/Users/surevil/Desktop/workspace/incubator-iotdb/server/target/0-0-1.tsfile
root.sg.d9
17535
root.sg.d0
35058
root.sg.d3
52581
root.sg.d4
70104
root.sg.d1
87627
root.sg.d2
105150
root.sg.d7
122673
root.sg.d8
140196
root.sg.d5
157719
root.sg.d6
175242
数据文件
- 源文件未发生改变,目标文件已创建并且写入了所有 Device 的数据,创建了 resource 文件,目标文件已封口
SGP 处理方式
将源文件加入到 resourceList 中,将目标文件加入到 resourceList 中
恢复方式
- 判断文件日志是否存在
- 分析文件日志
- 从日志中获取 deviceSet
- 从日志中获取源文件列表 sourceFileList
- 从日志中获取 offset
- 从日志中获取目标文件名字 targetFile
- 获取是否 fullMerge
- 获取是否顺序 isSeq
- 判断 targetFile 和 sourceFileList 是否为空,此处不为空,继续
- 判断 deviceSet.isEmpty(),此处不成立,继续
- 从 recoverTsFileResourceList 获取目标文件的 TsFileResource
- 获取目标文件的时间分区
- 新建一个 RestorableWriter writer
- 使用 writer.hasCrashed() 来判断文件是否封口,此处文件已经封口
- 关闭 writer
- 删除源文件
- 删除日志
合并恢复任务
...