在创建 MySQL 8.0 实例时,如何一次性指定字符集、排序规则与 SQL 模式?

解读

国内面试官问这道题,表面看是“怎么填参数”,实则考察三层能力:

  1. 是否理解 Cloud SQL 与自建 MySQL 在初始化阶段的差异——Cloud SQL 不允许直接修改 my.cnf,必须通过 官方暴露的 flag 列表 完成;
  2. 是否熟悉 MySQL 8.0 默认行为(utf8mb4、utf8mb4_0900_ai_ci、STRICT_TRANS_TABLES 等)与 国内合规要求(GB18030、大小写敏感、NO_ZERO_DATE 等)之间的冲突;
  3. 是否具备 “一次交付、后续免运维” 的云原生思维:用 Terraform + 变量文件 把字符集、排序规则、SQL 模式、备份窗口、高可用策略一并固化,避免人工在控制台“点选”带来的漂移风险。

如果仅回答“在创建页下拉框选一下”,会被视为“只用过控制台”的初级水平;必须给出 gcloud 命令 + Terraform 代码 + 可灰度验证的方案,才能拿到高分。

知识点

  1. Cloud SQL 初始化三要素

    • 字符集:由 character_set_server 控制,MySQL 8.0 默认 utf8mb4,国内业务若需 GB18030 必须显式指定。
    • 排序规则:由 collation_server 控制,决定大小写敏感、重音规则;国内常见 utf8mb4_0900_as_cs(敏感)或 utf8mb4_general_ci(不敏感)。
    • SQL 模式:由 sql_mode 控制,Cloud SQL 用 逗号分隔的字符串 传入,顺序无关,但 NO_AUTO_VALUE_ON_ZERO、STRICT_TRANS_TABLES、NO_ZERO_DATE、NO_ENGINE_SUBSTITUTION 是金融级标配。
  2. Cloud SQL 的“允许 Flag”白名单
    并非所有 my.cnf 参数都能改,必须通过 gcloud sql flags list --database-version=MYSQL_8_0 确认;若参数不在白名单,只能提 支持工单 或改用 Cloud SQL Enterprise Plus(可开自定义参数组)。

  3. 一次性注入的三种姿势

    • gcloud CLI--database-flags 支持键值对,一次最多 20 个,用 ^(Windows)或 \(Linux)换行续行;
    • Terraformgoogle_sql_database_instancesettings.database_flags 块,可变量化,方便多环境复用;
    • Cloud SQL Admin APIinstances.insertsettings.databaseFlags[] 数组,适合 CI/CD 自动触发
  4. 国内网络合规细节
    若通过 Private Service Connect 内网接入,需提前在 vpc-peering 中放通 servicenetworking.googleapis.com/24 前缀,否则创建实例会卡在“分配 IP”阶段,被误判为“参数无效”。

答案

步骤一:确认白名单

gcloud sql flags list --database-version=MYSQL_8_0 \
  --filter="name=(character_set_server,collation_server,sql_mode)" \
  --format="value(name)"

预期输出三行,证明均可改。

步骤二:gcloud 一次性创建(Linux 续行)

gcloud sql instances create prod-mysql80 \
  --database-version=MYSQL_8_0 \
  --tier=db-n1-standard-2 \
  --region=asia-east2 \
  --root-password='${ROOT_PW}' \
  --database-flags \
    character_set_server=utf8mb4,\
    collation_server=utf8mb4_0900_as_cs,\
    sql_mode='STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY'

注意

  • sql_mode 的值用 单引号包裹,内部逗号 不能有空格,否则会被拆成多个 flag 导致报错;
  • 若需 GB18030,把 character_set_server=gb18030collation_server=gb18030_chinese_ci 替换即可,但需先确认业务驱动支持该字符集。

步骤三:Terraform 模板(production/variables.tf)

variable "sql_mode" {
  default = "STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY"
}
variable "character_set" { default = "utf8mb4" }
variable "collation"     { default = "utf8mb4_0900_as_cs" }

production/main.tf

resource "google_sql_database_instance" "mysql80" {
  name             = "prod-mysql80"
  database_version = "MYSQL_8_0"
  region           = "asia-east2"
  settings {
    tier = "db-n1-standard-2"
    database_flags {
      name  = "character_set_server"
      value = var.character_set
    }
    database_flags {
      name  = "collation_server"
      value = var.collation
    }
    database_flags {
      name  = "sql_mode"
      value = var.sql_mode
    }
    backup_configuration {
      enabled                        = true
      start_time                     = "03:00"
      point_in_time_recovery_enabled = true
    }
    ip_configuration {
      ipv4_enabled    = false
      private_network = google_compute_network.vpc.id
    }
  }
}

执行

terraform plan -out=tfplan
terraform apply tfplan

即可 一次性 完成实例创建、参数注入、备份策略与内网接入,后续 零人工点选

验证

gcloud sql connect prod-mysql80 --user=root <<EOF
SHOW VARIABLES LIKE 'character_set_server';
SHOW VARIABLES LIKE 'collation_server';
SELECT @@sql_mode;
EOF

三行输出与预期完全一致,即交付完成。

拓展思考

  1. 灰度变更
    若实例已上线,修改 sql_mode立即重启示例,导致主库闪断;国内金融场景可先用 只读实例 验证新 SQL 模式是否击穿业务,再采用 蓝绿发布

    • 新建 Cloud SQL 蓝实例(带新 flag);
    • Database Migration Service最小停机迁移(<30 s);
    • 切换 Private DNS A 记录,实现业务无感。
  2. 参数漂移审计
    国内等保 2.0 要求 “配置基线可核查”,可在 Cloud Asset Inventory 中创建 策略监控

    gcloud asset feeds create mysql80-drift \
      --asset-types="sqladmin.googleapis.com/Instance" \
      --content-type="resource" \
      --feed-output-config="pubsubTopic=projects/${PROJECT}/topics/sql-drift"
    

    一旦有人控制台手动改 flag,Pub/Sub 触发 Cloud Function 自动回滚 Terraform 状态,确保 “代码即真相”

  3. Serverless 场景
    若业务使用 Cloud Run 全托管模式,建议把上述 Terraform 模块封装成 Google Cloud Blueprints,通过 Cloud Deploy 流水线 一键拉起 “Cloud Run + Cloud SQL + Secret Manager” 组合,字符集、SQL 模式、连接池大小 全部变量化,让开发同学 只改 yaml 不碰控制台,符合国内 “研发不碰生产” 的合规红线。