MySQL HeatWave 容量规划:用 SQL 查询把资源算明白

2026-05-21 15 预计阅读时间:1 分钟
来源:blogs.oracle.com AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:9 分钟

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 单机执行速度会慢。取舍看业务优先级。

容量规划清单

把上面这些串起来,实际操作时按这个顺序走:

  1. 盘点现状:查 rpd_cluster_stats,拿到 used/free 比例。
  2. 估算增量:对计划加载的表逐个跑 heatwave_estimate_table_memory,累加需求。
  3. 判断缺口:需求 + 15% 余量 vs 当前 free_memory。超出则扩容或卸载旧表。
  4. 选择 shape:小集群选 E3.16 起步,大集群用 E3.32 减少节点数和管理开销。节点数越少,数据重分布越快。
  5. 设监控:建视图,接告警,used_pct > 80% 就该行动。
  6. 定期复盘:每月查一次 rpd_table_stats,看实际占用和估算的差异,校准未来的预估。

HeatWave 的卖点是不做 ETL 就能跑实时分析,但"不做 ETL"不等于"不做规划"。内存是硬约束,用几条 SQL 把数字算清楚,比凭感觉加节点靠谱得多。


相关推荐