한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

游戏卡顿白皮书 › 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 在默认设置下按范围条件修改时,也会连行与行之间的间隙一起锁住(间隙锁),阻止插入新行。

出处

  1. Transaction Locking and Row Versioning Guide Microsoft SQL Server
    一条语句在一张表(或索引)上持有 5,000 个以上的锁时触发锁升级,可用 lock_escalation 扩展事件记录
  2. InnoDB Locking MySQL
    在 InnoDB 默认隔离级别 REPEATABLE READ 下,搜索和扫描使用 next-key 锁,间隙锁会阻止在间隙中插入新行
  3. The Slow Query Log MySQL
    记录超过 long_query_time 的查询,连同执行时间(Query_time)、锁时间(Lock_time)和扫描行数
  4. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    pg_stat_activity:每个会话当前正在执行的查询(query)及其开始时间(query_start)

相关原因

同一层:L12 数据库

其他层中同样导致“操作延迟”的原因

查看含图示和实验的原卡片