tidb应该推出 限定一条语句走tiflash 的hint

tidb的sql 走tiflash执行计划的时候,应该有个hint限制在tiflash上的最大内存,这样超出内存后就落盘,免得导致tiflash内存不断的上涨

TiFlash 内存控制这块确实是个痛点。目前可以用两个思路缓解:

  1. 全局配置 tiflash_max_memory_usagetiflash_max_memory_usage_for_all_queries 限制整体内存,但这个粒度比较粗。

是的,而且执行计划都不显示 tiflash 的内存,不友好

  • 强制单语句走 TiFlash:现成 Hint READ_FROM_STORAGE(tiflash[table])
  • v6.5.12 仅支持算子粒度落盘,缺少整条查询内存上限
  • v7.4+ 正式上线你需要的能力:tiflash_mem_quota_query_per_node + tiflash_query_spill_ratio,超限自动落盘
  • 当前缺少SQL‑Hint 直接指定 TiFlash 查询内存阈值,属于非常有价值的功能优化点
1 个赞

诉求合理:可用会话/全局 mem 限额与 TiFlash 落盘参数控制尖峰,hint 级更细粒度目前要看版本文档是否已支持。现阶段先用资源管控+查询级内存上限,超限取消或落盘,避免把 TiFlash 打满。

这个诉求合理:AP 语句打到 TiFlash 时,确实希望有语句级内存上限 + spill,避免把 TiFlash 节点内存顶满。

现状侧可先做的控制:用隔离副本/资源组限制大查询影响面;通过 SQL 优化与投影下推减少中间态;关注 TiFlash 相关内存与 spill 配置(版本能力以官方文档为准);对超大查询用限流、超时、分批。

语句级「限定走 TiFlash 且 mem/spill」的 hint 属于产品增强,建议到 AskTUG/GitHub 提 feature request,并附典型 SQL 与内存曲线,便于评估优先级。

TiDB 已有强制指定 TiFlash、查询级内存限制和自动落盘能力,但目前不能通过一个 Hint 同时设置“单条 SQL 的 TiFlash 总内存上限”。因此这是一个合理的功能增强诉求,现有证据不足以定性为产品缺陷。

适用版本:

  • READ_FROM_STORAGE(TIFLASH[表名]) 可在语句级指定 TiFlash。
  • TiFlash 从 v7.0.0 起支持部分执行算子落盘。
  • 从 v7.4.0 起,可通过以下会话/全局变量控制单条查询在每个 TiFlash 节点上的内存和落盘阈值:
SET SESSION tiflash_mem_quota_query_per_node = 8589934592;
SET SESSION tiflash_query_spill_ratio = 0.7;

但官方变量说明中,这两个变量均为 Applies to hint SET_VAR: No,所以不能写成:

/*+ SET_VAR(tiflash_mem_quota_query_per_node=...) */

建议诊断时执行:

SELECT VERSION();
SHOW VARIABLES LIKE 'tiflash_mem_quota_query_per_node';
SHOW VARIABLES LIKE 'tiflash_query_spill_ratio';
EXPLAIN ANALYZE <原SQL>;

同时检查 TiFlash 日志中的峰值内存和 spill 记录,确认主要消耗来自 Sort、Hash Join、Hash Aggregation,还是不支持落盘的算子。

风险:设置过低会频繁落盘,增加磁盘 IO 和查询延迟;并非所有算子都支持 spill,即使配置查询级限制,也可能因非落盘算子内存过高而终止查询。建议先在会话级和测试环境验证,不要直接修改全局值。

还请楼主补充 TiDB 版本、完整 SQL、EXPLAIN ANALYZE、TiFlash 节点内存、并发数,以及问题期间的 TiFlash 内存和 spill 曲线。如果核心诉求确实是 Hint 级总内存限制,建议携带这些材料提交 Feature Request。

有类似的控制,不过严格来说不是“超过 TiFlash 最大内存后再落盘”。TiDB 7.0 以后,TiFlash 的 HashAgg、HashJoin、Sort/TopN 这类支持 Spill 的算子,可以通过 SET_VAR Hint 设置对应的内存阈值,例如 tidb_max_bytes_before_tiflash_external_group_bytidb_max_bytes_before_tiflash_external_jointidb_max_bytes_before_tiflash_external_sort,达到阈值后会把部分中间数据落盘。7.4 以后又增加了查询级的 tiflash_mem_quota_query_per_nodetiflash_query_spill_ratio,可以从单个 TiFlash 节点上控制一条查询的内存和触发落盘的比例。需要注意的是,并不是所有算子都支持 Spill,所以不能理解成给 SQL 设一个内存值以后,超过的部分一定都会自动落盘;如果主要耗内存的算子不支持落盘,或者最终还是碰到查询内存上限,查询仍然可能被终止。

啥时候能落实这个建议