关于 analyzing-schema-change-storage-risk
这项技能用于 CockroachDB 在线架构变更前估算各存储节点所需空间。它结合范围和索引大小,将可用空间与按操作类型设定的保守目标进行比较。
主要功能
- 01检查各存储节点的最小可用空间
- 02估算表和索引大小
- 03按操作类型设定容量目标
- 04查找已暂停的架构变更任务
- 05说明范围统计数据的局限
适用场景
- 01创建大型索引前评估磁盘余量
- 02规划大型表的 ALTER PRIMARY KEY
- 03物化查询结果前检查容量
- 04排查因空间不足而暂停的架构变更
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cockroachlabs/ cockroachdb-skills --skill analyzing-schema-change-storage-risk安装后在 Claude Code 中输入/analyzing-schema-change-storage-risk确认已加载。
详细介绍
分析架构变更的存储风险
估算安全执行在线架构变更所需的存储空间余量。 与官方指南保持一致: 架构变更进行期间,某些操作可能暂时需要受影响表或索引大小的 3 倍空间。
如需持续监控范围分布,请参阅 analyzing-range-distribution。
何时使用此技能
对索引较大的表(每个索引达到数 GB,或每个索引包含许多范围)执行以下任一操作前,请先快速估算:
CREATE INDEX- 带有
INDEX或UNIQUE的ADD COLUMN ALTER PRIMARY KEYCREATE MATERIALIZED VIEWCREATE TABLE ASREFRESH MATERIALIZED VIEWALTER TABLE ... SET LOCALITY(当更改 locality 会重写数据时)
索引较小(几 KB 到几 MB)的表,存储风险可以忽略;无需估算。
背景
回填实际需要多少临时空间?
实际情况取决于操作:
CREATE INDEX/ADD COLUMN ... UNIQUE:大约需要新索引大小的 1 倍——索引列加上主键列,写入新的索引范围。这通常只占表的一小部分。最坏情况下所需的空间余量不会超过该索引的大小。ALTER PRIMARY KEY:会重写主索引,以及定义依赖旧主键的所有二级索引。旧数据会一直保留到 GC,因此变更期间磁盘峰值用量可能接近再次增加一个表的大小。- 所有批量导入回填:在 Pebble 完成压缩并运行 GC 之前,额外的 MVCC 版本和压缩前的 SST 都会增加开销。
官方文档将这些情况概括为一条保守建议:
预留最多相当于受影响表或索引大小 3 倍的可用空间。
这是一个安全上限,而非精确预测。对于大多数 CREATE INDEX 操作,实际开销要小得多;对于大型表上的 ALTER PRIMARY KEY,这个估算则较为合理。
如果集群在回填过程中耗尽磁盘空间,会发生什么?
回填通过 AddSSTable 批量导入数据;每次导入前都会检查每个存储节点的剩余容量。如果剩余比例低于 kv.bulk_io_write.min_capacity_remaining_fraction(默认值为 0.05,即 5%),导入就会因 InsufficientSpaceError 而被拒绝。旧版和声明式架构变更器都会将此错误转换为暂停作业的请求,因此架构变更会停止,而不会导致集群卡死。要恢复操作,请释放空间(例如删除未使用的索引、扩展存储),然后恢复已暂停的作业。
这是一种被动安全机制,并非规划工具——等它触发时,受影响存储节点上的前台写入可能已经受到影响。
估算容量
第 1 步 — 检查每个存储节点的可用空间
限制架构变更的是各存储节点中最少的可用空间,而非集群的总可用空间(副本分布在不同节点上)。
没有可在生产环境中安全使用的 SQL 视图能显示每个存储节点的容量。请使用 DB Console 的 Overview → Storage 页面(可按每个存储节点的用量排序),或抓取每个节点的 Prometheus 端点,并查看最小的 capacity_available:
curl -ks https://<node>:8080/_status/vars | grep -E '^capacity( |_used|_available)'
第 2 步 — 估算受影响表或索引的大小
使用文档推荐的 SHOW RANGES 形式:
SHOW RANGES FROM TABLE <table> WITH DETAILS, KEYS, INDEXES;
输出包含每个范围的一行,其中有 range_size_mb 和 index_name。
按索引汇总,得到容量规划所需的每个索引总大小:
WITH r AS (SHOW RANGES FROM TABLE <table> WITH DETAILS, KEYS, INDEXES)
SELECT
index_name,
COUNT(*) AS range_count,
ROUND(SUM(range_size_mb), 2) AS index_size_mb,
ROUND(SUM(range_size_mb) / 1024, 2) AS index_size_gb
FROM r
GROUP BY index_name
ORDER BY index_size_mb DESC;
步骤 3 — 与操作进行比较
| 操作 | 保守的空闲空间目标(每个存储节点) |
|---|---|
CREATE INDEX / ADD COLUMN ... UNIQUE | 最多为新索引大小的 3 倍(其索引列 + 主键列)。 |
ALTER PRIMARY KEY | 最多为表大小的 3 倍(步骤 2 中相关索引大小之和)。 |
CREATE MATERIALIZED VIEW / CREATE TABLE AS | 最多为物化结果预期大小的 3 倍。 |
新索引尚不存在,因此请根据类似的现有索引(例如,具有相似类型列的索引)进行估算,或根据源列对主索引的占用估算。
如果步骤 1 中最小的空闲空间远高于目标值,则可以安全执行该操作。如果空闲空间接近目标值,请先释放空间(删除未使用的索引、扩展存储),然后再执行 DDL。
运维说明
SHOW RANGES ... WITH DETAILS开销很大。 它会按需计算跨度统计信息。请始终指定特定表,切勿在整个集群范围内运行;对于包含数千个跨度的表,优先选择维护时段运行。- 关注作业,而不只是磁盘。 如果回填因
InsufficientSpaceError暂停,请释放受影响存储节点上的磁盘空间,并恢复已暂停的架构变更作业。使用以下命令检查:WITH j AS (SHOW JOBS) SELECT job_id, status, error FROM j WHERE job_type = 'SCHEMA CHANGE' AND status = 'paused'; - 先删除未使用的索引。 在大型回填之前,释放额外空间最经济的做法通常是删除
crdb_internal.index_usage_statistics显示未使用的索引(根据文档,这是 12 个可在生产环境中安全使用的crdb_internal视图之一)。 - 统计信息可能滞后。
range_size_mb是近似值,可能滞后于实际磁盘使用量;请将估算值视为保守的粗略参考,而非精确数值。
参考资料
相关技能
- analyzing-range-distribution — 跨度数量、租约持有者分布、碎片化