You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

需求

当一条查询sql涉及的列数过多,如: select * from root;服务器端内存无法容纳这么多列的查询结果集,就会抛出OOM异常。这条异常查询还会影响到其他正常查询。


解决方案

总体思想

限制每条查询能够涉及的总列数上限(由配置文件中的max_deduplicated_path_num参数决定,默认值为1000),单次查询实际能够涉及的列数与指定的fetch_size有关,fetch_size越大,则列数越小。


  1. 所有查询结果集总内存:allocateMemoryForReadWithoutCache。默认占查询总分配内存的3/10,由配置参数chunkmeta_chunk_timeseriesmeta_free_memory_proportion决定
  2. 单个点占内存16B,这个版本不考虑text类型的点。
  3. 在QueryResourceManager中维护查询剩余可用总内存,以及每个查询预估占用内存。
  4. 对于一个新查询的到来,根据公式Math.min((int) ((totalFreeMemoryForRead.get() / fetchSize) / POINT_ESTIMATED_SIZE),MAX_COLUMN_SUM)计算得到该查询最大的列数。
  5. 构建查询计划时
    1. 若发现实际列数超过步骤4得到的最大列数,则抛出PathNumOverLimitException异常,查询返回。
    2. 若发现实际列数低于步骤4得到的最大列数,在向QueryResourceManager申请queryID的同时,将fetch_size和actual_column_num作为参数传递,QueryResourceManager中计算该查询预计需要占用的内存,并更新查询剩余可用总内存。
      1. 若更新后小于0,则查询失败;
      2. 若更新成功,则在内部记录该queryID对应查询的占用内存
  6. 查询结束时,向QueryResourceManager申请关闭查询资源时,再同时归还查询剩余可用总内存。
  • No labels