mcpField
A
analyzing-schema-change-storage-risk

analyzing-schema-change-storage-risk

github.com/cockroachlabs数据与数据库23127 次安装14 周前更新
代码仓库

关于 analyzing-schema-change-storage-risk

这项技能用于 CockroachDB 在线架构变更前估算各存储节点所需空间。它结合范围和索引大小,将可用空间与按操作类型设定的保守目标进行比较。

主要功能

  1. 01检查各存储节点的最小可用空间
  2. 02估算表和索引大小
  3. 03按操作类型设定容量目标
  4. 04查找已暂停的架构变更任务
  5. 05说明范围统计数据的局限

适用场景

  1. 01创建大型索引前评估磁盘余量
  2. 02规划大型表的 ALTER PRIMARY KEY
  3. 03物化查询结果前检查容量
  4. 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 KEY
  • CREATE MATERIALIZED VIEW
  • CREATE TABLE AS
  • REFRESH MATERIALIZED VIEW
  • ALTER 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 是近似值,可能滞后于实际磁盘使用量;请将估算值视为保守的粗略参考,而非精确数值。

参考资料

相关技能

评论

支持 Markdown