求教 tidb-server heap内存一直在xG的级别是否正常

  • 【TiDB 版本】:
    v5.0.1

  • 【问题描述】:
    TiDB 内存 heap 占用高,请教状态是否正常。
    (tidb-server启动后,heap in_use就直接变成4.xG, 如果有大量更新/插入之后,很容易触发10G的报警)
    搜了asktug的帖子看到别人好像都是MB级别的状态~

  • 内存监控图

  • 服务器执行了pprof后
    top内容如下:

(pprof) top
Showing nodes accounting for 4.45GB, 97.84% of 4.55GB total
Dropped 209 nodes (cum <= 0.02GB)
Showing top 10 nodes out of 53
      flat  flat%   sum%        cum   cum%
    3.23GB 70.99% 70.99%     3.23GB 70.99%  github.com/pingcap/tidb/statistics.FMSketchFromProto
    0.52GB 11.52% 82.51%     0.52GB 11.52%  github.com/pingcap/tidb/store/copr.(*copIteratorWorker).handleCopResponse
    0.36GB  8.01% 90.52%     0.36GB  8.01%  github.com/pingcap/tidb/statistics.NewCMSketch
    0.06GB  1.43% 91.95%     0.06GB  1.43%  reflect.New
    0.06GB  1.40% 93.35%     0.14GB  3.15%  github.com/pingcap/tidb/statistics.(*Histogram).AppendBucketWithNDV
    0.06GB  1.35% 94.70%     0.48GB 10.50%  github.com/pingcap/tidb/statistics/handle.(*Handle).initStatsHistograms4Chunk
    0.04GB  0.96% 95.66%     0.04GB  0.96%  github.com/pingcap/tidb/statistics.(*Histogram).PreCalculateScalar
    0.04GB  0.93% 96.59%     0.08GB  1.72%  github.com/pingcap/tidb/util/chunk.(*Column).AppendBytes
    0.04GB  0.79% 97.38%     0.04GB  0.79%  github.com/pingcap/tidb/util/chunk.(*Column).finishAppendVar
    0.02GB  0.46% 97.84%     0.05GB  1.04%  github.com/pingcap/tidb/util/chunk.New
1赞

麻烦看下 dashboard 慢查询中是否有很多类似 sql
SELECT value FROM mysql.stats_fm_sketchWHEREtable_id= ? ANDis_index= ? ANDhist_id= ?

感谢回复。

  1. 这边slow_threshold之前设置的1s,后面改成默认300ms后,没有出现上面说的这个sql。
  2. 但是从流量可视化图里面能看到,stats_fm_sketch的读取还是很多的(写入看起来一般)(表内数据是20w条)
    具体见下图:

    image
  1. 麻烦查下 select @@tidb_partition_prune_mode; 的值
  2. SELECT count(*) FROM mysql.stats_fm_sketch; 的数据量。

数据如下:

MySQL [(none)]> select @@tidb_partition_prune_mode;
+-----------------------------+
| @@tidb_partition_prune_mode |
+-----------------------------+
| static                      |
+-----------------------------+
1 row in set (0.00 sec)

MySQL [(none)]> SELECT count(*) FROM mysql.stats_fm_sketch;
+----------+
| count(*) |
+----------+
|   201629 |
+----------+
1 row in set (0.00 sec)
MySQL [(none)]> SELECT count(*) FROM mysql.stats_meta;
+----------+
| count(*) |
+----------+
|    10450 |
+----------+
1 row in set (0.13 sec)
  1. 可以手工 delete 语句定期清空 mysql.stats_fm_sketch 中的数据:delete * from mysql.stats_fm_sketch。试试
  2. 感觉应该是这个,修复 PR :https://github.com/pingcap/tidb/pull/24357, 升级到 v5.0.2 及之后版本。

非常感谢~

刚刚去看了5.0.2的change log,发现还有下面的描述
(貌似我们的热力图也能看出来stats_histograms有很多读操作~)

Improvements

  • Avoid frequently reading the mysql.stats_histograms table if the cached statistics is up-to-date to avoid high CPU usage #24317

这边后面尝试下提供的方法看看。
多谢~

更新:

按照上面的建议

  1. 清空了stats_fm_sketch;
  2. cluster restart -R tidb;

结果如下:

  1. 监控面板看到HeapInuse目前降低到1.5G左右;
  2. pprof top内
    github.com/pingcap/tidb/statistics.FMSketchFromProto 的内存占用消失;

稍后找个机会考虑升级下版本。