THIS IS A TEST INSTANCE. ALL YOUR CHANGES WILL BE LOST!!!!
需求
当一条查询sql涉及的列数过多,如: select * from root;服务器端内存无法容纳这么多列的查询结果集,就会抛出OOM异常。这条异常查询还会影响到其他正常查询。
解决方案
总体思想
限制每条查询能够涉及的总列数上限(由配置文件中的max_deduplicated_path_num参数决定,默认值为1000),单次查询实际能够涉及的列数与指定的fetch_size有关,fetch_size越大,则列数越小。
- 所有查询结果集总内存:allocateMemoryForReadWithoutCache。默认占查询总分配内存的3/10,由配置参数chunkmeta_chunk_timeseriesmeta_free_memory_proportion决定
- 单个点占内存16B,这个版本不考虑text类型的点。
- 在QueryResourceManager中维护查询剩余可用总内存,以及每个查询预估占用内存。
- 对于一个新查询的到来,根据公式Math.min((int) ((totalFreeMemoryForRead.get() / fetchSize) / POINT_ESTIMATED_SIZE),MAX_COLUMN_SUM)计算得到该查询最大的列数。
- 构建查询计划时
- 若发现实际列数超过步骤4得到的最大列数,则抛出PathNumOverLimitException异常,查询返回。
- 若发现实际列数低于步骤4得到的最大列数,在向QueryResourceManager申请queryID的同时,将fetch_size和actual_column_num作为参数传递,QueryResourceManager中计算该查询预计需要占用的内存,并更新查询剩余可用总内存。
- 若更新后小于0,则查询失败;
- 若更新成功,则在内部记录该queryID对应查询的占用内存
- 查询结束时,向QueryResourceManager申请关闭查询资源时,再同时归还查询剩余可用总内存。