导出到 Cloud Storage 时,如何启用“存储桶对象保全”?

解读

面试官问的是“Cloud SQL 导出 → Cloud Storage 时,如何确保生成的对象立即被 WORM(Write Once Read Many)策略锁定”。
国内金融、政务、医疗客户在做等保、关保、密评时,常要求“数据一经写入不可篡改、不可提前删除”,因此必须让 Cloud SQL 导出的 .sql.csv 文件自动带上对象保全(Object Retention)锁
回答时要区分两层:

  1. Cloud SQL 导出接口本身没有 retention 参数
  2. 必须在存储桶侧预先配置“Bucket Retention Policy + Object Lock”,并保证导出账号具备设置对象保全的 IAM 权限
    答不到“桶级策略”与“IAM 权限”两点,会被认为只背过文档,没做过真实合规项目。

知识点

  • Cloud SQL 导出流程gcloud sql export ... --uri=gs://bucket/path → Cloud SQL 服务代理把数据流式写入 Cloud Storage。
  • Cloud Storage 对象保全(Object Retention)
    Bucket Retention Policy:桶级最短保留期限,对新对象自动生效,但可被桶主关闭
    Object Lock(Bucket Lock):把 Retention Policy 永久锁定,符合中国银保监会“不可撤销 WORM”要求。
    Event-Based Hold / Temporary Hold:单对象级开关,Cloud SQL 导出接口
    不会自动设置
    ,需事后脚本补设。
  • IAM 角色
    – 导出主账号需 roles/storage.objectAdmin(含 storage.objects.setRetention)。
    – Cloud SQL 服务代理(service-PROJECT@cloudsql-gserviceaccount.com)也需同一权限,否则写入后无法自动附加 retention。
  • 国内合规映射
    – 等保 2.0 安全区域边界“数据完整性”控制点;
    – 《金融行业数据安全管理办法》第 28 条“交易日志与备份不可篡改”。

答案

步骤如下:

  1. 创建专用存储桶并设定保留期限
    gsutil mb -p PROJECT -l ASIA-EAST1 gs://prod-backup-archive
    gsutil retention set 2555d gs://prod-backup-archive
    gsutil retention lock gs://prod-backup-archive   # 永久锁定,符合 WORM
    
  2. 给 Cloud SQL 服务代理授权
    gcloud projects add-iam-policy-binding PROJECT \
      --member="serviceAccount:service-PROJECT@gcp-sa-cloud-sql.iam.gserviceaccount.com" \
      --role="roles/storage.objectAdmin"
    
  3. 执行导出
    gcloud sql export sql INSTANCE gs://prod-backup-archive/2025/06/instance-20250601.sql \
      --database=erp --project=PROJECT
    
    由于桶已启用 Retention Policy,新生成的对象自动携带“保留到期日”,且因 Bucket Lock 无法被提前删除或缩短保留期,满足对象保全要求
  4. 验证
    gsutil ls -L gs://prod-backup-archive/2025/06/instance-20250601.sql | grep "Retention"
    
    输出包含 Retention: 2555 day(s) 即表示启用成功。

拓展思考

  • 如果客户已存在存量桶且未锁定,直接 retention lock 会失败(需先确保桶内无短于预期保留期的对象),此时可新建带锁桶并通过跨桶迁移满足合规。
  • 对于多项目、多数据库实例场景,建议用Terraform 模块统一创建“WORM 桶 + IAM 绑定 + Cloud SQL 导出计划”,代码入 Git,审计时可直接输出合规证据。
  • 当导出文件需先给内部运维人员短暂可读、后再锁定,可组合使用 Temporary Hold:导出后脚本立即 gsutil retention temp set,确认校验完成后再 temp release,既保证灵活又保留最终 WORM 属性。