TiDB 内存控制文档

    • 如果上面的配置项使用的是 “log”,那么当一条 SQL 的内存使用超过一定阈值(由 session 变量 来控制)后,TiDB 会在 log 文件中打印一条 LOG,然后这条 SQL 继续执行,之后如果发生了 OOM 可以在 LOG 中找到对应的 SQL。
    • 如果上面的配置项使用的是 “cancel”,那么当一条 SQL 的内存使用超过一定阈值后,TiDB 会立即中断这条 SQL 的执行并给客户端返回一个 error,error 信息中会详细写明这条 SQL 执行过程中各个占用内存比较多的物理执行算子的内存使用情况。

    可以在配置文件中设置每个 Query 默认的 Memory Quota,例如将其设置为 32GB:

    1. mem-quota-query = 34359738368

    此外还可通过如下几个 session 变量来控制一条 Query 中的内存使用,大多数用户只需要设置 tidb_mem_quota_query 即可,其他变量是高级配置,大多数用户不需要关心:

    几个使用例子:

    配置整条 SQL 的内存使用阈值为 8GB:

    配置整条 SQL 的内存使用阈值为 8MB:

    1. set @@tidb_mem_quota_query = 8 << 20;

    可以在配置文件中设置 tidb-server 实例的内存使用阈值。相关配置项为 。

    例如,配置 tidb-server 实例的内存使用总量,将其设置成为 32 GB:

    1. server-memory-quota = 34359738368

    在该配置下,当 tidb-server 实例内存使用到达 32 GB 时,正在执行的 SQL 语句会被随机强制终止,直至 tidb-server 实例内存使用下降到 32 GB 以下。被强制终止的 SQL 操作会向客户端返回 Out Of Global Memory Limit! 错误信息。

    默认配置下,tidb-server 实例会在机器内存使用达到总内存量的 80% 时打印报警日志,并记录相关状态文件。该内存使用率可以通过配置项 进行设置。具体报警规则请参考该配置项的说明部分。

    下例通过构造一个占用大量内存的 SQL 语句触发报警,对该报警功能进行演示:

    1. 配置报警比例为 0.8

    2. 创建单表 CREATE TABLE t(a int); 并插入 1000 行数据。

    3. 执行 select * from t t1 join t t1 join t t3 order by t1.a。该 SQL 语句会输出 1000000000 条记录,占用巨大的内存,进而触发报警。

    4. 检查 tidb.log 文件,其中会记录系统总内存、系统当前内存使用量、tidb-server 实例的内存使用量以及状态文件所在目录。

        • is server-memory-quota set:表示配置项 是否被设置
        • system memory total:表示当前系统的总内存
        • system memory usage:表示当前系统的内存使用量
        • :表示 tidb-server 实例的内存使用量
        • memory-usage-alarm-ratio:表示配置项 memory-usage-alarm-ratio 的值
        • record path:表示状态文件存放的目录
      1. 通过访问状态文件所在目录(该示例中的目录为 /tmp/1000_tidb/MC4wLjAuMDo0MDAwLzAuMC4wLjA6MTAwODA=/tmp-storage/record),可以得到一组文件,其中包括 goroutinueheaprunning_sql 3 个文件,文件以记录状态文件的时间为后缀。这 3 个文件分别用来记录报警时的 goroutine 栈信息,堆内存使用状态,及正在运行的 SQL 信息。其中 running_sql 文件内的日志格式请参考 。