1. 首页 > 国产数据库教程 > openGauss教程 > 正文

opengauss教程FG068-openGauss会话管理与阻塞分析生产实战

本文档详细介绍openGauss数据库会话管理与阻塞分析方法,包括会话状态监控、阻塞分析、会话清理等内容,风哥教程参考openGauss官方文档会话管理、锁管理等内容,适合DBA人员进行会话管理和阻塞处理时参考。

Part01-基础概念与理论知识

1.1 openGauss会话基本概念

openGauss会话特点:

  • 资源占用:每个会话占用一定的内存和连接资源
  • 事务上下文:会话维护事务状态和上下文信息
  • 隔离性:会话之间数据隔离,通过锁机制协调
  • 可管理性:可以通过系统表监控和管理会话

1.2 openGauss阻塞基本概念

阻塞是指一个会话因为等待资源(如锁)而无法继续执行的状态。阻塞会导致会话挂起,严重时可能导致整个系统性能下降。阻塞的常见原因包括锁冲突、资源竞争、长时间事务等。

openGauss阻塞类型:

  • 锁阻塞:等待其他会话释放锁
  • IO阻塞:等待磁盘IO完成
  • 网络阻塞:等待网络数据传输
  • 资源阻塞:等待系统资源(如内存、CPU)

1.3 openGauss会话状态详解

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

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息