测试目标

尽可能覆盖文件合并可能遇到的所有场景

测试版本

[ISSUE-3445] New compaction strategy and compaction scheduling strategy

https://github.com/apache/iotdb/pull/3447

测试中可调整的配置参数

以下为默认的参数配置

enable_seq_space_compaction=true

enable_unseq_space_compaction=true

enable_cross_space_compaction=true

compaction_priority=inner_cross

compaction_target_file_size=2147483648(合并后目标文件大小)

max_open_file_num_in_cross_space_compaction=2000(跨文件空间合并最多允许打开的文件数目)

merge_chunk_point_number=100000(达到本阈值后,文件合并不再将文件的chunk合大)

merge_page_point_number=100(达到本阈值后,文件合并不再解chunk以将文件的page合大)

compaction_concurrent_thread=50(合并执行任务的并行度)

compaction_interval=10000(定时合并任务的提交间隔,单位 ms)

测试中需要进行的操作组合

插入数据、flush(插入一个文件)

执行 merge 命令

delete数据、序列

查询数据

可能要加的相关操作(move, load, remove partition...)

单元测试

验证方法

使用TsFile接口查询合并后文件的数据点的时间、值(数据类型),顺序扫描文件检查数据点的值,Chunk 内 Page 个数、文件内的 Chunk 个数、Chunk 是否满足大小限制、统计信息、目标 TsFileResource 的内容

测试工具

文件生成工具

输入:

  • 时间序列(Map<String(fullPath), DataType> fullPathDataTypeMap)
  • 目标Chunk和Page数据点数(格式为List<List<Long>>)
  • 开始时间
  • 新文件TsFileResource

执行:

  • 生成一个新文件,对于每一个时间序列,从开始时间开始往文件中插入点(每个点+1),使得最后这个文件每个序列都满足目标Chunk和Page大小,值和时间保持一致
文件读取工具

输入:

  • 文件列表(List<TsFileResource>)

执行:

  • 使用TsFileSequenceReader从后往前读取文件

返回:

  • 所有时间序列及其对应的数据点(Map<String(fullPath),List<TimeValuePair>>)
数据正确性测试工具

输入:

  • 合并前所有时间序列及其对应的数据点(Map<String(fullPath),List<TimeValuePair>>)
  • 合并后文件(List<TsFileResource>)

执行

  • 使用TsFileSequenceReader从后往前读取合并后文件,并与合并前数据进行一一对比,保证完全一致
  • 使用TsFileSequenceReader从前往后读取合并后文件,并与合并前数据进行一一对比,保证完全一致,包括pointsInPage统计信息
  • 检查TsFileResource统计信息和原数据点是否一一对应,包括startTime,endTime(device级别)
Chunk和Page个数及大小检查工具

输入:

  • 目标Chunk和Page大小(格式为List<List<Long>>)
  • 合并后文件(TsFIleResource)

执行:

  • 使用TsFileSequenceReader从前往后读取合并后文件,并与合并前数据进行一一对比,保证Chunk和Page的顺序和大小都一一对应
mods生成工具

输入:

  • 删除的序列及时间段([startTime, endTime])Map<String(fullPath), Pair<Long(startTime),Long(endTime)>>
  • 对应TsFile文件
  • 是否是.compaction.mods(boolean)

执行:

  • 对相应文件根据Map<String(fulPath), Pair<Long,Long>>生成mods文件
文件清理工具

执行:

  • 清空测试目录下所有生成和合并成的文件

执行

合并执行:跨空间(没有解Page和解Chunk)、顺序空间、乱序空间

是否解 Page:是、否

是否解 Chunk:是、否

空间内合并的文件个数:2、3

文件的序列:全部一致、部分一致、全都不一致

合并前是否有 mods 文件:是、否

合并中是否有 compaction.mods 文件:是、否

是否有 log 文件(Recover测试、有测试用例):是、否


乱序空间内的重叠情况:File(1-n)、Chunk(1-n)、Page(1-n)、交集(Contains、Overlap)

File 无交集

File 有交集、Chunk 无交集

File 有交集、Chunk 有交集、Page 无交集

File 有交集、Chunk 有交集、Page 有交集


跨空间合并数据的重叠情况:File(1-n)、Chunk(1-n)、Page(1-n)、顺序和乱序的关系 (Contains / In / 前overlap / 后overlap / 前non-overlap / 后non-overlap )

1 顺序, 6 乱序 覆盖6种关系

6顺序,1 乱序 覆盖6种关系

调度 

主要测scheduleCompaction()方法

