迁移完成后,如何校验主键自增 ID 的连续性?

解读

面试官问“校验主增 ID 连续性”并不是想听“SELECT COUNT(*) 与 MAX(id) 比较”这种表面答案,而是考察候选人是否理解:

  1. Google Cloud SQL 这种托管环境里,主键空洞 可能来自批量回滚、并行复制、REPLACE/INSERT IGNORE、pt-online-schema-change、Dataflow 并行导入等;
  2. 空洞是否影响业务(如库存、财务),以及能否在 零停机、只读实例、跨区域只读副本 上完成校验;
  3. 如何给出可重复、可审计、可灰度的校验报告,满足国内金融、电商、政府等合规场景。

知识点

  • Cloud SQL 内置函数GENERATION_EXPRESSIONinformation_schema.tablesmysql.innodb_table_stats 的权限边界;
  • Cloud SQL for MySQL 的 sql_modeNO_AUTO_VALUE_ON_ZEROINSERT ... SELECT 对自增计数器的影响;
  • Cloud SQL for PostgreSQL 的 sequencecurrval()last_valuepg_sequence_last_value() 在只读副本上的可见性;
  • Cloud SQL Auth ProxyIAM 鉴权Cloud SQL Studio 只读账号,避免校验脚本误写;
  • Cloud Monitoring 自定义指标:把“空洞率”作为 SLI 写入 SLO,实现持续校验;
  • Dataflow SQLBigQuery Federated Query 对 Cloud SQL 做 并行窗口分析,10 亿行表 5 分钟内完成;
  • Terraform 输出 validation_job_id,把校验结果写回 Cloud Storage 并配置 Bucket 级 CMEK,满足国内等保 3 级要求。

答案

分五步落地,全部在 只读实例 上完成,确保主库零影响。

  1. 前置审计
    通过 gcloud sql instances describe 拿到 master_instance_namereplica_names,确认校验目标为 只读实例
    执行 SHOW VARIABLES LIKE 'read_only'; 必须返回 ON

  2. 空洞扫描
    MySQL 场景:

    WITH base AS (
      SELECT id,
             id - LAG(id,1,id-1) OVER (ORDER BY id) AS gap
      FROM   tbl FORCE INDEX (PRIMARY)
    )
    SELECT COUNT(*) AS holes,
           MIN(id)  AS first_hole,
           MAX(id)  AS last_hole
    FROM   base
    WHERE  gap > 1;
    

    PostgreSQL 场景:

    SELECT COUNT(*) AS holes,
           MIN(id)  AS first_hole,
           MAX(id)  AS last_hole
    FROM (
      SELECT id, id - lag(id) OVER (ORDER BY id) AS gap
      FROM   tbl
    ) t
    WHERE gap > 1;
    

    以上 SQL 通过 Cloud SQL Studio 提交,执行计划必须走 Index Only Scan(MySQL 看 Using index),耗时控制在 30 秒 内;若表大于 5 千万行,改用 Dataflow Template JdbcIO 并行分片,splitColumn 选主键fetchSize=20000maxParallelism=Cloud SQL vCPU×2

  3. 连续性指标
    定义 continuity_ratio = (MAX(id) - MIN(id) + 1 - holes) / (MAX(id) - MIN(id) + 1)
    业务方可接受阈值 ≥ 99.9%;若低于阈值,触发 PagerDuty 高优先级事件。

  4. 结果固化
    将空洞列表 INSERT INTO cloudsql_validation.gaps_YYYYMMDD(位于 独立校验库binlog=ROW 方便审计),并 EXPORT TO GCS gs://project-cloudsql-backup/validation/gaps_YYYYMMDD.csv
    文件使用 CMEK 加密,Bucket 设置 uniform bucket-level accessretention 30 天

  5. 回归与灰度
    Terraform 中把校验 SQL 封装为 null_resourcetriggers = { always_run = timestamp() }apply 后自动输出 continuity_ratio
    ratio < 阈值terraform apply 直接失败,阻断灰度发布,实现 “校验即门禁”

拓展思考

  • 双云互备场景:若源库在 阿里云 RDS,目标为 Cloud SQL,可用 Cloud DatastreamCDC 同步;校验时需在 Cloud SQL 只读实例RDS 只读实例 同时跑空洞扫描,再对比 checksum,确保 双向一致性
  • Sharding 场景:对 64 张分表可并行起 64 个 Cloud Run Job,每个 Job 扫描一片,Job 级最小权限使用 Cloud SQL IAM 数据库身份认证结果汇总到 BigQueryData Studio 可视化
  • 法律合规:国内 个人信息保护法 要求删除权,删除后产生空洞是合规表现;此时连续性指标需 排除已删除主键,应在 校验库 维护 deleted_pks 表,JOIN 排除后再算 ratio,避免误报警。