使用一段时间后会出现oom问题,提示查询TDengine ERROR (0x73a): Query memory exhausted

【TDengine 使用环境】
生产环境

【TDengine 版本】3.3.8.8

【操作系统以及版本】linux

【部署方式】非容器部署

【集群节点数】

【集群副本数】

【描述业务影响】生产环境无法查询

【问题复现路径/shan】做过哪些操作出现的问题

【遇到的问题:问题现象及影响】

【资源配置】

【报错完整截图】(不要大段的粘贴报错代码,论坛直接看报错代码不直观)

TDengine ERROR (0x73a) desc: Query memory exhausted,Internal error: Query memory exhausted

您的 taosadapter 服务处于异常,请尝试重启 taosadapter 服务并保证服务可用

Query memory exhausted dnode 查询内存到达使用上限 设置合理的内存上限或调整并发查询量或增大系统内存

是内存不够了

和我的查询方法有关系吗,我分页查询使用了limit offset的方式,然后还有count(*)计算总数的操作

具体表有多少数据量?

sql 语句是什么?

子表数量大约多少?

服务器cpu\内存配置是什么?

目前大概单张子表两万条,sql分别是

<select id="selectCount" resultType="java.lang.Long">
    SELECT COUNT(*)
    FROM ${subTable}
    WHERE 1=1
    <if test="deviceId != null and deviceId != ''">
        AND device_id = #{deviceId}
    </if>
    <if test="deviceTime != null and deviceTime.length == 2">
        AND device_time BETWEEN #{deviceTime[0]} AND #{deviceTime[1]}
    </if>
</select>和
<select id="selectPageList" resultMap="BaseResultMapVO" parameterType="map">
        SELECT
        device_time,
        warn_bit,
        status_bit,
        longitude,
        latitude,
        altitude,
        speed,
        direction,
        ROUND(inner_voltage * 0.1, 1) AS inner_voltage,
        ROUND(outside_voltage * 0.1, 1) AS outside_voltage,
        soc,
        ROUND(total_current * 0.1, 1) AS total_current,
        signal_strength,
        gnss_count,
        voltages,
        temperatures,
        voltage_max,
        voltage_min,
        temperature_max,
        temperature_min,
        hotplate_temperature_1,
        hotplate_temperature_2,
        post_temperature_1,
        post_temperature_2,
        pcb_temperature_1,
        pcb_temperature_2,
        discharging_capacity_total,
        charging_capacity_total,
        internal_resistance,
        equilibrium_bit,
        acceleration_x,
        acceleration_y,
        acceleration_z,
        local_start_count,
        remote_start_count,
        mileages,
        voltage_count,
        temperature_count,
        soh,
        short_circuits_total
        FROM ${subTable}
        WHERE 1=1
        <if test="deviceId != null and deviceId != ''">
            AND device_id = #{deviceId}
        </if>
        <if test="deviceTime != null and deviceTime.length == 2">
            AND device_time BETWEEN #{deviceTime[0]} AND #{deviceTime[1]}
        </if>
        <if test="warnBit != null and warnBit != ''">
            AND warn_bit &amp; #{warnBit} != 0
        </if>
        ORDER BY device_time DESC
        LIMIT #{offset}, #{limit}
    </select>子表目前为两千出头一点,后期预计10w左右,服务器配置为8核16G

queryUseMemoryPool

  • 说明:查询是否使用内存池管理内存

  • 类型:整数;0:关闭;1:打开 当内存池开关打开时,还需要满足如下条件才会启用内存池:1. 系统的可用内存总量不低于 5G;2. 扣除预留部分后系统的可用内存不低于4G

  • 默认值:1

  • 最小值:0

  • 最大值:1

  • 参数类型:局部配置参数

  • 动态修改:支持通过 SQL 修改,重启后效。

  • 支持版本:v3.3.5.0 引入

minReservedMemorySize

  • 说明:内存池开启时,最小预留的系统可用内存数量,除预留外的内存都可以被用于查询。

  • 类型:整数

  • 单位:MB

  • 默认值:系统物理内存的 20%

  • 最小值:1024

  • 最大值:1000000000

  • 参数类型:局部配置参数

  • 动态修改:支持通过 SQL 修改,立即生效。

  • 支持版本:v3.3.5.0 引入

alter all dnodes ‘queryUseMemoryPool 0’;

alter all dnodes ‘minReservedMemorySize 1024‘; 这样修改一下,然后重启下 taosd 再试下

这是之前的内存变化,我观察内存余量走势如下图,产品是没有释放内存的机制吗,内存用量会随时间越来越大?需要定期重启?

有相关的内存诊断工具吗

做了很多配置上的调整,内存还是不停上升,没有稳定或者释放的过程,只能手动释放,这是产品的缺陷吗?

TDengine TSDB 的内存的管理比较平衡,不会立刻释放。
可以采用 jemalloc 内存分配器替代默认的glibc , jemalloc 内存回收比较快。

内存还是不断上升,所以说这个是产品的缺陷吗,如果是的话就不折腾了

这个图的内存使用是taosd的内存,还是所有TDengine组件的??
每个组件的内存占用分别是多少?

这个SQL包含普通列(warn_bit)过滤+排序(order by desc) 确实会占用大量内存