输入:

  • 顺序(List<TsFileResource>)
  • 乱序(List<TsFileResource>)

组合改变如下参数,进行测试

enable_seq_space_compaction=true

enable_unseq_space_compaction=true

# enable_cross_space_compaction=true

# compaction_priority=inner_cross

compaction_target_file_size=2147483648(合并后目标文件大小)

# max_open_file_num_in_cross_space_compaction=2000(跨文件空间合并最多允许打开的文件数目)

# merge_chunk_point_number=100000(达到本阈值后,文件合并不再将文件的chunk合大)

# merge_page_point_number=100(达到本阈值后,文件合并不再解chunk以将文件的page合大)

compaction_concurrent_thread=50(合并执行任务的并行度)

集成测试

测和各模块的交互

compaction_interval测试

insert

flush

delete

deleteFolder

syncDeleteDataFiles

removePartitions

deleteTsFile

checkTTL

upgrade

sync

load

move

removeFullyOverlapFiles(分布式Snapshot)

query

测试场景配置

顺序文件空间内合并为核心的测试

序号

场景设置(仅列出需要修改的配置)

场景描述

目标状态

1

concurrent_compaction_thread=0

插入两个文件

手动merge

concurrent_compaction_thread=0即系统不允许合并,写入文件以检查此时系统是否合并

 

系统中仍存在两个文件

2

enable_unseq_space_compaction=false

enable_cross_space_compaction=false

concurrent_compaction_thread=1

插入两个顺序文件

手动merge

concurrent_compaction_thread=1即系统每次只允许一次合并,关闭文件空间内乱序合并和跨文件空间合并,写入顺序文件以检查此时系统是否合并


系统中仅存在一个文件

3

enable_unseq_space_compaction=false

enable_cross_space_compaction=false

concurrent_compaction_thread=1

target_compaction_file_size=1000

compaction_interval=100000

插入五个顺序文件(大小分别为f1:100,f2:200,f3:800,f4:100,f5:2000)这里为bytes

手动merge

 concurrent_compaction_thread=1即系统每次只允许一次合并,关闭文件空间内乱序合并和跨文件空间合并,设置目标文件大小为1000,理论上此时一次合并应该只合并f2,f3,f4三个文件,因此合并完最后剩下f1,f2',f5


系统中仅存在三个文件,且f1和f5没有变化,f2‘查出来的数据=f2+f3+f4

4

enable_unseq_space_compaction=false

enable_cross_space_compaction=false

concurrent_compaction_thread=2

target_compaction_file_size=1000

compaction_interval=100000

插入六个顺序文件(大小分别为f1:100,f2:200,f3:200,f4:800,f5:150,f6:2000)这里为bytes

手动merge

concurrent_compaction_thread=2即系统每次允许两次合并,关闭文件空间内乱序合并和跨文件空间合并,设置目标文件大小为1000,理论上此时两次合并应该同时合并f1,f2两个文件和f3,f4,f5三个文件,因此合并完最后剩下f1',f2',f6

系统中仅存在三个文件,且f6没有变化,f1‘查出来的数据=f1+f2,f3‘查出来的数据=f3+f4+f5

5

enable_unseq_space_compaction=false

enable_cross_space_compaction=false

concurrent_compaction_thread=2

target_compaction_file_size=1000

compaction_interval=100000

merge_chunk_point_number=150

插入六个顺序文件(大小分别为f1:100,f2:200,f3:200,f4:800,f5:150,f6:2000)这里为点数(point num)

手动merge

文件个数同上,且合并后的chunk大小与合并前一致。

系统中仅存在三个文件,且f6没有变化,point_num(f1'-chunk1)=point_num(f1)+point_num(f2),point_num(f3'-chunk1)=point_num(f3),point_num(f3'-chunk2)=point_num(f4),point_num(f3'-chunk3)=point_num(f5)

6

enable_unseq_space_compaction=false

enable_cross_space_compaction=false

concurrent_compaction_thread=1

target_compaction_file_size=10

compaction_interval=100000

merge_chunk_point_number=150

merge_page_point_number=2

插入六个顺序文件(大小分别为f1:200,f2:150,f3:3,f4:2,f5:5,f6:1,f7:3)这里为点数(point num)

手动merge

检查中间状态t1

target_compaction_file_size=200

手动merge

检查中间状态t2

target_compaction_file_size=1000

手动merge

检查最终状态t3

先进行解page合并,再进不解page合并,再进行不解chunk合并

t1:{

f1:200, f2:150, f3:3, f4':11(解page)

}

t2:{

f1:200, f2':164(不解page)

}

