
TDengine 常见问题 TOP7
TOP7 主题:内存占用高 / OOM / 查询内存耗尽
典型表现:内存一直涨不降、查询报
Query memory exhausted、进程被系统 OOM Killer 杀掉
为什么它是 TOP7
内存问题是社区里"最容易被误判"的一类问题:
- 社区典型帖:
- 《内存异常 停止数据写入 依旧内存占用较高 》------压测后内存停在 20G(32G 机器),停了写入脚本内存也不降,周末没写入也一样;
- 《使用一段时间后会出现 oom 问题,提示查询
TDengine ERROR (0x73a): Query memory exhausted》; - 《高并发查询 taosadapter 内存占用飙升,导致服务器内存耗尽》;
- 《Taosadapter 内存占用太高 》------大量写入查询后占用 30G,几小时不释放,关掉 Java 程序也不降。
- 它的误判率极高 :用户看到"内存不释放",第一反应是"内存泄漏",但 TDengine 的 vnode 是预分配内存 的,且操作系统有 page cache / 内存回收 机制,很多"占用高"其实是设计使然。
- 但它也确实会真出事 :查询内存耗尽会导致业务不可用,OS OOM Killer 会直接杀掉
taosd(表现为"数据库突然挂了")。
所以这篇的重点是:先分清"正常的预分配占用"和"真正的内存问题",再区分是 taosd 还是 taosAdapter,最后给出参数级优化。
一、症状大全(对号入座)
A. 内存占用高且不降
| # | 现象 | 指向 |
|---|---|---|
| A1 | 压测入库后内存稳定在 20G(32G 机器),停止写入后内存不降,甚至过周末也不降 | vnode 预分配 + OS 缓存,多数情况正常 |
| A2 | taosd 内存随运行时间持续增长 |
需看 vnode 数量与查询行为 |
| A3 | taosAdapter 内存涨到 6G / 30G,几小时不释放,关掉应用也不降 |
taosAdapter 侧问题(见 TOP2) |
| A4 | 内存"从没降下来过" | 需区分是 taosd 还是 OS cache |
| A5 | 系统整体内存吃紧,其他进程受影响 | 需重新规划内存 |
B. 查询内存耗尽
| # | 报错 / 现象 | 指向 |
|---|---|---|
| B1 | TDengine ERROR (0x73a): Query memory exhausted(0x8000073A) |
dnode 查询内存到达使用上限 |
| B2 | Internal error: Query memory exhausted |
同上 |
| B3 | memory exceeds threshold |
内存超过阈值 |
| B4 | 高并发查询(如多线程 + 大批量 union all)时服务器内存耗尽 |
查询并发/规模问题 |
| B5 | 报错同时提示 "您的 taosadapter 服务处于异常,请尝试重启 taosadapter 服务" | 需分清是 adapter 还是 taosd |
| B6 | 查询历史数据时经常失败 | 查询范围过大 |
C. OOM(进程被杀)
| # | 现象 | 指向 |
|---|---|---|
| C1 | taosd 进程突然消失,服务需要重启 |
大概率被 OOM Killer 杀掉 |
| C2 | dmesg 里出现 Out of memory: Killed process ... taosd |
确认 OOM |
| C3 | 剩余内存小于 vm.min_free_kbytes 时触发杀进程 |
OS 内存水位问题 |
| C4 | 内存"看起来很充足"但仍然 OOM | 可能是特殊内存地址/碎片问题 |
D. 配置与部署
| # | 现象 | 指向 |
|---|---|---|
| D1 | 改了 singleQueryMaxMemorySize 等参数不生效 |
3.4.0.0+ 需用 ALTER |
| D2 | 报 Invalid config option [0x80000119] |
参数名或版本不支持 |
| D3 | 容器内改内存参数无效 | 配置未挂载(见 TOP5) |
| D4 | 按"内存优化"文档操作 set_taos_malloc.sh 报错 |
脚本需在指定目录运行 |
| D5 | 建库报 Out of dnodes / Vnodes exhausted |
vnode 数量超限 |
二、原因分析
2.1 先搞清 TDengine 的内存构成
#mermaid-svg-ypHcXJfmLsDJheb0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ypHcXJfmLsDJheb0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ypHcXJfmLsDJheb0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ypHcXJfmLsDJheb0 .error-icon{fill:#552222;}#mermaid-svg-ypHcXJfmLsDJheb0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ypHcXJfmLsDJheb0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ypHcXJfmLsDJheb0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ypHcXJfmLsDJheb0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ypHcXJfmLsDJheb0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ypHcXJfmLsDJheb0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ypHcXJfmLsDJheb0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ypHcXJfmLsDJheb0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ypHcXJfmLsDJheb0 .marker.cross{stroke:#333333;}#mermaid-svg-ypHcXJfmLsDJheb0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ypHcXJfmLsDJheb0 p{margin:0;}#mermaid-svg-ypHcXJfmLsDJheb0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ypHcXJfmLsDJheb0 .cluster-label text{fill:#333;}#mermaid-svg-ypHcXJfmLsDJheb0 .cluster-label span{color:#333;}#mermaid-svg-ypHcXJfmLsDJheb0 .cluster-label span p{background-color:transparent;}#mermaid-svg-ypHcXJfmLsDJheb0 .label text,#mermaid-svg-ypHcXJfmLsDJheb0 span{fill:#333;color:#333;}#mermaid-svg-ypHcXJfmLsDJheb0 .node rect,#mermaid-svg-ypHcXJfmLsDJheb0 .node circle,#mermaid-svg-ypHcXJfmLsDJheb0 .node ellipse,#mermaid-svg-ypHcXJfmLsDJheb0 .node polygon,#mermaid-svg-ypHcXJfmLsDJheb0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ypHcXJfmLsDJheb0 .rough-node .label text,#mermaid-svg-ypHcXJfmLsDJheb0 .node .label text,#mermaid-svg-ypHcXJfmLsDJheb0 .image-shape .label,#mermaid-svg-ypHcXJfmLsDJheb0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-ypHcXJfmLsDJheb0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ypHcXJfmLsDJheb0 .rough-node .label,#mermaid-svg-ypHcXJfmLsDJheb0 .node .label,#mermaid-svg-ypHcXJfmLsDJheb0 .image-shape .label,#mermaid-svg-ypHcXJfmLsDJheb0 .icon-shape .label{text-align:center;}#mermaid-svg-ypHcXJfmLsDJheb0 .node.clickable{cursor:pointer;}#mermaid-svg-ypHcXJfmLsDJheb0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ypHcXJfmLsDJheb0 .arrowheadPath{fill:#333333;}#mermaid-svg-ypHcXJfmLsDJheb0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ypHcXJfmLsDJheb0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ypHcXJfmLsDJheb0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ypHcXJfmLsDJheb0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ypHcXJfmLsDJheb0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ypHcXJfmLsDJheb0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ypHcXJfmLsDJheb0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ypHcXJfmLsDJheb0 .cluster text{fill:#333;}#mermaid-svg-ypHcXJfmLsDJheb0 .cluster span{color:#333;}#mermaid-svg-ypHcXJfmLsDJheb0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ypHcXJfmLsDJheb0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ypHcXJfmLsDJheb0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-ypHcXJfmLsDJheb0 .icon-shape,#mermaid-svg-ypHcXJfmLsDJheb0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ypHcXJfmLsDJheb0 .icon-shape p,#mermaid-svg-ypHcXJfmLsDJheb0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ypHcXJfmLsDJheb0 .icon-shape .label rect,#mermaid-svg-ypHcXJfmLsDJheb0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ypHcXJfmLsDJheb0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ypHcXJfmLsDJheb0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ypHcXJfmLsDJheb0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} TDengine 内存占用
① vnode 预分配内存
(写入缓存,最主要)
② 查询执行内存
(排序、聚合、连接)
③ mnode / 系统开销
④ 组件进程
taosAdapter / taosKeeper / taosX
⑤ OS 层 page cache
(进程退出也不一定释放)
关键认识:vnode 内存是"预分配"的。
- 每个 vnode 会预先占用一块内存作为写入缓存。
- vnode 数量由建库时的
vgroups决定 ,单个 vnode 的内存大小受buffer等参数影响。 - 所以:建了很多库、每个库
vgroups很大 → 内存基线就很高,即使没有查询也一样。 - 这也是为什么"停止写入后内存不降"------它是预分配的,不是按需增长的。
官方 FAQ 原话:"TDengine 会预先为每个 vnode 分配内存。每个数据库的 vnode 数量受建库时
vgroups参数影响,每个 vnode 占用的内存大小受buffer等参数影响。"
2.2 OOM 的触发条件
操作系统 OOM 通常由两种情况触发:
- 剩余内存小于
vm.min_free_kbytes(内核保留水位); - 程序请求的内存大于剩余内存。
还有一种少见情况:内存充足但程序占用了特殊内存地址,也会触发 OOM。
官方建议:"为防止 OOM,须在建设初期合理规划内存并配置 SWAP;查询过量数据也可能导致内存暴涨。"
2.3 根因归类
| 类别 | 说明 | 对应症状 |
|---|---|---|
| ① vnode 预分配 | vgroups 过多 / buffer 过大 → 内存基线高 |
A1 A2 A4 D5 |
| ② 查询过量数据 | 大范围聚合、超大 IN、union all 拼接、无 LIMIT |
B1 B2 B4 B6 |
| ③ 查询并发过高 | 多线程大查询同时执行 | B4 |
| ④ 查询内存上限未设 | singleQueryMaxMemorySize=0(无上限) |
B1 B3 |
| ⑤ 内存池未启用 | queryUseMemoryPool=0 或条件不满足 |
B1 |
| ⑥ 组件侧内存问题 | taosAdapter 连接数/线程数失控 | A3 B5 |
| ⑦ OS 层面 | 未配 SWAP、vm.min_free_kbytes 不合理 |
C1 C2 C3 |
| ⑧ 配置未生效 | 3.4.0.0+ 改文件无效 |
D1 D2 D3 |
三、先搞懂内存参数:五个关键配置
| 参数 | 作用 | 默认值 | 动态修改 | 引入版本 |
|---|---|---|---|---|
buffer |
单个 vnode 的写入缓存大小 | 见版本文档 | --- | --- |
vgroups |
数据库的 vgroup 数量(建库时指定),直接决定 vnode 数量 | 2 | --- | 建库参数 |
supportVnodes |
dnode 支持的最大 vnode 数目 | CPU 核数 × 2 + 5 | 企业版支持 SQL 修改 | v3.0.0.0 |
queryUseMemoryPool |
查询是否使用内存池管理内存 | 1(打开) |
支持 SQL 修改,重启生效 | v3.3.5.0 |
minReservedMemorySize |
内存池开启时,最小预留 的系统可用内存(MB)。设为 0 时系统自动计算 |
0(自动) |
支持 SQL 修改,立即生效 | v3.3.5.0 |
singleQueryMaxMemorySize |
单个查询在单个 dnode 上的内存上限 (MB),超过则报错。0 = 无上限 |
0 |
不支持动态修改 | v3.3.5.0 |
queryUseMemoryPool 打开时的额外条件:
当内存池开关打开时,还需要满足两个条件才会实际启用内存池:
- 系统的可用内存总量不低于 5G;
- 扣除预留部分后系统的可用内存不低于 4G。
常用修改方式:
sql
-- 单个节点
ALTER DNODE <dnode_id> 'singleQueryMaxMemorySize' '10240'; -- 10G
-- 所有节点(全局参数只能用这个)
ALTER ALL DNODES 'singleQueryMaxMemorySize' '10240';
内存分配器优化脚本:
bash
# 必须在 /usr/local/taos/bin/ 下运行
cd /usr/local/taos/bin
./set_taos_malloc.sh -m 3 # 3 = jemalloc 优化(推荐用于稳定性优化)
| mode | 含义 |
|---|---|
0 |
glibc 默认分配器 |
1 |
tcmalloc 优化 |
2 |
tcmalloc 定制检查(内存泄漏检测) |
3 |
jemalloc 优化 |
4 |
jemalloc 定制检查(内存泄漏检测) |
脚本会生成环境变量文件:
- Shell:
/usr/local/taos/bin/set_taos_malloc_env.sh - systemd taosd:
/etc/default/taosd - systemd taosadapter:
/etc/default/taosadapter - 日志:
/var/log/taos/set_taos_malloc.log
改完需要重启服务(或重新 source 环境变量文件)。
官方说明:TDengine TSDB-Enterprise 对内存管理做了优化并采用新的内存分配器,对稳定性要求更高的用户可考虑选用企业版。
四、标准排查流程(照着做)
第 1 步:先确认是哪个进程内存高
bash
# 按内存排序看 TOP 进程
ps -eo pid,rss,vsz,pmem,comm --sort=-rss | head -20
# 分别看
ps -o pid,rss,vsz,pmem,cmd -p $(pgrep taosd)
ps -o pid,rss,vsz,pmem,cmd -p $(pgrep taosadapter)
# 线程级
top -Hp $(pgrep taosd)
top -Hp $(pgrep taosadapter)
| 谁高 | 去哪节看 |
|---|---|
taosd |
继续第 2 步 |
taosAdapter |
直接看 TOP2 场景 4(连接数/连接池问题) |
第 2 步:看系统整体内存与 SWAP
bash
free -h
vmstat 1 5
cat /proc/meminfo | head -10
重点看:
available是否充足;swap是否已配置(强烈建议配置 SWAP);si/so(swap in/out)是否频繁(说明已经在换页,性能会崩)。
第 3 步:确认是否发生过 OOM
bash
# 内核 OOM 记录
dmesg -T | grep -i "killed process"
dmesg -T | grep -i "out of memory"
# 内核保留水位
sysctl vm.min_free_kbytes
cat /proc/sys/vm/swappiness
若确认 taosd 是被 OOM 杀的:这不是"内存泄漏",而是内存总量/规划不足,按第 6、7 步处理。
第 4 步:确认 vnode 数量与内存基线
sql
-- 各 dnode 的 vnode 数量与上限
SHOW DNODES;
-- 每个库的 vgroup 数量
SHOW <db_name>.VGROUPS;
-- 查看实际配置
SHOW VARIABLES LIKE 'supportVnodes';
SHOW VARIABLES LIKE 'buffer';
估算内存基线:
text
内存基线 ≈ 总 vnode 数 × 单 vnode 内存(受 buffer 影响)
若"总 vnode 数"很大(例如几十个库 × 每个 2~10 个 vgroups),内存基线自然就高。
sql
-- 统计所有库的 vgroup 总数
SELECT name, vgroups FROM INFORMATION_SCHEMA.INS_DATABASES;
第 5 步:定位是否有"吃内存"的查询
sql
-- 当前正在执行的查询
SHOW QUERIES;
-- 连接数
SHOW CONNECTIONS;
典型"吃内存"写法:
| 反模式 | 问题 |
|---|---|
大范围无 LIMIT 的全表扫描 |
结果集全量驻留 |
超大 IN (...) 列表 |
表达式膨胀 |
单条 SQL 用 union all 拼几百个子查询 |
并发度高(社区有 500 个子句/批、8 线程并发的案例) |
超大基数的 GROUP BY |
分组状态占内存 |
| 多线程同时发起大查询 | 内存叠加 |
处理 :拆批、加时间范围、加 LIMIT、降低并发。
第 6 步:检查关键参数是否合理
sql
SHOW VARIABLES LIKE 'queryUseMemoryPool';
SHOW VARIABLES LIKE 'minReservedMemorySize';
SHOW VARIABLES LIKE 'singleQueryMaxMemorySize';
SHOW VARIABLES LIKE 'supportVnodes';
建议调整方向:
sql
-- ① 给单查询设内存上限,避免单个查询吃光内存
ALTER ALL DNODES 'singleQueryMaxMemorySize' '10240'; -- 10G,按机器内存调整
-- ② 确保内存池开启
ALTER ALL DNODES 'queryUseMemoryPool' '1'; -- 重启生效
-- ③ 设置合理的最小预留内存
ALTER ALL DNODES 'minReservedMemorySize' '2048'; -- 2G
⚠️ 注意:
3.4.0.0+起改配置文件不生效 ,必须用ALTER(参考 TOP4 场景 5)。若报Invalid config option [0x80000119],说明该参数在当前版本不支持动态修改。
第 7 步:检查 vnode 上限是否被打满
sql
-- 若建库报 Out of dnodes / Vnodes exhausted
SHOW DNODES; -- 看 support_vnodes 列
SHOW VARIABLES LIKE 'supportVnodes';
sql
-- 调大上限(企业版支持 SQL 修改)
ALTER ALL DNODES 'supportVnodes' '256';
bash
# 或改配置文件后重启(< 3.4.0.0)
vi /etc/taos/taos.cfg
# supportVnodes 256
sudo systemctl restart taosd
第 8 步:优化内存分配器
bash
cd /usr/local/taos/bin
./set_taos_malloc.sh -m 3 # jemalloc 优化
sudo systemctl restart taosd taosadapter
若怀疑内存泄漏,用检查模式并保留现场:
bash
./set_taos_malloc.sh -m 4 # jemalloc 定制检查
# 或
./set_taos_malloc.sh -m 2 # tcmalloc 定制检查
五、典型场景实操
场景 1:停止写入后内存不降(先别慌)
现象:压测入库后内存停在 20G,停了脚本也不降,周末没写入也一样。
判断:
bash
# ① 看进程 RSS 是否真的持续增长(而不是"停了就不降")
ps -o pid,rss,pmem,cmd -p $(pgrep taosd)
# 每隔几分钟观察一次
# ② 看系统 available 内存
free -h
# ③ 看是否还有后台任务(合并、落盘、流计算)
taos -s "show queries;"
结论:
| 情况 | 判断 |
|---|---|
| RSS 在写入停止后保持平稳(不涨) | ✅ 正常。vnode 预分配内存本来就不会主动归还 |
| RSS 在无写入时仍持续增长 | ⚠️ 需要进一步排查(查询/流/泄漏) |
available 充足 |
✅ 不用处理 |
available 紧张 |
按第 6 步调参 + 扩容内存 |
核心结论 :"占用高"不等于"有问题"。 判断标准是是否持续增长 和是否影响业务,而不是"是否降下来"。
场景 2:Query memory exhausted
报错 :TDengine ERROR (0x73a): Query memory exhausted(0x8000073A)
含义 :dnode 查询内存到达使用上限。
处理(按顺序):
sql
-- ① 找出正在跑的查询
SHOW QUERIES;
-- ② 定位吃内存的 SQL,判断能否优化
-- 缩小时间范围、加 LIMIT、拆批、减少 union all
sql
-- ③ 设置单查询内存上限,防止单查询拖垮节点
ALTER ALL DNODES 'singleQueryMaxMemorySize' '10240';
-- ④ 确认内存池开启
ALTER ALL DNODES 'queryUseMemoryPool' '1';
bash
# ⑤ 若确实需要更大内存,扩容或增加 vnode 分布
free -h
优化查询的具体做法:
sql
-- ❌ 差:全范围扫描 + 无上限
SELECT * FROM stb WHERE ts > '2020-01-01' ORDER BY ts;
-- ✅ 好:限定时间范围 + 明确列 + LIMIT
SELECT ts, col1, col2 FROM stb
WHERE ts >= '2026-09-01 00:00:00' AND ts < '2026-09-02 00:00:00'
ORDER BY ts LIMIT 10000;
场景 3:高并发查询打爆内存
现象 :多线程并发执行大批量 union all 查询,内存飙升,报 memory exceeds threshold。
处理:
sql
-- ① 降低并发:客户端限制并发线程数(如从 8 降到 2~4)
-- ② 拆批:把每批 500 个时间段降到 50~100 个
-- ③ 设置单查询上限
ALTER ALL DNODES 'singleQueryMaxMemorySize' '8192';
sql
-- ④ 观察
SHOW QUERIES;
根本解法 :评估是否可以用流计算预计算(见 TOP3),把大范围查询变成小范围点查。
场景 4:建库报 Out of dnodes / Vnodes exhausted
sql
-- 查看当前 dnode 的 vnode 上限与使用情况
SHOW DNODES;
-- 查看参数
SHOW VARIABLES LIKE 'supportVnodes';
sql
-- 调大上限(企业版)
ALTER ALL DNODES 'supportVnodes' '512';
bash
# 社区版:改配置文件 + 重启
sudo vi /etc/taos/taos.cfg
# supportVnodes 512
sudo systemctl restart taosd
注意 :supportVnodes 默认是 CPU 核数 × 2 + 5 ,最大值 1024 。调大它意味着更多 vnode → 更高内存基线,要同步评估内存。
场景 5:改了内存参数不生效
排查顺序:
- 版本 ≥
3.4.0.0? → 改配置文件无效,必须用ALTER(参考 TOP4 场景 5)。 - 参数是否支持动态修改?
queryUseMemoryPool:支持 SQL 改,但重启生效;minReservedMemorySize:支持 SQL 改,立即生效;singleQueryMaxMemorySize:不支持动态修改,需改配置 + 重启(且注意第 1 条)。
- 容器场景:配置目录是否挂载(参考 TOP5 场景 3)。
- 报
Invalid config option [0x80000119]:参数名拼错,或当前版本不支持该参数。
sql
-- 改完确认
SHOW VARIABLES LIKE 'singleQueryMaxMemorySize';
场景 6:set_taos_malloc.sh 报错
原因 :脚本必须在 TDengine 安装目录 /usr/local/taos/bin/ 下运行。
bash
# ✅ 正确
cd /usr/local/taos/bin
./set_taos_malloc.sh -m 3
# ❌ 在其他目录执行会报错
bash
# 容器内若没有该脚本,可从安装包中获取后放入容器
# 并确保 /usr/local/taos/bin 目录存在
bash
# 改完重启
sudo systemctl restart taosd taosadapter
# 验证环境变量是否写入
cat /etc/default/taosd
cat /etc/default/taosadapter
场景 7:OOM 后的完整处置
bash
# ① 确认是 OOM
dmesg -T | grep -i "killed process"
grep -i "out of memory" /var/log/messages 2>/dev/null
# ② 恢复服务
sudo systemctl start taosd
# ③ 检查数据完整性
taos -s "show databases;"
taos -s "show dnodes;"
taos -s "show vgroups;"
bash
# ④ 配置 SWAP(关键预防措施)
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# ⑤ 调整内核水位(谨慎)
sudo sysctl -w vm.min_free_kbytes=1048576
# 持久化
echo 'vm.min_free_kbytes=1048576' | sudo tee -a /etc/sysctl.conf
sql
-- ⑥ 限制单查询内存,降低再次 OOM 的概率
ALTER ALL DNODES 'singleQueryMaxMemorySize' '8192';
六、错误码 / 关键字速查
| 错误码 / 关键字 | 含义 | 处理方向 |
|---|---|---|
0x8000073A(0x73a) |
Query memory exhausted(dnode 查询内存到达使用上限) |
设内存上限 / 降并发 / 加内存 |
memory exceeds threshold |
内存超过阈值 | 同上 |
Out of dnodes |
建库所需 vnode 超过 dnode 上限 | 调大 supportVnodes |
Vnodes exhausted |
vnode 用尽 | 同上 |
0x80000119 |
Invalid config option |
参数名错或版本不支持 |
Killed process ... taosd(dmesg) |
OS OOM Killer | 加内存 + 配 SWAP + 限查询 |
Query memory exhausted + taosAdapter 异常提示 |
可能是 adapter 侧问题 | 检查 taosAdapter(TOP2) |
七、预防清单
- 建库前规划内存 :库数量 ×
vgroups× 单 vnode 内存 = 内存基线。 -
vgroups按写入并发合理设置,不要盲目调大。 -
supportVnodes按需调整,调大后同步评估内存。 - 必须配置 SWAP ,并合理设置
vm.min_free_kbytes。 - 设置
singleQueryMaxMemorySize,给单个查询设上限。 - 保持
queryUseMemoryPool=1,并设置合理的minReservedMemorySize。 - 查询侧规范:限定时间范围、加
LIMIT、拆批、避免超大union all/IN。 - 控制并发查询数,客户端连接池设上限。
- 对
taosd与taosadapter的 RSS 做长期监控 + 阈值告警。 - 怀疑泄漏时用
set_taos_malloc.sh -m 2 / -m 4做检查。 - 内存紧张时考虑升级到企业版(内存管理与分配器优化)。
- 定期
SHOW QUERIES巡检长耗时大查询。
八、求助模板(贴在社区里,回复会快很多)
text
【TDengine 使用环境】生产 / 预生产 / 测试 / PoC
【TDengine 版本】___
【操作系统及版本】___ 【机器配置】CPU ___ 核 / 内存 ___ G
【部署方式】容器 / 非容器
【集群节点数】___ 【副本数】___
【问题现象】内存持续增长 / 查询报错 / 进程被杀
【内存数据】
- free -h 输出:___
- taosd RSS:___ taosadapter RSS:___
- 是否配置 SWAP:___
【关键配置】
- SHOW DNODES(含 support_vnodes):___
- SHOW VARIABLES LIKE 'queryUseMemoryPool':___
- SHOW VARIABLES LIKE 'minReservedMemorySize':___
- SHOW VARIABLES LIKE 'singleQueryMaxMemorySize':___
- 库数量与各库 vgroups:___
【是否有 OOM】
- dmesg -T | grep -i "killed process":___
【查询情况】是否高并发 / 大范围查询 / union all
【日志】/var/log/taos 关键片段
九、相关链接
- 社区问答:https://ask.taosdata.com
- 提交 Issue:https://github.com/taosdata/TDengine/issues
- 官方文档:https://docs.taosdata.com
- 典型讨论帖:
本文整理自 TDengine 技术社区真实提问,覆盖 3.0 至 3.4 各版本的内存与容量问题。如果你遇到的情况不在上述症状列表中,欢迎到社区发帖并附上本文第八节的求助模板。