# [Know Issue] tidb_mem_quota_query 设置无法控制单条 sql 的内存使用

## Key Words

tidb_mem_quota_query, TiDB OOM, Memory, Hash join

## Description

测试单条 sql 通过 tidb_mem_quota_query 参数控制内存使用时，发现有些 sql 能生效，有些 sql 不能生效。并且 tidb_enable_rate_limit_action 参数已经设置为 false。 通过抓取 TiDB 的火焰图发现大部分内存消耗在 `diskFormatRow`，读取路径为 `hashRowContainer.GetMatchedRowsAndPtrs --> RowContainer.GetRow --> ListInDisk.GetRow --> diskFormatRow.toMutRow`。

![tidb-oom-memory-quota.png](/images/TiDB/tidb-oom-memory-quota.png)

## Root Cause

Hash join 开启了 oom-use-tmp-storage 特性后，触发了落盘，但是在进行 Join 的时候需要重新将数据读取到内存中，这个部分内存没有被 Memory tracker 追踪识别到，因此tidb_mem_quota_query 设置无法控制这种场景下的 sql 内存使用。
相关 issue：[#35631](https://github.com/pingcap/tidb/issues/35631)

## Diagnostic Steps

1. TiDB Server 触发 OOM 或者内存占用异常。
2. 在内存异常占用期间使用抓取 profile，大量内存消耗在`diskFormatRow`，调用路径为 `hashRowContainer.GetMatchedRowsAndPtrs --> RowContainer.GetRow --> ListInDisk.GetRow --> diskFormatRow.toMutRow`。

## Resolution

升级到 v6.2.0 及以后版本。

## Workaround

如果 TiDB Server 触发 OOM，建议先禁用落盘功能，然后设置 tidb-oom-memory-quota 触发查询 cancel，从而避免 TiDB Server OOM。

## Affected Versions

 ~ v6.2.0