t3:{

f1':200+164(不解chunk)

}

7

enable_unseq_space_compaction=false

enable_cross_space_compaction=false

concurrent_compaction_thread=2

target_compaction_file_size=1000

compaction_interval=100000

merge_chunk_point_number=150

插入六个顺序文件(大小分别为f1:100,f2:200,f3:200,f4:800,f5:150,f6:2000)这里为点数(point num)

删除f3的后一半数据, f6的所有数据

手动merge

带删除的顺序数据合并,同时这里有一个注意点,在其中一个待合并文件有mods文件时,不管其他数据有多大,都进行解page合并

系统中仅存在三个文件,且f6没有变化,point_num(f1'-chunk1)=point_num(f1)+point_num(f2),size(f3'-chunk1)=point_num(f3)/2+point_num(f4)+point_num(f5),查询所有数据,等于删除f3的后一半数据, f6的所有数据的结果

8

enable_unseq_space_compaction=false

enable_cross_space_compaction=false

concurrent_compaction_thread=1

target_compaction_file_size=300

compaction_interval=100000

compaction_interval=1

插入九个大小(point num)为100的顺序文件

等待10s

测试定时合并任务提交间隔(连续合并)是否生效,这里暂时没法预估最终会收缩为多少个文件(压缩率无法预估)

最终文件数应该小于等于3

以乱序文件空间内合并为核心的测试

9

enable_cross_space_compaction=false

concurrent_compaction_thread=1

插入两个顺序文件,两个乱序文件

手动merge

检查中间状态t1

手动merge

检查最终状态t2

检查乱序文件空间合并


t1:顺序空间只有一个文件,乱序空间还有两个文件

t2:顺序空间和乱序空间都只有一个文件

10

enable_cross_space_compaction=false

concurrent_compaction_thread=1

target_compaction_file_size=1000

compaction_interval=100000

插入五个乱序文件(大小分别为f1:100,f2:200,f3:800,f4:100,f5:2000)这里为bytes

手动merge

 concurrent_compaction_thread=1即系统每次只允许一次合并,跨文件空间合并,设置目标文件大小为1000,理论上此时一次合并应该只合并f2,f3,f4三个文件,因此合并完最后剩下f1,f2',f5


系统中仅存在三个文件,且f1和f5没有变化,f2‘查出来的数据=f2+f3+f4

11

enable_cross_space_compaction=false

concurrent_compaction_thread=2

target_compaction_file_size=1000

compaction_interval=100000

插入六个乱序文件(大小分别为f1:100,f2:200,f3:200,f4:800,f5:150,f6:2000)这里为bytes

手动merge

concurrent_compaction_thread=2即系统每次允许两次合并,关闭文件空间内乱序合并合跨文件空间合并,设置目标文件大小为1000,理论上此时两次合并应该同时合并f1,f2两个文件和f3,f4,f5三个文件,因此合并完最后剩下f1',f2',f6

系统中仅存在三个文件,且f6没有变化,f1‘查出来的数据=f1+f2,f3‘查出来的数据=f3+f4+f5

12

enable_cross_space_compaction=false

concurrent_compaction_thread=2

target_compaction_file_size=1000

compaction_interval=100000

merge_chunk_point_number=150

插入六个顺序文件(大小分别为f1:100,f2:200,f3:200,f4:800,f5:150,f6:2000)这里为点数(point num)

手动merge

文件个数同上,且每个文件都只有一个chunk。

系统中仅存在三个文件,且f6没有变化,point_num(f1'-chunk1)=point_num(f1)+point_num(f2),point_num(f3'-chunk1)=point_num(f3)+point_num(f4)+point_num(f5)

13

enable_cross_space_compaction=false

concurrent_compaction_thread=1

target_compaction_file_size=10

compaction_interval=100000

merge_chunk_point_number=150

merge_page_point_number=2

插入六个顺序文件(大小分别为f1:200,f2:150,f3:3,f4:2,f5:5,f6:1,f7:3)这里为点数(point num)

手动merge

检查中间状态t1

target_compaction_file_size=200

手动merge

检查中间状态t2

target_compaction_file_size=1000

手动merge

检查最终状态t3

测试乱序文件空间内合并中,不管是文件大小是什么样的情况,都进行解page合并

t1:{

f1:200, f2:150, f3:3, f4':11

}

t2:{

f1:200, f2':164

}

t3:{

f1':364

}

14

enable_unseq_space_compaction=false

enable_cross_space_compaction=false

concurrent_compaction_thread=2

target_compaction_file_size=10000

compaction_interval=100000

merge_chunk_point_number=150

