数据库锁堆积
SysAdmin Crisis 中的数据库锁堆积:Web 服务器看似正常,延迟却不断攀升。了解它的日志特征以及与其他事件的区别。
最后更新:
这是专门惩罚套用固定模式的事件。机架上一切正常,流量条也正常,这一夜却照样分崩离析。
它做什么
在某台数据库机器上,查询开始在锁上等待,而不是完成。没有任何东西崩溃,没有机器进入饱和——但请求在数据库后面排起了队,延迟攀升,可用率随之下降。
Web 层从头到尾都是正常的。这正是该事件的全部特点:症状是整个服务器群变慢,原因却是一台从不变红的机器。
日志特征
数据库机器的 PostgreSQL 日志里有等待和耗时的记录,而在边缘只会出现一条延迟警告:
04:03:11 db-01 postgres[1187]: [2210] LOG: process 2210 still waiting for ShareLock on transaction 48212 after 1000.051 ms
04:03:11 db-01 postgres[1187]: [2210] DETAIL: Process holding the lock: 2207. Wait queue: 2210.
04:03:40 web-01 monit[598]: 'shop-api' failed protocol test [HTTP] at [localhost]:80/healthz [TCP/IP] -- HTTP: response time 2100 ms exceeds 1000 ms
04:04:12 db-01 postgres[1187]: [1187] FATAL: remaining connection slots are reserved for non-replication superuser connections
持有锁的会话只报告自己的持续时间;等待的会话则会说明自己在等谁。要找到根因,需要沿着这条链从末端一路走回起点。db_stat 按 ID、等待时间和名称列出活动查询,并标出卡在锁上的那些。
置之不理的后果
锁队列不断增长,延迟在班次余下的时间里一直居高不下。由于没有机器进入 DOWN,可用率的损失完全来自延迟,随后来自 SLA 债务。这就是为什么整排机架全绿,一夜照样可能输掉。
如何区分
| 看起来相似 | 区分依据 |
|---|---|
| DDoS 洪水 | 两者都会推高延迟。洪水还会推高 Web 机器的 CPU,并带来内核的 SYN 警告;锁堆积两者都没有。 |
| 失控任务 | 两者都可能涉及数据库机器,但失控任务会占满 CPU 并点出一个进程;本事件点出的是一条查询。 |
何时出现
| 最早出现的夜 | 3 |
| 前提 | 一台 db 机器 |
| 权重 | 80 |
| 同时出现 | 一个实例 |
该事件收尾时可能带来真实的可用率损失;收尾的那行日志可以据此区分是干净收尾还是带着损失收尾。