MySQL HeatWave 把 OLTP 和实时 OLAP 搬到同一套引擎上,省掉了 ETL 管道,查询性能也确实猛——但如果你没把容量算清楚,要么花钱买了一堆闲置节点,要么高峰期内存溢出导致分析查询被踢回 MySQL 执行,性能一夜回到解放前。这篇文章讲的是:用几条 SQL 就能把 HeatWave 当前的资源占用看明白,并据此推算你该加多少节点、该留多少余量。
HeatWave 的资源模型:先搞清楚"算的是什么"
HeatWave 的计算节点(即 OCI 上的 HeatWave Cluster)资源核心是 内存。数据以列存格式加载到节点内存中,查询全程在内存里跑——没有磁盘 I/O,这也是它快的原因。所以容量规划的本质问题就一个:
你的数据占多少内存?你的节点总共有多少内存?还剩多少?
每个 HeatWave 节点的内存规格是固定的,取决于你选的 shape:
| Shape | 每节点内存 |
|---|---|
| MySQL.HeatWave.VM.Standard.E3 | 16 GB |
| MySQL.HeatWave.VM.Standard.E3.8 | 64 GB |
| MySQL.HeatWave.VM.Standard.E3.16 | 128 GB |
| MySQL.HeatWave.VM.Standard.E3.24 | 256 GB |
| MySQL.HeatWave.VM.Standard.E3.32 | 512 GB |
一个集群由多个节点组成,总可用内存 = 节点数 × 单节点内存 × 0.75(约 25% 被 HeatWave 内部元数据和管理开销占用,实际可用比例随数据特征略有浮动)。
用 SQL 查清楚当前占用
HeatWave 提供了一组性能模式(Performance Schema)表和专用视图,让你直接在 MySQL 里查集群状态。以下查询都可以在连接到 MySQL 实例后直接运行。
查集群节点与总内存
-- 查看 HeatWave 集群节点数和 shape
SELECT
cluster_shape,
cluster_size AS node_count,
total_memory_gb
FROM performance_schema.rpd_cluster_status;
输出大致如下:
+----------------------+-----------+-----------------+
| cluster_shape | node_count| total_memory_gb |
+----------------------+-----------+-----------------+
| VM.Standard.E3.16 | 4 | 512 |
+----------------------+-----------+-----------------+
这里 total_memory_gb 是集群原始总内存。实际可用于数据加载的部分要打个折扣。
查已加载表的实际内存消耗
-- 每张已加载到 HeatWave 的表占多少内存
SELECT
table_schema,
table_name,
memory_estimated_gb,
memory_used_gb,
load_status
FROM performance_schema.rpd_table_stats
WHERE load_status = 'Loaded'
ORDER BY memory_used_gb DESC;
这个查询是容量规划的核心。memory_used_gb 是真实占用,memory_estimated_gb 是加载前的估算值。两者可能有差异——列存压缩率、字典编码的效果在加载后才确定。
查集群剩余容量
-- 集群层面的剩余可用内存
SELECT
cluster_shape,
cluster_size,
total_memory_gb,
used_memory_gb,
free_memory_gb,
round(free_memory_gb / total_memory_gb * 100, 1) AS free_pct
FROM performance_schema.rpd_cluster_stats;
如果 free_pct 低于 15%,就该认真考虑扩容了。低于 5% 时,新表可能加载失败,已有表的查询也可能因内存不足被回退到 MySQL 单机执行。
容量估算:新表加载前先算一笔账
往 HeatWave 加表之前,先用估算函数测一下它会吃多少内存,避免加载后才发现撑爆集群。
-- 对尚未加载的表做内存估算
CALL sys.heatwave_estimate_table_memory(
'your_schema', -- 数据库名
'your_table', -- 表名
TRUE -- 是否包含变更估算(增量加载的额外开销)
);
执行后查结果:
SELECT
table_schema,
table_name,
estimated_memory_gb,
estimated_change_memory_gb
FROM performance_schema.rpd_table_estimates
WHERE table_schema = 'your_schema'
AND table_name = 'your_table';
estimated_memory_gb 是首次全量加载的预估,estimated_change_memory_gb 是后续增量变更(DML 导致的增量数据)的额外占用。两者加起来才是这张表长期运行的真实消耗。
批量估算多张表
如果你打算把一个 schema 下所有大表都搬上 HeatWave,可以批量跑:
-- 列出超过 100 万行的未加载表
SELECT
table_schema,
table_name,
table_rows
FROM information_schema.tables
WHERE table_schema = 'analytics_db'
AND table_rows > 1000000
AND table_name NOT IN (
SELECT table_name
FROM performance_schema.rpd_table_stats
WHERE load_status = 'Loaded'
AND table_schema = 'analytics_db'
)
ORDER BY table_rows DESC;
拿到表名列表后,逐个调用 heatwave_estimate_table_memory,把估算值累加,再和集群 free_memory_gb 对比——如果总和超过剩余容量的 70%,就别一次性全加,分批来。
扩容决策:从数据到节点数
假设你当前集群是 2 个 E3.16 节点(每节点 128 GB,总计 256 GB),已用 180 GB,剩余 76 GB。现在要加三张估算合计 120 GB 的表。
简单算术:
- 当前可用:76 GB
- 新表需求:120 GB
- 缺口:44 GB,加上 15% 安全余量(约 18 GB),实际需要额外 ~62 GB
一个 E3.16 节点提供约 96 GB 可用内存(128 × 0.75),加一个节点就够了。但考虑到后续增长,加两个节点更稳妥。
-- 扩容前再确认一次当前状态
SELECT
used_memory_gb,
free_memory_gb,
round(used_memory_gb / total_memory_gb * 100, 1) AS used_pct
FROM performance_schema.rpd_cluster_stats;
在 OCI 控制台或用 CLI 扩容:
# 用 OCI CLI 给 HeatWave 集群加节点(从 2 扩到 4)
oci mysql heatwave-cluster update \
--mysql-instance-id ocid1.mysqlinstance.oc1.phx.example123 \
--cluster-size 4 \
--shape-name MySQL.HeatWave.VM.Standard.E3.16
扩容后 HeatWave 会自动重新平衡数据分布,不需要手动重载。
日常监控:把关键指标收进定时任务
容量规划不是一次性的事。数据在增长,增量变更在累积,今天够用的集群三个月后可能就不够了。建议建一个定时监控视图:
-- 创建容量监控视图,方便定期查询或接入告警
CREATE OR REPLACE VIEW v_heatwave_capacity AS
SELECT
c.cluster_shape,
c.cluster_size AS node_count,
c.total_memory_gb,
c.used_memory_gb,
c.free_memory_gb,
round(c.used_memory_gb / c.total_memory_gb * 100, 1) AS used_pct,
(SELECT count(*)
FROM performance_schema.rpd_table_stats
WHERE load_status = 'Loaded') AS loaded_tables,
(SELECT sum(memory_used_gb)
FROM performance_schema.rpd_table_stats
WHERE load_status = 'Loaded') AS actual_data_gb
FROM performance_schema.rpd_cluster_stats c;
-- 每天跑一次
SELECT * FROM v_heatwave_capacity;
当 used_pct 超过 80%,触发告警——要么清理不再需要的已加载表,要么加节点。
清理不常用表的 HeatWave 加载:
-- 把不常用的分析表从 HeatWave 卸载(数据仍在 MySQL 中,只是不再在内存里)
CALL sys.heatwave_unload('report_db', 'monthly_summary_2022');
卸载后立刻释放内存,比扩容省钱,但代价是这些表的查询回到 MySQL 单机执行速度会慢。取舍看业务优先级。
容量规划清单
把上面这些串起来,实际操作时按这个顺序走:
- 盘点现状:查
rpd_cluster_stats,拿到 used/free 比例。 - 估算增量:对计划加载的表逐个跑
heatwave_estimate_table_memory,累加需求。 - 判断缺口:需求 + 15% 余量 vs 当前 free_memory。超出则扩容或卸载旧表。
- 选择 shape:小集群选 E3.16 起步,大集群用 E3.32 减少节点数和管理开销。节点数越少,数据重分布越快。
- 设监控:建视图,接告警,
used_pct > 80%就该行动。 - 定期复盘:每月查一次
rpd_table_stats,看实际占用和估算的差异,校准未来的预估。
HeatWave 的卖点是不做 ETL 就能跑实时分析,但"不做 ETL"不等于"不做规划"。内存是硬约束,用几条 SQL 把数字算清楚,比凭感觉加节点靠谱得多。