插入六个顺序文件(大小分别为f1:100,f2:200,f3:200,f4:800,f5:150,f6:2000)这里为点数(point num)

删除f3的后一半数据, f6的所有数据

手动merge

测试乱序文件空间内合并中,不管删不删除文件,都进行解page合并

系统中仅存在一个文件,查询所有数据,等于删除f3的后一半数据, f6的所有数据的结果

15

enable_cross_space_compaction=false

concurrent_compaction_thread=1

target_compaction_file_size=300

compaction_interval=1

插入九个大小(point num)为100的顺序文件

等待10s

测试定时合并任务提交间隔(连续合并)是否生效,这里暂时没法预估最终会收缩为多少个文件(压缩率无法预估)

最终文件数应该小于等于3

以跨文件空间合并为核心的测试

16

concurrent_compaction_thread=1

插入一个顺序文件,一个乱序文件

手动merge

检查跨文件空间合并


系统中仅存在一个顺序文件,且该文件数据=原顺序文件数据+原乱序文件数据

17

concurrent_compaction_thread=1

max_open_file_num_in_cross_space_compaction=1

插入一个顺序文件,两个乱序文件

手动merge

检查中间状态t1

手动merge

检查最终状态t2

 测试max_open_file_num_in_cross_space_compaction的限制,每次合并的最多乱序个数=max_open_file_num_in_cross_space_compaction


t1:系统中还有一个顺序文件,一个乱序文件

t2:系统中只有一个顺序文件,无乱序文件

18

concurrent_compaction_thread=2

max_open_file_num_in_cross_space_compaction=1

插入两个顺序文件,两个乱序文件

fseq1:0-100 fseq2:110-200

funseq1:80-120 funseq2:90-130

手动merge

手动merge

检查中间状态t1

手动merge

检查最终状态t2

测试跨文件空间合并选择文件的正确性,此时第一次merge应该选择,fseq1,fseq2,funseq1一起进行合并且重复提交也无法让funseq2同时进行合并,第二次merge应该选择fseq1,fseq2,funseq2fseq1,fseq2,funseq1

t1:{

fseq1:0-109

fseq2:110-200

funseq2:90-130

}

t2:{

fseq1:0-109

fseq2:110-200

}

19

concurrent_compaction_thread=2

max_open_file_num_in_cross_space_compaction=1

插入两个顺序文件,两个乱序文件

fseq1:0-100 fseq2:110-200

funseq1:80-90 funseq2:120-130

手动merge

手动merge

测试跨文件空间合并选择文件的正确性,此时第一次merge应该选择,fseq1,funseq1一起进行合并,但重复提交能让fseq2,funseq2同时进行合并

fseq1:0-100

fseq2:110-200

20

concurrent_compaction_thread=2

max_open_file_num_in_cross_space_compaction=1

插入两个顺序文件,两个乱序文件

fseq1:0-100 fseq2:110-200

funseq1:80-105 funseq2:120-130

手动merge

手动merge

测试跨文件空间合并选择文件的正确性,此时第一次merge应该选择,fseq1,fseq2,funseq1一起进行合并且重复提交也无法让funseq2同时进行合并,第二次merge应该选择fseq1,fseq2,funseq2fseq1,fseq2,funseq1

注意:这一场景的特点是实际funseq1和fseq2无重叠,但是要将fseq2提交到第一次合并去

fseq1:0-105

fseq2:110-200

funseq2:90-130

21

concurrent_compaction_thread=2

max_open_file_num_in_cross_space_compaction=1

插入两个顺序文件,两个乱序文件

fseq1:0-100 fseq2:110-200

funseq1:80-105 funseq2:120-210

删除数据205-210

手动merge

sleep 1

手动merge

测试跨文件空间合并能否让删除操作生效

fseq1:0-105

fseq2:110-205

22

concurrent_compaction_thread=1

compaction_interval=100000

compaction_interval=1

插入1个顺序文件(time:1-100 value:0),100个乱序文件,每个乱序文件只有一个点(time:50,value:{i}),且互相重叠(即对文件的更新操作)

等待10s

测试定时合并任务提交间隔(连续合并)是否生效,且同时测试文件的更新操作在跨文件空间合并后是否生效

系统中只有一个顺序文件,其中time(50)=100

混合测试

23

concurrent_compaction_thread=3

compaction_priority=balance

target_compaction_file_size=10

插入6个顺序文件,3个乱序文件

fseq1=1-10,fseq2=11-12,fseq3=12-13,fseq4=14-15,fseq5=16-17,fseq6=18-25

funseq1=1-9,funseq2=11-12,funseq3=12-20

