【GaussDB 】GaussDB 性能排查与锁等待分析常用 SQL 全面解析(TOP SQL / 等锁 / 长事务 / LwLock / SubPlan)

GaussDB 在实际生产环境中,性能瓶颈与数据库锁等待问题常常是影响业务的核心因素。本文整理了一套 可直接用于排查性能问题的 SQL & 实战案例,涵盖:

  • TOP SQL 耗时分析
  • 会话等锁 & 持锁分析
  • 长事务排查
  • 常规锁 / 轻量级锁(lwlock)案例
  • SubPlan / 子查询引发的性能问题

1. TOP SQL 排查(耗时高、调用高)

在 GaussDB 中,可通过 dbe_perf.summary_statement 快速定位耗时最久的 SQL。

🔍 查询耗时最高的 TOP SQL

sql 复制代码
SELECT
    n_calls,
    unique_sql_id,
    substr(query, 1, 50) AS query,
    total_elapse_time / n_calls / 1000 AS avg_time,
    total_elapse_time / 1000 AS totaltime
FROM
    dbe_perf.summary_statement
WHERE
    user_name = 'root'
    AND n_calls > 1
ORDER BY
    totaltime DESC;

可用于快速识别:

  • 平均耗时最高的 SQL
  • 调用次数高但效率差的 SQL
  • 业务热点 SQL 性能瓶颈

2、等锁 & 持锁会话排查(阻塞分析)

当业务出现"卡顿""SQL 无响应"时,首要处理方向就是锁等待。

🔍 查找等待锁的会话与持锁会话

sql 复制代码
SELECT
    a.query_id,            
    a.query AS waiting_sql,    
    b.wait_status,         
    b.wait_event,          
    b.block_sessionid,     
    c.pid AS block_id,     
    c.query AS block_query 
FROM
    pg_stat_activity a,
    pg_thread_wait_status b,
    pg_stat_activity c
WHERE
    a.query_id = b.query_id
    AND b.block_sessionid = c.sessionid
    AND a.state != 'idle'
    AND a.datname = 'postgres';

可直接判断:

  • 哪条 SQL 在等锁
  • 哪个会话造成阻塞
  • 等待事件类型(锁 / IO / LWLock / 其他)

3、长事务排查(经典导致锁问题的根源)

长事务可能导致:

  • 锁长时间不释放
  • 膨胀(dead tuple)无法清理
  • 真正的性能瓶颈

🔍 查找持续时间最长的事务

sql 复制代码
SELECT
    (now() - xact_start) AS diff_time,
    pid,
    sessionid,
    query
FROM
    pg_stat_activity
WHERE
    state = 'active'
ORDER BY
    diff_time DESC;

案例:长事务造成阻塞分析

步骤 1:先查看阻塞关系(等锁 SQL)

使用第 2 节的等锁 SQL,发现会话 2 被会话 1 阻塞:

  • 会话 2:执行 UPDATE → 需要 RowExclusiveLock
  • 会话 1:执行 LOCK TABLE → 持有 AccessExclusiveLock

二者锁模式不兼容 → 形成锁等待。

后台日志也能看到冲突

路径:

$GAUSSLOG/pg_log/dn_6001

日志信息会明确提示:

  • 会话 2 请求 RowExclusiveLock
  • 会话 1 持有 AccessExclusiveLock
  • 锁冲突产生阻塞

4、 常规锁分析(pg_locks + wait event)

该 SQL 适用于排查阻塞链路+锁类型+等待事件。

🔍 常规锁排查 SQL

sql 复制代码
SELECT
    (now() - s.xact_start) diff_time,
    s.pid,
    s.sessionid,
    s.query,
    locktag_decode(l.locktag) AS locktag,
    t.node_name,
    t.db_name,
    t.thread_name,
    t.wait_status,
    t.wait_event
FROM
    pg_thread_wait_status t,
    pg_locks l,
    pg_stat_activity s
WHERE
    t.locktag = l.locktag
    AND l.granted = 't'
    AND s.pid = t.tid;

🔍 示例分析

情况 1:
idle in transaction

说明:

  • 手动开启事务但未提交
  • 或发生 CN 剔除 / 主备切换导致事务残留

→ 这种事务不提交就会一直占锁。

情况 2:等待事件为
acquire lock

说明:

  • 该线程等待另一个事务释放锁
  • 继续溯源即可找到真正的阻塞点

情况 3:等待事件为
acquire lwlock

说明:

  • 正在申请轻量级锁(LWLock)
  • 特别是 "LockMgrLock" 说明主锁表竞争高
  • 多发生在并发较大系统中

5、轻量级锁(LWLock)分析

LWLock 是 GaussDB 内部的轻量级锁,用于:

  • 保护共享内存结构
  • 维持锁管理器、buffer、wal buffer 的线程安全

🔍 查询 LWLock 情况

sql 复制代码
SELECT
    (now() - s.xact_start) diff_time,
    s.pid,
    s.sessionid,
    s.query,
    t.*,
    lw.*
FROM
    pg_stat_activity s,
    pg_thread_wait_status t,
    gs_lwlock_status() lw
WHERE
    s.state = 'active'
    AND s.pid = t.tid
    AND t.sessionid = lw.sessionid
    AND lw.granted = 't'
ORDER BY
    diff_time DESC;

备注:如遇 "LockMgrLock" 则表示主锁表竞争严重,常见于热点表、超高并发场景。

6. SubPlan / 子查询导致性能问题

什么是 SubQuery / SubLink?

SubQuery:SQL 中的子查询语法

SubLink:执行计划中子查询的表达方式

在执行计划中看到:

SubPlan

通常意味着性能隐患,例如:

  • 子查询被重复执行
  • 触发 NESTED LOOP + 子查询组合
  • 无法使用索引回表

常用优化方式

总结

本文整理 GaussDB 中与性能瓶颈和锁等待排查最相关的 SQL,包括:

  • TOP SQL 分析
  • 等锁 & 持锁会话排查
  • 长事务定位
  • 常规锁 / 轻量级锁(LWLock)分析
  • SubPlan 性能问题识别

如果你正在做生产排障或稳定性优化,这套 SQL 可以直接作为"随手工具箱"。

相关推荐
剩下了什么3 小时前
MySQL JSON_SET() 函数
数据库·mysql·json
山峰哥4 小时前
数据库工程与SQL调优——从索引策略到查询优化的深度实践
数据库·sql·性能优化·编辑器
较劲男子汉4 小时前
CANN Runtime零拷贝传输技术源码实战 彻底打通Host与Device的数据传输壁垒
运维·服务器·数据库·cann
java搬砖工-苤-初心不变4 小时前
MySQL 主从复制配置完全指南:从原理到实践
数据库·mysql
山岚的运维笔记6 小时前
SQL Server笔记 -- 第18章:Views
数据库·笔记·sql·microsoft·sqlserver
roman_日积跬步-终至千里7 小时前
【LangGraph4j】LangGraph4j 核心概念与图编排原理
java·服务器·数据库
汇智信科7 小时前
打破信息孤岛,重构企业效率:汇智信科企业信息系统一体化运营平台
数据库·重构
野犬寒鸦7 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
WHD3068 小时前
苏州数据库(SQL Oracle)文件损坏修复
hadoop·sql·sqlite·flume·memcached
晚霞的不甘8 小时前
揭秘 CANN 内存管理:如何让大模型在小设备上“轻装上阵”?
前端·数据库·经验分享·flutter·3d