summary
2017-10-10,GoCardless 在执行一次数据库迁移时,迁移脚本运行得过快,同时一个长时间运行的事务持有锁,二者叠加导致一张关键 PostgreSQL 表被锁住:所有针对该表的查询都被阻塞,支付平台的核心操作因此降级或超时。
timeline
迁移脚本批量操作触发锁竞争;一个长事务持锁未释放,关键表进入锁等待。监控发现查询大面积阻塞后,团队终止长事务并调整迁移节奏,表查询恢复。
root_cause
迁移操作与长事务的锁冲突:迁移未控制速率,与既有长查询争夺同一张关键表的锁,造成全表查询阻塞。
amplifiers
① 迁移无速率控制:批量操作瞬间抢占锁。② 长事务持锁:既有长查询放大锁等待。③ 关键表单点:一张表被锁即拖垮核心流程。④ 缺乏锁等待告警:发现偏晚。
mitigation
终止阻塞的长事务;以更低速率、分批方式重跑迁移;增加锁等待监控与告警。
lessons
在线迁移必须限速并避开长事务窗口;关键表操作需评估锁影响;对锁等待设实时告警;大表变更优先用在线/无锁方式。
checklist
① 迁移脚本增加速率限制与批处理。② 避免在长事务窗口做结构变更。③ 关键表锁等待实时告警。④ 大表变更采用无锁/在线方案。