查询长时间运行的事务
SELECT
pid,
usename,
application_name,
client_addr,
client_port,
state,
-- 计算事务已运行时长
now() - xact_start AS transaction_duration,
-- 计算当前查询已运行时长
now() - query_start AS query_duration,
query
FROM pg_stat_activity
WHERE xact_start IS NOT NULL -- 只显示开启了事务的连接
AND state != 'idle' -- 排除完全空闲的连接(可选)
AND pid != pg_backend_pid() -- 排除当前查询本身
ORDER BY transaction_duration DESC;
中止活跃事务
-- 终止所有运行超过5分钟的活跃事务
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE xact_start < now() - interval '5 minutes'
AND state = 'active'
AND pid != pg_backend_pid();
查询pid的链路
SELECT
blocked_locks.pid AS blocked_pid, -- 被阻塞的进程
blocked_activity.query AS blocked_query, -- 被阻塞的查询
blocking_locks.pid AS blocking_pid, -- 阻塞源进程 (元凶)
blocking_activity.query AS blocking_query, -- 阻塞源正在执行的SQL
-- 计算阻塞时长 (被阻塞进程已经等待了多久)
now() - blocked_activity.query_start AS blocked_duration
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity
ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks
ON blocking_locks.locktype = blocked_locks.locktype
AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database
AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity
ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted order by blocked_duration desc; -- 只查看正在等待锁的进程
数据库连接数
SELECT
client_addr,
COUNT(*) AS connection_count,
COUNT(*) FILTER (WHERE state = 'active') AS active_count
FROM pg_stat_activity
WHERE client_addr IS NOT NULL
GROUP BY client_addr
ORDER BY connection_count DESC;
设置锁超时
-- 设置锁等待超时(10秒)
ALTER SYSTEM SET lock_timeout = '10s';
-- 设置语句执行超时(30秒)
ALTER SYSTEM SET statement_timeout = '30s';
-- 设置空闲事务超时(30秒)
ALTER SYSTEM SET idle_in_transaction_session_timeout = '30s';
-- 重新加载配置(使设置立即对新建会话生效)
SELECT pg_reload_conf();
查询超时参数
-- 查看所有超时参数
SELECT name, setting, unit, context
FROM pg_settings
WHERE name IN (
'lock_timeout',
'statement_timeout',
'idle_in_transaction_session_timeout',
'deadlock_timeout'
);