opengauss教程FG068-openGauss会话管理与阻塞分析生产实战
本文档详细介绍openGauss数据库会话管理与阻塞分析方法,包括会话状态监控、阻塞分析、会话清理等内容,风哥教程参考openGauss官方文档会话管理、锁管理等内容,适合DBA人员进行会话管理和阻塞处理时参考。
Part01-基础概念与理论知识
1.1 openGauss会话基本概念
- 资源占用:每个会话占用一定的内存和连接资源
- 事务上下文:会话维护事务状态和上下文信息
- 隔离性:会话之间数据隔离,通过锁机制协调
- 可管理性:可以通过系统表监控和管理会话
1.2 openGauss阻塞基本概念
阻塞是指一个会话因为等待资源(如锁)而无法继续执行的状态。阻塞会导致会话挂起,严重时可能导致整个系统性能下降。阻塞的常见原因包括锁冲突、资源竞争、长时间事务等。
- 锁阻塞:等待其他会话释放锁
- IO阻塞:等待磁盘IO完成
- 网络阻塞:等待网络数据传输
- 资源阻塞:等待系统资源(如内存、CPU)
1.3 openGauss会话状态详解
openGauss会话有以下几种状态:
1. active(活跃)
– 含义:正在执行查询
– 特点:占用CPU资源
– 注意:长时间active可能表示慢查询
2. idle(空闲)
– 含义:连接建立但未执行查询
– 特点:占用连接但不占用CPU
– 注意:长时间idle可能表示连接池泄漏
3. idle in transaction(事务中空闲)
– 含义:事务已开始但未提交或回滚
– 特点:持有事务锁
– 注意:最危险的状态,容易导致阻塞
4. idle in transaction (aborted)(事务中止)
– 含义:事务出错但未回滚
– 特点:需要手动回滚
– 注意:占用资源且无法执行新查询
5. fastpath function call(快速路径调用)
– 含义:执行快速路径函数
– 特点:短暂状态
– 注意:通常无需关注
6. disabled(禁用)
– 含义:会话被禁用
– 特点:无法执行查询
– 注意:需要重新启用
# 会话状态转换图
建立连接
|
v
+——–+ 执行查询 +——–+
| idle | —————–> | active |
+——–+ +——–+
^ |
| | 查询完成
| v
| +——–+
| | idle |
| +——–+
| |
| | BEGIN
| v
| +————————+
| | idle in transaction |
| +————————+
| |
| | COMMIT/ROLLBACK
| v
+——————————+
# 危险状态识别
– idle in transaction > 1分钟:需要关注
– idle in transaction > 10分钟:需要处理
– active > 5分钟:可能是慢查询
– idle > 1小时:可能是连接池泄漏
Part02-生产环境规划与建议
2.1 openGauss会话管理策略
会话管理策略:
1. 连接池配置
– 使用连接池管理连接
– 设置合理的连接池大小
– 配置连接超时和空闲超时
2. 会话超时配置
# 空闲会话超时
idle_in_transaction_session_timeout = 60000 # 1分钟
# 连接空闲超时
tcp_keepalives_idle = 60
tcp_keepalives_interval = 10
tcp_keepalives_count = 6
# 语句超时
statement_timeout = 300000 # 5分钟
3. 会话限制配置
# 最大连接数
max_connections = 2000
# 超级用户保留连接
superuser_reserved_connections = 10风哥提示:
# 用户级连接限制
ALTER USER fgedu WITH CONNECTION LIMIT 100;
4. 会话监控策略
– 监控活跃会话数
– 监控空闲会话数
– 监控长事务
– 监控阻塞会话
5. 会话清理策略
– 定期清理空闲会话
– 自动回滚长事务
– 终止异常会话
2.2 openGauss阻塞预防策略
阻塞预防策略:
1. 应用层优化
– 缩短事务执行时间
– 及时提交或回滚事务
– 避免在事务中等待用户输入
– 按相同顺序访问资源
2. 数据库层优化
– 使用合适的隔离级别
– 优化SQL执行计划学习交流加群风哥微信: itpux-com
– 创建合适的索引
– 避免全表扫描
3. 锁优化策略
– 使用行级锁替代表级锁
– 减少锁持有时间
– 使用NOWAIT选项
– 设置锁等待超时
4. 监控告警策略
# 阻塞检测
– 检测锁等待会话
– 检测长时间事务
– 检测死锁
# 告警阈值
– 锁等待 > 30秒:警告
– 锁等待 > 5分钟:严重
– 事务时间 > 10分钟:警告
– 事务时间 > 30分钟:严重
5. 自动处理策略
# 自动终止长时间会话
# 自动回滚空闲事务
# 自动清理僵尸会话
2.3 openGauss监控策略设计
监控策略设计:
1. 会话监控指标
– 总连接数
– 活跃会话数
– 空闲会话数
– 事务中空闲会话数
– 长事务数量
– 阻塞会话数量
2. 监控频率学习交流加群风哥QQ113257174
– 关键指标:10秒
– 一般指标:60秒
– 趋势指标:300秒
3. 告警规则
# 连接数告警
– 连接数 > 80%:警告
– 连接数 > 90%:严重
# 阻塞告警
– 阻塞会话 > 0:警告
– 阻塞时间 > 5分钟:严重
# 长事务告警
– 事务时间 > 10分钟:警告
– 事务时间 > 30分钟:严重
4. 监控脚本
#!/bin/bash
# session_monitor.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
DB_IP=”192.168.1.10″
echo “=== 会话监控 ===”
# 会话统计
gsql -h $DB_IP -d postgres -c ”
SELECT
state,
count(*) as count
FROM pg_stat_activity
GROUP BY state
ORDER BY count DESC;
”
# 长事务
gsql -h $DB_IP -d postgres -c “更多视频教程www.fgedu.net.cn
SELECT
count(*) as long_transaction_count
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
AND now() – xact_start > interval ’10 minutes’;
”
# 阻塞会话
gsql -h $DB_IP -d postgres -c ”
SELECT
count(*) as blocking_count
FROM pg_locks
WHERE NOT granted;
”
Part03-生产环境项目实施方案
3.1 openGauss会话查询管理
#!/bin/bash
# session_management.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
DB_IP=”192.168.1.10″
echo “=== openGauss会话管理 ===”
echo “管理时间: $(date)”
# 1. 查看所有会话
echo “”
echo “— 1. 所有会话统计 —”
gsql -h $DB_IP -d postgres -c ”
SELECT 更多学习教程公众号风哥教程itpux_com
state,
count(*) as count,
ROUND(100.0 * count(*) / sum(count(*)) OVER(), 2) as percentage
FROM pg_stat_activity
GROUP BY state
ORDER BY count DESC;
”
# 2. 查看活跃会话
echo “”
echo “— 2. 活跃会话详情 —”
gsql -h $DB_IP -d postgres -c ”
SELECT
pid,
usename,
application_name,
client_addr,
wait_event_type,
wait_event,
TO_CHAR(query_start, ‘HH24:MI:SS’) as query_start,
EXTRACT(EPOCH FROM (now() – query_start)) as duration_seconds,
LEFT(query, 150) as query_text
FROM pg_stat_activity
WHERE state = ‘active’
ORDER BY query_start;
”
# 3. 查看空闲事务
echo “”
echo “— 3. 空闲事务详情 —“from DB视频:www.itpux.com
gsql -h $DB_IP -d postgres -c ”
SELECT
pid,
usename,
application_name,
TO_CHAR(xact_start, ‘HH24:MI:SS’) as xact_start,
EXTRACT(EPOCH FROM (now() – xact_start)) as transaction_duration,
LEFT(query, 150) as last_query
FROM pg_stat_activity
WHERE state = ‘idle in transaction’
ORDER BY xact_start;
”
# 4. 查看空闲连接
echo “”
echo “— 4. 长时间空闲连接 —”
gsql -h $DB_IP -d postgres -c ”
SELECT
pid,
usename,
application_name,
client_addr,
TO_CHAR(state_change, ‘HH24:MI:SS’) as idle_since,
EXTRACT(EPOCH FROM (now() – state_change)) as idle_duration
FROM pg_stat_activity
WHERE state = ‘idle’
AND now() – state_change > interval ‘1 hour’
ORDER BY state_change;
”
# 5. 查看会话资源使用
echo “”
echo “— 5. 会话资源使用 —”
gsql -h $DB_IP -d postgres -c ”
SELECT
pid,
usename,
application_name,
backend_start,
xact_start,
query_start,
state_change,
wait_event_type,
wait_event
FROM pg_stat_activity
WHERE pid != pg_backend_pid()
ORDER BY backend_start
LIMIT 20;
”
# 执行结果
=== openGauss会话管理 ===
管理时间: Thu Apr 9 14:00:00 CST 2026
— 1. 所有会话统计 —
state | count | percentage
———————+——-+————
idle | 80 | 80.00
active | 15 | 15.00
idle in transaction | 5 | 5.00
(3 rows)
— 2. 活跃会话详情 —
pid | usename | application_name | client_addr | wait_event_type | wait_event | query_start | duration_seconds | query_text
——+———+——————+—————-+—————–+————+————-+——————+—————-
1234 | fgedu | app1 | 192.168.1.20 | | | 13:59:50 | 10 | SELECT * FROM fgedu.orders…
1235 | fgedu | app2 | 192.168.1.21 | Lock | transactionid| 13:59:45 | 15 | UPDATE fgedu.users…
(2 rows)
— 3. 空闲事务详情 —
pid | usename | application_name | xact_start | transaction_duration | last_query
——+———+——————+————+———————-+————
1240 | fgedu | app5 | 13:30:00 | 1800 | BEGIN;
1241 | fgedu | app6 | 13:45:00 | 900 | SELECT * FROM fgedu.products;
(2 rows)
— 4. 长时间空闲连接 —
pid | usename | application_name | client_addr | idle_since | idle_duration
——+———+——————+—————-+————+—————
1250 | fgedu | old_app | 192.168.1.30 | 12:00:00 | 7200
(1 row)
— 5. 会话资源使用 —
pid | usename | application_name | backend_start | xact_start | query_start | state_change | wait_event_type | wait_event
——+———+——————+————————+———————–+———————–+———————–+—————–+————
1234 | fgedu | app1 | 2026-04-09 08:00:00 | 2026-04-09 13:59:50 | 2026-04-09 13:59:50 | 2026-04-09 13:59:50 | |
(1 row)
3.2 openGauss阻塞分析处理
#!/bin/bash
# blocking_analysis.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
DB_IP=”192.168.1.10″
echo “=== openGauss阻塞分析 ===”
echo “分析时间: $(date)”
# 1. 查看锁等待情况
echo “”
echo “— 1. 锁等待情况 —”
gsql -h $DB_IP -d postgres -c ”
SELECT
l.locktype,
l.relation::regclass as relation,
l.mode,
l.granted,
l.pid,
a.usename,
a.application_name,
a.state,
LEFT(a.query, 100) as query
FROM pg_locks l
JOIN pg_stat_activity a ON l.pid = a.pid
WHERE l.relation IS NOT NULL
ORDER BY l.relation, l.granted, l.pid;
”
# 2. 查看阻塞关系
echo “”
echo “— 2. 阻塞关系 —”
gsql -h $DB_IP -d postgres -c ”
SELECT
blocked_locks.pid AS blocked_pid,
blocked_activity.usename AS blocked_user,
blocked_activity.query AS blocked_query,
blocking_locks.pid AS blocking_pid,
blocking_activity.usename AS blocking_user,
blocking_activity.query AS blocking_query
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.page IS NOT DISTINCT FROM blocked_locks.page
AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
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;
”
# 3. 查看等待事件
echo “”
echo “— 3. 等待事件统计 —”
gsql -h $DB_IP -d postgres -c ”
SELECT
wait_event_type,
wait_event,
count(*) as count
FROM pg_stat_activity
WHERE state = ‘active’
AND wait_event_type IS NOT NULL
GROUP BY wait_event_type, wait_event
ORDER BY count DESC;
”
# 4. 终止阻塞会话
echo “”
echo “— 4. 终止阻塞会话(示例) —”
echo “终止PID为1234的会话:”
echo “SELECT pg_terminate_backend(1234);
”
# 5. 取消查询
echo “”
echo “— 5. 取消查询(示例) —”
echo “取消PID为1234的查询:”
echo “SELECT pg_cancel_backend(1234);
”
# 执行结果
=== openGauss阻塞分析 ===
分析时间: Thu Apr 9 14:30:00 CST 2026
— 1. 锁等待情况 —
locktype | relation | mode | granted | pid | usename | application_name | state | query
————-+————-+—————-+———+——+———+——————+——–+——————-
relation | fgedu.orders| AccessShareLock| t | 1234 | fgedu | app1 | active | SELECT * FROM…
relation | fgedu.orders| RowExclusiveLock| f | 1235 | fgedu | app2 | active | UPDATE fgedu.orders…
(2 rows)
— 2. 阻塞关系 —
blocked_pid | blocked_user | blocked_query | blocking_pid | blocking_user | blocking_query
————-+————–+—————+————–+—————+—————-
1235 | fgedu | UPDATE… | 1234 | fgedu | SELECT…
(1 row)
— 3. 等待事件统计 —
wait_event_type | wait_event | count
—————–+—————–+——-
Lock | transactionid | 3
IO | DataFileRead | 2
Client | ClientRead | 1
(3 rows)
— 4. 终止阻塞会话(示例) —
终止PID为1234的会话:
SELECT pg_terminate_backend(1234);
— 5. 取消查询(示例) —
取消PID为1234的查询:
SELECT pg_cancel_backend(1234);
3.3 openGauss会话优化配置
# 步骤1:配置会话超时
$ cat >> /opengauss/fgdata/postgresql.conf << EOF
# 会话超时配置
idle_in_transaction_session_timeout = 60000 # 1分钟,自动终止空闲事务
statement_timeout = 300000 # 5分钟,语句执行超时
lock_timeout = 30000 # 30秒,锁等待超时
# TCP保活配置
tcp_keepalives_idle = 60
tcp_keepalives_interval = 10
tcp_keepalives_count = 6
EOF
# 步骤2:配置连接限制
$ gsql -d postgres -c "
-- 设置用户级连接限制
ALTER USER fgedu WITH CONNECTION LIMIT 100;
-- 设置数据库级连接限制
ALTER DATABASE fgedudb WITH CONNECTION LIMIT 500;
"
ALTER ROLE
ALTER DATABASE
# 步骤3:配置资源队列(企业版)
$ gsql -d postgres -c "
-- 创建资源队列
CREATE RESOURCE QUEUE fgedu_queue WITH (
ACTIVE_STATEMENTS = 50,
MEMORY_LIMIT = '8GB',
MAX_COST = 1000000
);
-- 将用户关联到资源队列
ALTER USER fgedu RESOURCE QUEUE fgedu_queue;
"
CREATE RESOURCE QUEUE
ALTER ROLE
# 步骤4:重启数据库
$ gs_ctl restart -D /opengauss/fgdata
# 步骤5:验证配置
$ gsql -d postgres -c "SHOW idle_in_transaction_session_timeout;
”
idle_in_transaction_session_timeout
————————————-
1min
(1 row)
$ gsql -d postgres -c “SHOW statement_timeout;
”
statement_timeout
——————-
5min
(1 row)
$ gsql -d postgres -c “SELECT rolconnlimit FROM pg_roles WHERE rolname = ‘fgedu’;
”
rolconnlimit
————–
100
(1 row)
Part04-生产案例与实战讲解
4.1 openGauss会话清理案例
4.1.1 问题描述
数据库连接数接近上限,需要清理无效会话。
4.1.2 清理方案
#!/bin/bash
# session_cleanup.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
DB_IP=”192.168.1.10″
LOG_FILE=”/opengauss/log/session_cleanup.log”
log() {
echo “[$(date ‘+%Y-%m-%d %H:%M:%S’)] $1” | tee -a $LOG_FILE
}
# 清理空闲事务
cleanup_idle_transactions() {
log “=== 清理空闲事务 ===”
# 查找空闲时间超过10分钟的会话
gsql -h $DB_IP -d postgres -t -c ”
SELECT pid
FROM pg_stat_activity
WHERE state = ‘idle in transaction’
AND now() – xact_start > interval ’10 minutes’;
” | while read pid; do
if [ -n “$pid” ]; then
log “终止空闲事务会话: $pid”
gsql -h $DB_IP -d postgres -c “SELECT pg_terminate_backend($pid);
”
fi
done
}
# 清理长时间空闲连接
cleanup_idle_connections() {
log “=== 清理长时间空闲连接 ===”
# 查找空闲时间超过2小时的会话
gsql -h $DB_IP -d postgres -t -c ”
SELECT pid
FROM pg_stat_activity
WHERE state = ‘idle’
AND now() – state_change > interval ‘2 hours’
AND pid != pg_backend_pid();
” | while read pid; do
if [ -n “$pid” ]; then
log “终止空闲连接: $pid”
gsql -h $DB_IP -d postgres -c “SELECT pg_terminate_backend($pid);
”
fi
done
}
# 清理异常会话
cleanup_abnormal_sessions() {
log “=== 清理异常会话 ===”
# 查找异常会话(idle in transaction (aborted))
gsql -h $DB_IP -d postgres -t -c ”
SELECT pid
FROM pg_stat_activity
WHERE state = ‘idle in transaction (aborted)’;
” | while read pid; do
if [ -n “$pid” ]; then
log “终止异常会话: $pid”
gsql -h $DB_IP -d postgres -c “SELECT pg_terminate_backend($pid);
”
fi
done
}
# 主逻辑
main() {
log “========== 会话清理开始 ==========”
cleanup_idle_transactions
cleanup_idle_connections
cleanup_abnormal_sessions
log “========== 会话清理结束 ==========”
}
main
# 执行结果
[2026-04-09 15:00:00] ========== 会话清理开始 ==========
[2026-04-09 15:00:00] === 清理空闲事务 ===
[2026-04-09 15:00:01] 终止空闲事务会话: 1240
[2026-04-09 15:00:02] 终止空闲事务会话: 1241
[2026-04-09 15:00:03] === 清理长时间空闲连接 ===
[2026-04-09 15:00:04] 终止空闲连接: 1250
[2026-04-09 15:00:05] === 清理异常会话 ===
[2026-04-09 15:00:06] ========== 会话清理结束 ==========
4.2 openGauss阻塞解决案例
4.2.1 问题描述
应用反馈查询卡住,怀疑是阻塞问题。
4.2.2 解决方案
#!/bin/bash
# blocking_resolution.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
DB_IP=”192.168.1.10″
LOG_FILE=”/opengauss/log/blocking_resolution.log”
log() {
echo “[$(date ‘+%Y-%m-%d %H:%M:%S’)] $1” | tee -a $LOG_FILE
}
# 分析阻塞情况
analyze_blocking() {
log “=== 阻塞情况分析 ===”
# 获取阻塞关系
gsql -h $DB_IP -d postgres -c ”
SELECT
blocked_locks.pid AS blocked_pid,
blocked_activity.usename AS blocked_user,
blocked_activity.application_name AS blocked_app,
EXTRACT(EPOCH FROM (now() – blocked_activity.query_start)) AS blocked_duration,
LEFT(blocked_activity.query, 100) AS blocked_query,
blocking_locks.pid AS blocking_pid,
blocking_activity.usename AS blocking_user,
blocking_activity.application_name AS blocking_app,
EXTRACT(EPOCH FROM (now() – blocking_activity.query_start)) AS blocking_duration,
LEFT(blocking_activity.query, 100) AS blocking_query
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.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;
” >> $LOG_FILE
}
# 解决阻塞
resolve_blocking() {
log “=== 解决阻塞 ===”
# 终止长时间阻塞的会话(超过5分钟)
gsql -h $DB_IP -d postgres -t -c ”
SELECT DISTINCT blocking_locks.pid
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.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
AND now() – blocking_activity.query_start > interval ‘5 minutes’;
” | while read pid; do
if [ -n “$pid” ]; then
log “终止阻塞会话: $pid”
gsql -h $DB_IP -d postgres -c “SELECT pg_terminate_backend($pid);
”
fi
done
}
# 验证解决结果
verify_resolution() {
log “=== 验证解决结果 ===”
BLOCKING_COUNT=$(gsql -h $DB_IP -d postgres -t -c ”
SELECT count(*) FROM pg_locks WHERE NOT granted;
” | tr -d ‘ ‘)
log “当前阻塞会话数: $BLOCKING_COUNT”
if [ “$BLOCKING_COUNT” -eq 0 ]; then
log “阻塞已解决”
else
log “警告: 仍有 $BLOCKING_COUNT 个阻塞会话”
fi
}
# 主逻辑
main() {
log “========== 阻塞解决开始 ==========”
analyze_blocking
resolve_blocking
verify_resolution
log “========== 阻塞解决结束 ==========”
}
main
# 执行结果
[2026-04-09 15:30:00] ========== 阻塞解决开始 ==========
[2026-04-09 15:30:00] === 阻塞情况分析 ===
[2026-04-09 15:30:01] === 解决阻塞 ===
[2026-04-09 15:30:02] 终止阻塞会话: 1234
[2026-04-09 15:30:03] === 验证解决结果 ===
[2026-04-09 15:30:04] 当前阻塞会话数: 0
[2026-04-09 15:30:05] 阻塞已解决
[2026-04-09 15:30:06] ========== 阻塞解决结束 ==========
4.3 openGauss空闲会话处理案例
4.3.1 问题描述
连接池配置不当,导致大量空闲连接占用资源。
4.3.2 处理方案
#!/bin/bash
# idle_session_handler.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
DB_IP=”192.168.1.10″
echo “=== 空闲会话处理 ===”
echo “处理时间: $(date)”
# 1. 统计空闲会话
echo “”
echo “— 1. 空闲会话统计 —”
gsql -h $DB_IP -d postgres -c ”
SELECT
usename,
application_name,
client_addr,
count(*) as idle_count,
MAX(EXTRACT(EPOCH FROM (now() – state_change))) as max_idle_seconds
FROM pg_stat_activity
WHERE state = ‘idle’
GROUP BY usename, application_name, client_addr
ORDER BY idle_count DESC;
”
# 2. 查看空闲时间分布
echo “”
echo “— 2. 空闲时间分布 —”
gsql -h $DB_IP -d postgres -c ”
SELECT
CASE
WHEN EXTRACT(EPOCH FROM (now() – state_change)) < 60 THEN '< 1分钟'
WHEN EXTRACT(EPOCH FROM (now() - state_change)) < 300 THEN '1-5分钟'
WHEN EXTRACT(EPOCH FROM (now() - state_change)) < 600 THEN '5-10分钟'
WHEN EXTRACT(EPOCH FROM (now() - state_change)) < 3600 THEN '10-60分钟'
ELSE '> 1小时’
END as idle_range,
count(*) as count
FROM pg_stat_activity
WHERE state = ‘idle’
GROUP BY 1
ORDER BY 1;
”
# 3. 终止超时空闲会话
echo “”
echo “— 3. 终止超时空闲会话 —”
gsql -h $DB_IP -d postgres -t -c ”
SELECT pid
FROM pg_stat_activity
WHERE state = ‘idle’
AND now() – state_change > interval ‘1 hour’
AND pid != pg_backend_pid();
” | while read pid; do
if [ -n “$pid” ]; then
echo “终止空闲会话: $pid”
gsql -h $DB_IP -d postgres -c “SELECT pg_terminate_backend($pid);
”
fi
done
# 4. 优化建议
echo “”
echo “— 4. 连接池优化建议 —”
echo “建议调整以下参数:”
echo “1. idle_in_transaction_session_timeout = 60000”
echo “2. 应用层连接池配置:”
echo ” – maxIdleTime = 300000 (5分钟)”
echo ” – maxLifetime = 1800000 (30分钟)”
echo ” – connectionTimeout = 30000 (30秒)”
# 执行结果
=== 空闲会话处理 ===
处理时间: Thu Apr 9 16:00:00 CST 2026
— 1. 空闲会话统计 —
usename | application_name | client_addr | idle_count | max_idle_seconds
———+——————+—————-+————+——————
fgedu | app1 | 192.168.1.20 | 50 | 7200
fgedu | app2 | 192.168.1.21 | 30 | 3600
(2 rows)
— 2. 空闲时间分布 —
idle_range | count
————+——-
< 1分钟 | 10
1-5分钟 | 20
5-10分钟 | 15
10-60分钟 | 25
> 1小时 | 10
(5 rows)
— 3. 终止超时空闲会话 —
终止空闲会话: 1250
终止空闲会话: 1251
— 4. 连接池优化建议 —
建议调整以下参数:
1. idle_in_transaction_session_timeout = 60000
2. 应用层连接池配置:
– maxIdleTime = 300000 (5分钟)
– maxLifetime = 1800000 (30分钟)
– connectionTimeout = 30000 (30秒)
Part05-风哥经验总结与分享
5.1 openGauss会话管理最佳实践
会话管理最佳实践:
- 连接池管理:使用连接池管理数据库连接,避免频繁创建和销毁连接
- 超时配置:合理配置各类超时参数,及时释放无效连接
- 事务管理:及时提交或回滚事务,避免长时间持有锁
- 监控告警:建立会话监控和告警机制,及时发现异常
- 定期清理:定期清理空闲和异常会话,释放资源
5.2 openGauss常用脚本集
1. 查看活跃会话
gsql -h $DB_IP -d postgres -c ”
SELECT pid, usename, state, LEFT(query, 100)
FROM pg_stat_activity
WHERE state = ‘active’;
”
2. 查看阻塞会话
gsql -h $DB_IP -d postgres -c ”
SELECT * FROM pg_locks WHERE NOT granted;
”
3. 终止会话
gsql -h $DB_IP -d postgres -c ”
SELECT pg_terminate_backend($PID);
”
4. 取消查询
gsql -h $DB_IP -d postgres -c ”
SELECT pg_cancel_backend($PID);
”
5. 查看长事务
gsql -h $DB_IP -d postgres -c ”
SELECT pid, usename, now() – xact_start as duration
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
ORDER BY xact_start;
”
6. 查看空闲连接
gsql -h $DB_IP -d postgres -c ”
SELECT pid, usename, now() – state_change as idle_time
FROM pg_stat_activity
WHERE state = ‘idle’
ORDER BY state_change;
”
5.3 openGauss常见问题处理
常见问题处理:
- 连接数满:清理空闲连接,增加max_connections,优化连接池
- 阻塞严重:分析阻塞链,终止阻塞源会话,优化SQL
- 长事务:检查应用逻辑,设置事务超时,及时提交
- 连接泄漏:检查连接池配置,设置连接超时,定期清理
- 性能下降:分析活跃会话,优化慢查询,调整资源分配
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
