现象描述
TDSQL Boundless 实例在运行过程中,内存使用率持续处于高位或出现突增,可能伴随以下现象:
实例监控面板中内存使用率持续超过80%。
查询响应时间变长,出现间歇性卡顿。
新连接建立失败或被拒绝。
节点因 OOM(Out Of Memory)触发重启,可能导致主备切换。
您可在 TDSQL Boundless 控制台的实例详情 > 监控告警 > 指标监控页面中查看各节点的内存使用率指标。
故障风险
内存使用率过高可能导致以下风险:
节点触发 OOM 后自动重启,正在执行的事务中断。
存储节点(DN)OOM 可能触发主备切换,切换期间业务出现秒级闪断。
计算节点(CN)OOM 会导致该节点上的所有会话断开,需重新连接。
业务高峰期发生 OOM 或主备切换,会严重影响业务稳定性和连续性。
可能原因
TDSQL Boundless 的内存消耗主要来源于以下几类,OOM 可能由任一类内存的异常增长引发。
会话级私有内存
每个数据库连接在执行 SQL 时会独立分配私有内存缓冲区,并发连接数越多、单条 SQL 消耗的缓冲区越大,私有内存总量就越高。
低效 SQL 或全表扫描:缺少索引或执行计划不佳的 SQL 会触发大量排序和临时表操作,导致单个会话的私有内存缓冲区被反复分配,内存占用急剧上升。
全局共享内存
全局共享内存在实例启动时预分配,所有连接共享访问。
Block Cache 不足:Block Cache 大小不足以缓存热点数据,大量读请求穿透到磁盘,导致 I/O 压力增大。Block Cache 大小由实例内存规格决定,不支持单独调整。
Write Buffer 积压:存储引擎的 MemTable 在写入高峰期积压大量内存,通常与大批量写入操作有关。
事务内存
大事务和批量导入会在事务执行期间持有大量内存。
实例规格不匹配
内存规格不足:实例配置的内存规格无法满足业务实际负载需求。
内存与 CPU 比例失衡:CPU 扩容后内存未同步调整,导致内存成为瓶颈。
解决思路
TDSQL Boundless 的内存管理以实例内存规格为核心,实例启动时根据内存规格自动计算并联动设置最大连接数、Block Cache 大小、表缓存内存上限等参数。处理内存使用率过高问题的整体思路如下:
1. 查看监控:通过控制台监控确认内存使用趋势和异常时间点。
2. 定位内存消耗来源:通过系统视图查看各内存组件的占用分布,判断是共享内存、私有内存还是事务内存的问题。
3. 优化 SQL 和连接:优化低效 SQL、减少无效长连接,降低会话级私有内存消耗。
4. 调整参数:通过控制台参数设置页面调整用户可见的内存相关参数。
5. 扩容升级:优化后仍无法满足需求时,升级实例内存规格。
处理步骤
步骤1:查看内存监控
2. 选择监控告警 > 指标监控页签,查看各节点的内存使用率曲线。
3. 重点关注以下信息:
内存使用率是否持续超过80%。
是否存在突增(短时间内急剧上升)。
突增时间点是否与业务高峰、批量任务执行时间吻合。
4. 如需更细粒度的内存分布信息,执行步骤2。
步骤2:查看内存使用详情
通过系统视图查看各内存组件的占用情况,判断内存消耗的主要来源。
1. 连接数据库实例,执行以下 SQL 查看 LogService 内存统计信息。
SELECT * FROM information_schema.LOGSERVICE_MEMORY_STAT;
该视图展示各内存组件的当前使用量和总量,帮助您快速定位内存消耗大户。
2. 执行以下 SQL 查看 performance_schema 中的内存汇总信息(适用于已开启 performance_schema 的实例)。
SELECT
EVENT_NAME,
CURRENT_NUMBER_OF_BYTES_USED / 1024 / 1024 AS CURRENT_MB,
HIGH_NUMBER_OF_BYTES_USED / 1024 / 1024 AS HIGH_MB
FROM performance_schema.memory_summary_global_by_event_name
WHERE CURRENT_NUMBER_OF_BYTES_USED > 0
ORDER BY CURRENT_NUMBER_OF_BYTES_USED DESC
LIMIT 20;
该查询列出当前内存占用最高的20个内存事件,帮助您定位具体的内存消耗来源。
步骤3:优化慢 SQL
慢 SQL 是导致会话级私有内存异常增长的常见原因。通过 DBbrain 智能诊断或手动排查,优化低效 SQL。
2. 连接数据库实例,执行以下 SQL 查看当前正在执行的高消耗 SQL。
SELECT
ID,
USER,
HOST,
DB,
COMMAND,
TIME,
STATE,
INFO
FROM information_schema.PROCESSLIST
WHERE COMMAND != 'Sleep'
ORDER BY TIME DESC
LIMIT 20;
重点关注 TIME 值较大且 STATE 包含 Sorting result、Creating sort index、Sending data 等状态的会话,这些会话通常正在消耗大量排序或连接缓冲区。
3. 对识别出的慢 SQL 进行优化:
添加合适的索引,避免全表扫描。
避免在 SQL 中对大结果集进行排序或分组。
拆分复杂大查询为多个小查询。
步骤4:减少无效连接
连接数过多会导致会话级私有内存总量过大。
3. 选择监控告警 > 指标监控页签,查看当前连接数指标,确认实际并发连接数是否接近 max_connections 的上限。
4. 连接数据库实例,执行以下 SQL 查看各来源的连接分布,定位连接数过多的来源。
SELECT
SUBSTRING_INDEX(HOST, ':', 1) AS CLIENT_HOST,
COUNT(*) AS CONNECTION_COUNT
FROM information_schema.PROCESSLIST
GROUP BY CLIENT_HOST
ORDER BY CONNECTION_COUNT DESC;
5. 根据查询结果,采取以下措施:
降低应用程序侧连接池的最大连接数配置,使其与 max_connections 合理匹配。
排查是否存在连接泄漏(连接未正确关闭)。
对非核心业务进行限流或错峰执行。
6. 如需调整最大连接数(max_connections ),详细请参见 设置实例参数。 步骤5:查看 Block Cache 命中数
Block Cache 是 TDStore 存储引擎的核心缓存,命中数持续偏低说明当前 Block Cache 大小不足,大量读请求穿透到磁盘导致 I/O 压力增大,建议评估是否需要扩容内存规格以增大 Block Cache。
2. 选择监控告警 > 指标监控页签,切换到节点维度,查找 DataDB BlockCache 命中数指标曲线。
3. 关注命中数趋势:
命中数持续偏低,说明 Block Cache 缓存效果不佳,大量读请求穿透到磁盘。
可结合读 IOPS、读 I/O 吞吐量等指标综合判断磁盘读压力。
4. 若命中数持续偏低,可考虑以下措施:
优化查询模式,减少大范围扫描。
Block Cache 大小由实例内存规格决定,不支持单独调整,如需增大 Block Cache 请参见 升级实例内存规格。 步骤6:查看事务内存参数
大事务和批量导入会在事务执行期间占用大量内存。
2. 选择参数设置 > 数据库参数页签,查看以下事务内存相关参数的当前值:
|
| 单个事务的内存使用上限,默认1GB。 |
| 批量导入合并缓冲区总大小。 |
3. 若发现内存使用率在批量任务执行期间突增,可适当调低相关参数限制。
注意:
调低事务内存上限可能导致大批量写入操作被限制或报错,请根据业务实际情况谨慎调整,并在低峰期验证。
步骤7:通过控制台调整参数
根据排查结果,调整以下用户可见的内存相关参数,详细请参见 设置实例参数。 |
| 最大连接数。连接数过多会导致会话级私有内存总量过大。 | 根据业务实际并发需求设置,避免设置过高。 |
| 表打开缓存数量。设置过大会占用过多内存。 | 根据实例表数量合理设置,不宜过大。 |
| 表定义缓存数量。设置过大会占用过多内存。 | 根据实例表数量合理设置,不宜过大。 |
| 单个事务的内存使用上限。 | 若大事务导致内存突增,可适当调小。 |
| 批量导入合并缓冲区总大小。 | 若批量导入导致内存突增,可适当调小。 |
步骤8:升级实例内存规格
若经过以上优化后,内存使用率仍持续超过80%且影响业务正常运行,建议升级实例内存规格。升级后实例内存规格会自动更新,系统将根据新的内存规格自动联动调整最大连接数、Block Cache 大小、表缓存内存上限等参数。详细操作请参见 调整实例配置。 预防措施
为避免内存使用率过高问题反复发生,建议采取以下预防措施:
配置告警策略:在控制台为实例配置内存使用率告警,建议阈值设为80%,提前发现内存增长趋势。
定期巡检慢 SQL:通过 DBbrain 智能诊断定期检查慢 SQL,及时优化低效查询。
合理设置连接池:应用程序侧连接池大小应与实例 max_connections 合理匹配,避免连接数过多。
控制批量任务规模:大批量写入操作建议分批执行,单批次数据量控制在合理范围内。
监控 Block Cache 命中数:定期关注控制台监控面板中的 DataDB BlockCache 命中数指标,命中数持续偏低时考虑扩容。