单次查询表数据太大超过1G触发了oom

这个没有涉及到排序,如果limit n,这个n值比较小则封装的task数较少大概率小于tidb_distsql_scan_concurrency则不容易oom,最大也是tidb_distsql_scan_concurrency=15(默认值),也就是最多使用内存15region_size,当然这种情况非常少,因为一个region中记录数太多了,你需要limit 几十万或者上百万才可能用到15个region,因此只是limit n情况几乎不需要考虑oom的问题。
你可能想要表达的是select xxx from xx order by cola limit n,cola不是索引列这种情况吧?首先这种情况下cop_task个数基本上是该表所有region数,但是针对每一个cop_task会将topN算子下推到tikv上执行,也就是针对每一个cop_task(这里基本上等同于region)均获取topN值,然后并发的返回tidb-server,那么tidb-server中最多缓存limit N * tidb_distsql_scan_concurrency记录数,所以这里会发生oom的概率很小。
进一步分析,假设你需要的是select cola ,count(
) from xx group by cola limit n; cola上并没有索引的情况下,是否会发生oom呢?这种涉及到聚合运算的如果数据离散度较低(重复度)一般情况下会在tikv层做hashagg聚合然后将数据拿到tidb层进行二次聚合运算发生oom的概率较小,如果数据离散度较高,大量数据放到tidb层做hashagg运算,那么默认配置下会有较大概率发生oom。
大数据量在tidb-server层如何控制其避免oom呢?首先要打开落盘相关参数,让一些算子能够进行落盘,但是hashagg在并发情况下并不能落盘,需要将tidb_hashagg_partial_concurrency,tidb_hashagg_final_concurrency均设置为1才能进行落盘,但是没有并发加持加之写入磁盘,效率会比较慢,但是避免了oom(这里只是理论上会避免oom,tidb的内存追踪评估在准确度上要进一步加强才能够完全避免oom)。

1 个赞