游戏卡顿白皮书 › L12 数据库
大型批处理任务 Batch jobs during service
原因 ID db-batch · 主责 研发团队·服务器开发 · 配合 运维团队·数据库运维
在含图示和实验的完整版中打开此卡片 →
在运营期间跑排行榜统计、批量发邮件、清理旧数据,会占用锁和磁盘。
起因 在运营时段执行大批量任务 → 结果 大范围加锁,占用磁盘和 CPU → 画面表现 特定时段交易、存盘失败,加载变慢
- 症状
- 操作延迟, 吞操作/回档
- 因素
- 延迟, 停顿
- 谁会遇到
- 仅特定功能, 全服
- 何时出现
- 固定周期
- 负责方
- 主责 研发团队·服务器开发 · 配合 运维团队·数据库运维
- 研发团队要做的事
- 拆小分批执行,统计放到从库上做。
- 运维团队要做的事
- 提供统计专用从库,批处理安排在空闲时段,监控锁升级和间隙锁等待。
- 监控图上
- 周期性尖峰 · DB 查询延迟、锁等待
- 查看位置
- 找出卡顿时刻正在运行的长查询。MySQL 看 slow query log,PostgreSQL 看 pg_stat_activity 的 query_start、query,再与同一时刻的锁等待指标和批处理计划(cron、DB 事件调度器)对照。SQL Server 用 lock_escalation 扩展事件记录锁升级
- 确认依据
- 每次都在同一时间有大批量 UPDATE、DELETE、统计查询在跑,期间锁等待和磁盘利用率一起上升
- 排除依据
- 那个时刻没有长查询,看“检查点/日志刷盘”(db-checkpoint)或服务器上的“备份/压缩/扫描任务”(dk-backup)
- 确认手段
- 运维工具即可确认(无需游戏代码)
- 深入了解
- 在 SQL Server 中,一条语句持有的行锁超过约 5,000 个时,会把它们换成表锁(锁升级)。那一刻,使用同一张表的所有请求都会停住。MySQL 在默认设置下按范围条件修改时,也会连行与行之间的间隙一起锁住(间隙锁),阻止插入新行。
出处
- Transaction Locking and Row Versioning Guide Microsoft SQL Server
一条语句在一张表(或索引)上持有 5,000 个以上的锁时触发锁升级,可用 lock_escalation 扩展事件记录 - InnoDB Locking MySQL
在 InnoDB 默认隔离级别 REPEATABLE READ 下,搜索和扫描使用 next-key 锁,间隙锁会阻止在间隙中插入新行 - The Slow Query Log MySQL
记录超过 long_query_time 的查询,连同执行时间(Query_time)、锁时间(Lock_time)和扫描行数 - The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
pg_stat_activity:每个会话当前正在执行的查询(query)及其开始时间(query_start)
相关原因
同一层:L12 数据库
其他层中同样导致“操作延迟”的原因
查看含图示和实验的原卡片