当磁盘使用率超过 95% 时,自动扩容为何可能失败?

解读

在国内的 Google Cloud SQL 面试中,这道题考察的是候选人对托管数据库“最后一公里”扩容机制的理解深度。
面试官真正想听的是:

  1. 托管服务并非“无限魔法”,磁盘扩容依赖底层 IaaS 资源池余量文件系统层剩余 inode/元数据
  2. 超过 95% 后,Cloud SQL 的预写日志(WAL/Redo)临时排序文件可能瞬间把剩余 5% 吃光,导致扩容事务本身无法提交;
  3. 国内账号若走包年包月配额跨境资源路由,可能因区域级 SSD 库存不足而触发后台“软拒绝”,控制台却仅提示“扩容失败”,易被误判为权限问题。
    答出“扩容操作自身也要写盘”与“国内资源池隔离策略”两点,就能体现资深运维视角。

知识点

  • 自动扩容触发阈值:Cloud SQL 默认在磁盘使用率 95% 时发出扩容请求,但不保证 100% 成功
  • 扩容流程:API 调用 → Compute Engine 下发 disk.resize 请求 → 文件系统执行 xfs_growfs/ext4_resize → 更新元数据 → 回写 CloudSQL 控制面。
  • 失败根因
    1. 剩余空间不足 2 GB:resize 需要临时快照,快照链写 manifest 文件需额外空间,若剩余<2 GB 直接回滚。
    2. inode 耗尽:国内用户常选 16 KB 块大小的 SSD,小文件多时 inode 先满,df -h 显示 95%,df -i 已 100%,扩容无法解决 inode 不足。
    3. 区域级库存:北京/上海区域若遇企业级客户抢占 SSD 配额,后台会返回 RESOURCE_EXHAUSTED,但控制台仅提示“自动扩容未生效”。
    4. 只读锁未释放:MySQL 引擎在 95% 时会触发只读保护,此时扩容事务无法获得 MDL 写锁,导致超时失败。
  • 监控盲区:Cloud Monitoring 的指标disk_utilization 不含 WAL 与临时表空间,实际磁盘可能在 30 秒内从 95% 飙到 100%,扩容请求还未下发就已无空间。

答案

“当磁盘使用率超过 95% 时,Cloud SQL 的自动扩容可能失败,核心原因是扩容操作本身需要额外的临时空间与元数据写权限,而 95% 已触发引擎只读保护及快照链写 manifest 的 2 GB 预留门槛;同时国内区域可能存在SSD 库存瞬时耗尽包年包月配额软限制,导致底层 Compute Engine 返回 RESOURCE_EXHAUSTED。此时即使控制台显示‘扩容中’,后台会因inode 耗尽无法获取 MDL 写锁而回滚,最终表现为扩容失败。”

拓展思考

  1. 预防策略
    • 自动扩容阈值下调到 80%,并通过 Terraform 设置max_disk_size 为当前 3 倍,避免无限扩容带来的费用失控。
    • 对 MySQL 场景,打开binlog_expire_logs_secondsinnodb_redo_log_capacity 动态清理,减少 WAL 占用。
  2. 应急方案
    • 国内账号可临时提升 SSD 配额(需提工单到谷歌中国合作伙伴),或手动创建跨区域只读实例后切换业务流量,再对原实例做离线扩容。
  3. 面试加分项
    • 提到Private Service Connect 场景下,若客户用VPC Service Controls 封网,扩容请求会被Service Perimeter拦截,需加ingress/egress rule放行 googleapis.com。
    • 指出 Cloud SQL for SQL Server 因使用本地 SSD + 远程镜像架构,不支持在线扩容,超过 95% 只能新建实例做分布式可用性组迁移,可展示对多引擎差异的掌握。