暂无图片
MogDB - SQL性能问题快速排查
最近更新:2024-04-30 17:27:29

1、前言

本文档用于针对基于MogDB数据库系统生产环境下,SQL运行缓慢,系统性能负载压力过大等问题进行问题定位,问题处理流程,问题成因等各个方面提供指导。 适用于MogDB DBA及相关技术人员。

2、可处理问题

1、前台业务运行缓慢; 2、前台业务运行SQL,但是无返回结果; 3、数据库所在服务器负载高; 4、数据库运行SQL查询没有响应; 5、单条SQL运行长时间没有返回结果。

3、处理流程

3.1 检查系统资源负载

确定是否存在系统资源瓶颈(CPU,Disk IO,MEM),并通过瓶颈类型,简单推测可能出现的问题

## CPU
--CPU突然增高,由以下几个原因导致:
1、短时间内大量并发热点块争用,锁竞争,软/硬解析过多
2、SQL中包含大量jion查询,sort排序,聚合函数甚至是笛卡尔乘积
3、由于数据变动导致的大量的突发表维护操作(auto vacuum/analyze)
4、数据碎片较多的表,维护长版本链的消耗
5、扫描数据量较大的表的同时,存在对表的sort,hash等,也会占用较大cpu资源

--CPU检查:
top命令
htop工具

## DISK IO
--除了CPU增长外,磁盘负载的突然提升,也会导致SQL运行变慢,由以下几个原因导致:
1、大型运维操作争用(vacuum freeze/full);
2、由于数据倾斜导致的SQL执行计划变化,使用了全表扫描替代索引扫描;
3、排序或子查询的数据量较大,排序结果集发生了落盘;
4、定时任务或定期报表等OLAP导致的IO争用;
5、如果服务器是虚拟机,也请检查是否存在iops上限设置等问题

--DISK检查:
iostat -dxt 1 10
## MEM
--由于MogDB使用max_process_memory限制了数据库计算节点可用的最大物理内存,一般情况下不会出现由于内存不足导致的问题,如果出现了内存被MogDB进程大量使用的问题,需要尽快排查是否存在OOM(out of memory)

-- 内存检查:
ps auxw|head -1;ps auxw|sort -rn -k4|head -10 

3.2 检查锁阻塞

对系统负载情况简单摸底后,可以通过数据库pg_locks视图确认是否存在锁阻塞导致了SQL的体感变慢。也可以通过设置lockwait_timeout和update_lockwait_timeout两个参数,规避该类问题的发生

--查看是否存在锁阻塞
with tl as (select a.pid,usename,granted,locktag,query_start,query,mode,a.state
                    from pg_locks l,pg_stat_activity a 
                    where l.pid=a.pid and locktag in(select locktag from pg_locks where granted='f')) 
        select ts.pid locker_pid,ts.usename locker_user,ts.query_start locker_query_start,ts.granted locker_granted,ts.query locker_query,ts.mode locker_mode,tt.pid locked_pid,tt.query locked_query,tt.query_start locked_query_start,tt.granted locked_granted,tt.usename locked_user,tt.mode locked_mode,extract(epoch from now() - tt.query_start) as locked_times
        from (select * from tl where granted='t') as ts,(select * from tl where granted='f') tt 
        where ts.locktag=tt.locktag order by 1;

图片.png

3.3 检查会话并发

当排除锁阻塞问题后,接下来使用数据库pg_stat_activity视图对当前活动会话的并发压力进行态势感知,提取故障/慢SQL。

--检查数据库并发情况
select datname,usename,state,query,count(*)  from pg_stat_activity where state='active' group by datname,usename,state,query order by 5;

图片.png

--根据运行时间阈值定向查找慢SQL,比如已经运行了超过5min的SQL
select pid,datname,usename,state,query,query_start from pg_stat_activity where state='active' and query_start < (now() - interval '5 minutes');

图片.png

--根据pid查询事务链接信息,及时间节点信息
select pid,datname,usename,client_addr,application_name,backend_start,xact_start,query_start,state_change,query,state from pg_stat_activity where pid=140433990350592;

图片.png

3.4 提取慢SQL执行计划

根据从pg_stat_activity数据字典中的提取的慢SQL(或由业务侧直接定位到的慢SQL),接下来就可以诊断执行计划了。但是需要注意的是正在执行的SQL和历史执行过的SQL的query plan,需要在两张不同数据字典查询。同时需要注意只有sysadmin权限可以查询视图。

--正在执行的SQL
--前置参数:
use_workload_manager:资源负载管理总开关,默认on
--如果能筛选出独立的长时间query,根据pid查询语句:
select dbname,
       schemaname,
       username,
       application_name,
       client_addr,
       pid,
       start_time,
       duration,
       estimate_total_time,
       estimate_left_time,
       round(estimate_left_time/estimate_total_time,2)||'%' exec_percent,
       max_cpu_time/1000000 max_cpu_time_s,
       max_peak_memory max_mem_mb,
       max_spill_size max_spill_space_mb,
......