解释“死锁日志”在 Cloud Logging 中的字段结构。
解读
在国内面试中,这道题考察的是候选人是否真正“用过”Cloud SQL,而不仅是“看过文档”。
面试官通常先问“你遇到过死锁吗?怎么排查?”——如果你答“看日志”,就会顺势追问“日志长什么样?字段怎么解析?”
答不出字段细节,会被判定为“只背过概念,没实操”。
因此,必须给出可检索、可告警、可仪表盘的字段级说明,并指出与国内自建 MySQL 日志的差异(格式、字段命名、缺失值处理)。
知识点
- Cloud SQL 死锁日志本质:是 MySQL/PostgreSQL 引擎 InnoDB 死锁检测器的 JSON 输出,被 Cloud Logging 接收后自动注入 GCP 资源标签,与自建实例的 text 格式完全不同。
- 日志桶位置:默认落在
_Default桶,logName 固定为
projects/PROJECT_ID/logs/cloudsql.googleapis.com%2Fmysql.err或%2Fpostgres.log。 - 关键字段分三层:
- GCP 元数据层(monitoredResource、timestamp、severity、labels)——做全局过滤。
- 引擎事件层(jsonPayload 下的 message、errorCode、thread_id)——做内容过滤。
- 死锁详情层(jsonPayload 内嵌的 deadlock 结构体)——做根因分析。
- 国内合规注意:死锁详情里可能出现业务敏感字段值,需通过日志路由器(Log Router) 做脱敏或转存至中国境内 Bucket,避免跨境传输风险。
答案
在 Cloud Logging 中,一条死锁日志的 JSON 结构如下(以 MySQL 5.7 为例,字段顺序无关):
{
"insertId": "1a2b3c4d",
"logName": "projects/PROJECT_ID/logs/cloudsql.googleapis.com%2Fmysql.err",
"timestamp": "2024-06-01T08:15:30.123456Z",
"severity": "ERROR",
"resource": {
"type": "cloudsql_database",
"labels": {
"project_id": "PROJECT_ID",
"database_id": "PROJECT_ID:INSTANCE_ID",
"region": "us-central1"
}
},
"jsonPayload": {
"errorCode": "MY-012138",
"message": "InnoDB: transactions deadlock detected, dumping detailed information.",
"thread_id": 123456,
"deadlock": {
"transaction_1": {
"thread_id": 123456,
"query": "update order set status='PAID' where order_id=98765",
"lock_mode": "X locks rec but not gap",
"holds": ["lock on db.order.PRIMARY, id 98765"],
"waiting": ["lock on db.inventory.PRIMARY, id 54321"]
},
"transaction_2": {
"thread_id": 123457,
"query": "update inventory set stock=stock-1 where sku='SKU123'",
"lock_mode": "X locks rec but not gap",
"holds": ["lock on db.inventory.PRIMARY, id 54321"],
"waiting": ["lock on db.order.PRIMARY, id 98765"]
},
"victim": 123457
}
},
"labels": {
"RECEIVER": "cloudsql_mysql"
}
}
字段含义与用法(面试时需口头点到):
- jsonPayload.errorCode:值固定为 MY-012138,可快速过滤死锁。
- jsonPayload.deadlock.victim:被回滚的事务线程 ID,直接对应连接池里的异常连接。
- resource.labels.database_id:格式为
项目:实例,在 SCC(Security Command Center)里做统一资源路径告警。 - timestamp:Cloud SQL 采用 UTC+0,与国内业务系统做关联时需**+8 小时**转北京时间。
- jsonPayload.deadlock.transaction_x.query:如果业务用了 ORM,SQL 会被截断到 1024 字节,需要回代码里补全。
拓展思考
-
如何基于上述字段在 Log Explorer 写一条过滤语句,只输出过去 1 小时 victim 为 123457 的死锁?
答:resource.type="cloudsql_database" jsonPayload.errorCode="MY-012138" jsonPayload.deadlock.victim=123457 timestamp >= "2024-06-01T07:15:30Z" -
如果业务要求死锁超过 5 次/分钟就电话告警,但日志量太大,怎样避免误报?
思路:用 Log-Based Metrics 聚合jsonPayload.errorCode="MY-012138",按resource.labels.database_id分组,设置对齐时间窗口 60 秒、阈值 5,再叠加 Alert Policy 的 MQL 去抖参数(duration=120s)即可。 -
国内金融客户常问:“死锁日志里会不会泄露持卡人卡号?”
标准回答:Cloud SQL 只记录当前持有和等待的索引记录主键值,如果主键是卡号明文就会泄露。解决方案:- 主键改用哈希或令牌化列;
- 通过 Log Router 在北京/上海区域的 Sink 里用 CEL 函数
replace()做脱敏; - 开启 CMEK 让日志落地即加密,满足《个人金融信息保护技术规范》。
-
与 阿里云 RDS 死锁日志对比:
- 阿里云仍用文本格式,需要正则解析;Cloud SQL 直接 JSON,BigQuery 一键直查。
- 阿里云日志延迟约 1–2 分钟,Cloud SQL 通过 Cloud Logging API 实时拉流,延迟 <10 秒,对高频交易场景更友好。