手动merge

测试compaction_priority=balance


fseq1=1-10

fseq2=11-12

fseq3=12-13

fseq4'=14-25

funseq2'=11-20

24

concurrent_compaction_thread=3

target_compaction_file_size=10

插入6个顺序文件,3个乱序文件

fseq1=1-10,fseq2=11-12,fseq3=12-13,fseq4=14-15,fseq5=16-17,fseq6=18-25

funseq1=1-9,funseq2=11-12,funseq3=12-20

手动merge

 测试compaction_priority=inner_cross


fseq1=1-10

fseq2'=11-13

fseq4'=14-25

funseq1=1-9

funseq2'=11-20

25

concurrent_compaction_thread=3

target_compaction_file_size=10

插入3个顺序文件,4个乱序文件

fseq1=1-10,fseq2=11-12,fseq3=12-13

funseq1=1-9,funseq2=11-12,funseq3=12-20,funseq4=20-21

手动merge

测试compaction_priority=cross_inner

fseq1=1-10

fseq2=11-12

fseq3=12-20

funseq4=20-21

26

concurrent_compaction_thread=3

target_compaction_file_size=10

插入6个顺序文件,3个乱序文件

fseq1=1-10,fseq2=11-12,fseq3=12-13,fseq4=14-15,fseq5=16-17,fseq6=18-25

funseq1=1-9,funseq2=11-12,funseq3=12-20

手动merge

sleep 1

手动merge

测试先进行文件空间内合并,再进行跨文件空间合并

fseq1=1-10

fseq2'=11-13

fseq4'=14-25

27

concurrent_compaction_thread=3

target_compaction_file_size=10

插入6个顺序文件,3个乱序文件

fseq1=1-10,fseq2=11-12,fseq3=12-13,fseq4=14-15,fseq5=16-17,fseq6=18-25

funseq1=1-9,funseq2=11-12,funseq3=12-20

手动merge

sleep 1

delete 13-14

insert 24

手动merge

测试先进行文件空间内合并,再进行跨文件空间合并,中间穿插delete和update操作

fseq1=1-10

fseq2'=11-12

fseq4'=15-25

time(24)=new value

28

target_compaction_file_size=100000

compaction_interval=1

for i in range(10):

  插入10个顺序文件,10个乱序文件

sleep 20

测试较大数据量的文件自动合并

系统仅剩一个顺序文件,包含之前的所有数据

29

enable_cross_space_compaction=false

target_compaction_file_size=100000

compaction_interval=1

for i in range(10):

  插入10个顺序文件,10个乱序文件

sleep 20

测试较大数据量的文件自动合并,不开启跨文件空间合并

系统中只有一个顺序文件,和一个乱序文件
30

concurrent_compaction_thread=3

target_compaction_file_size=10

插入6个顺序文件,3个乱序文件,其中顺序文件有两个timeseries,乱序文件只有一个timeseries

fseq1=1-10,fseq2=11-12,fseq3=12-13,fseq4=14-15,fseq5=16-17,fseq6=18-25

funseq1=1-9,funseq2=11-12,funseq3=12-20

手动merge

测试timeseries不一致情况下的测试最终查询结果与一开始插入的数据一致,不报错
31

concurrent_compaction_thread=3

target_compaction_file_size=10

插入6个顺序文件,3个乱序文件,其中顺序文件有的两个timeseries,乱序文件有的有一个timeseries,有的有三个timeseries

fseq1=1-10,fseq2=11-12,fseq3=12-13,fseq4=14-15,fseq5=16-17,fseq6=18-25

funseq1=1-9,funseq2=11-12,funseq3=12-20

手动merge

测试timeseries不一致情况下的测试最终查询结果与一开始插入的数据一致,不报错
32

concurrent_compaction_thread=3

target_compaction_file_size=10

插入6个顺序文件,3个乱序文件,其中顺序文件有的两个timeseries,乱序文件有的有一个timeseries,有的有三个timeseries,整体删除一个timeseries

fseq1=1-10,fseq2=11-12,fseq3=12-13,fseq4=14-15,fseq5=16-17,fseq6=18-25

funseq1=1-9,funseq2=11-12,funseq3=12-20

手动merge

测试timeseries不一致情况下的测试,含删除最终查询结果与一开始插入和后面删除的数据一致,不报错
33

concurrent_compaction_thread=50

target_compaction_file_size=2

插入50个顺序文件,50个乱序文件(文件大小均为1)

手动merge

测试并行度是否生效顺序区剩下25个文件,乱序区剩下25个文件
  • No labels