数据库性能分析和优化是一个难题,笔者所在的Greenplum研发部门近期正好在解决一个实际用户的全局性能问题,本文记录了分析过程和解决思路。本案例是第一次对实际客户的生产库以GPCC历史数据为核心剖析性能问题,因此有一定的开创性和借鉴意义,故撰文供研发同事、现场工程师、支持工程师参考,同时也适合具备一定GP基础并希望提高的读者阅读。同时为了保护客户的商业秘密,本文不透露任何关于该商业用户的名称、行业等信息,并对数据中的缩写、表名等敏感信息都进行了脱敏处理。
客户在2019-09-22执行了从 GP4.3 到 GP5.20 的升级,随后在10月中旬提出升级后整体性能下降的问题 “overall performance degrade after upgrade” 。现场工程师提出了包括ANALYZE、VACUUM等合理建议,同时售后支持和研发着手分析性能问题。
该客户升级前后都使用了GPCC,GP4.3使用了GPPerfmon+GPCC3的组合,GP5.20使用的是GPCC4.8 (截止发稿时4.9版本已经发布,请使用最新版本),并正确开启了历史数据收集(参见博文如何开启)。在支持人员的协助下,我们得以获得升级前后的相关历史数据。
GPCC的历史数据主要包括系统性能信息和查询历史,后文会结合分析过程详细展开。
该部分历史数据非常庞大,仅9月22日升级后到十月中旬几周内,GPCC 4.8就记录了1.5亿次查询。面对overall performance这一模糊的课题,我们要想真正帮到客户,就需要让这些数据说话。
第一部分,了解GPDB集群的整体性能特征
先介绍GPCC的系统性能历史表
这个表的定义从GPPerfmon到GPCC4.8变化不大,在GPPerfmon时代表名为public.system_history,GPCC4以后为gpmetrics.gpcc_system_history。
GPCC运作时会每分钟四次(分别在00秒、15秒、30秒、45秒)对GPDB集群的每个主机(包括Master、Segment和Standby Master)采样上面所列信息,作用是掌握用户数据库的整体负载状况,可以帮助我们回答诸如以下几个问题:
- 用户的系统负载高不高
- 什么时间段负载最高,是否呈现按小时、天、周的规律
- CPU和DiskIO是否用满,谁是瓶颈
- 系统负载是否随时间推移越来越高(性能退化)
我们使用下面查询来分析一周内的系统资源变化情况
SELECT
ctime::date || '_' || CASE WHEN extract(hour from ctime) < 10 THEN '0' ELSE '' END || extract(hour from ctime) AS date_hour
, avg(cpu_sys) AS cpu_sys
, avg(cpu_user) AS cpu_user
, avg(cpu_sys+cpu_user) AS cpu
, avg(mem_total) AS mem_total
, avg(mem_used) AS mem_used
, avg(mem_actual_used) AS mem_actual
, avg(load0) AS load0
, avg(load1) AS load1
, avg(load2) AS load2
, avg(disk_rb_rate) / 1024 / 1024 AS disk_R_MBs
, avg(disk_wb_rate) / 1024 / 1024 AS disk_W_MBs
, avg(net_rb_rate) / 1024 / 1024 AS net_I_MBs
, avg(net_wb_rate) / 1024 / 1024 AS net_O_MBs
FROM
gpmetrics.gpcc_system_history
WHERE
hostname LIKE 'sdw%'
AND ctime >= '2019-10-09 00:00:00'
AND ctime < '2019-10-16 00:00:00'
GROUP BY 1
ORDER BY 1
;
- 由于每个主机都会被采样,这里我们更关心Segment的负载,因此在WHERE条件上过滤掉了MASTER。也可以根据需要反过来观察MASTER或单个主机上的性能指标。
- 这里我们更关心每个小时的平均值,因此多采用avg(),实际应用中还可以根据需要活用max(), min(), rank()等分析角度。
取得的结果我们可以导入到 Excel、Grafana、Tableu 等办公软件进行图形化的对比。下图是对客户升级前后各取一周时间的样本,重叠到一起观察变化趋势。
剖析
- 整体来看CPU处于非常繁忙状态、全天(周)都处在平均70%以上
- 图中可以看出GP4时代用户每天有一段时间做维护(ANALYZE、VACUUM)导致系统态CPU出现峰值。GP5之后没有每天做。与用户自述一致。
- GP5之后整体CPU比GP4低几个百分点,这个比较复杂,有可能是GP5优化更好,也可能是计算资源不能充分利用,引起查询变慢,尚不明确。
- 内存方面,升级前后系统总内存没变。进程占用的内存前后无太大变化。
- 大部分内存被用作Buff+Cache,这是PostgreSQL特性,无异常。
- Load也表现出GP5略低于GP4,与CPU降低相通,尚不明确。
- 系统整体负载没有明显变化趋势,所以基本排除升级后9月22日到10月中旬期间用户人为引入额外工作负载带来整体性能下降的可能。(后续其他分析佐证)
剖析
- 磁盘IO对比差异明显,GP5的IO大幅增加。
- 网络IO同样提示GP5的开销增大了。
初步诊断用户升级GP5之后磁盘IO/网络IO增加的确存在潜在的性能问题,我们列举出以下一些可能性。
- 用户升级后跑的查询个数是否变多了?(见下面第二部分)
- 表里的数据行数是否变多了?(见下面第三部分)
- 查询的执行计划是否变差了?(见下面第四部分)
- GP5的执行器、BufferPool等内核组件是否有bug?
针对这些怀疑,我们需要进一步查证用户的查询负载。
(未完待续)
获得更多关于Greenpum的技术干货,请访问Greenplum中文社区网站。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。