PostgreSQL 出现锁表异常(如业务卡住、SQL 一直等待、表无法写入)通常不是“随机故障”,而是由锁机制 + 并发行为 + 配置共同导致的。下面从常见原因 → 典型场景 → 排查方法 → 解决/规避系统说明。
PostgreSQL 的锁是按锁级别 + 锁对象工作的:
关键点:
长事务 + 未提交事务 = 锁表异常的最大根源
BEGIN;
UPDATE users SET ...;
-- 忘记 COMMIT / ROLLBACK
后果:
✅ 特征:
idle in transaction例如:
ALTER TABLE orders ADD COLUMN xxx;
会被以下阻塞:
PostgreSQL 的 DDL 通常需要 AccessExclusiveLock
LOCK TABLE users IN ACCESS EXCLUSIVE MODE;
如果:
两个事务互相等待:
A 锁了行1,等行2
B 锁了行2,等行1
PostgreSQL 会:
✅ 日志中常见:
deadlock detected
导致:
例如:
常见问题参数:
lock_timeout
deadlock_timeout
idle_in_transaction_session_timeout
未设置 → 锁可能无限等待
SELECT
pid,
usename,
state,
wait_event_type,
wait_event,
query
FROM pg_stat_activity
WHERE wait_event_type = 'Lock';
SELECT
l.locktype,
l.relation::regclass,
l.mode,
l.granted,
a.pid,
a.query
FROM pg_locks l
JOIN pg_stat_activity a ON l.pid = a.pid
WHERE l.relation IS NOT NULL;
SELECT
blocked.pid AS blocked_pid,
blocking.pid AS blocking_pid,
blocking.query AS blocking_query
FROM pg_locks blocked
JOIN pg_locks blocking
ON blocked.locktype = blocking.locktype
AND blocked.relation = blocking.relation
WHERE NOT blocked.granted
AND blocking.granted;
-- 终止阻塞事务
SELECT pg_terminate_backend(pid);
SET lock_timeout = '5s';
SET idle_in_transaction_session_timeout = '30s';
PostgreSQL 锁表异常,99% 是因为未提交事务、长事务或 DDL 冲突,不是数据库“坏了”。
如果你愿意,可以:
我可以帮你精准定位是哪一类锁问题。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。