前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >postgres-checkup PG体检工具

postgres-checkup PG体检工具

作者头像
保持热爱奔赴山海
发布2022-04-18 14:22:35
5600
发布2022-04-18 14:22:35
举报
文章被收录于专栏:饮水机管理员饮水机管理员

项目地址: https://gitlab.com/postgres-ai/postgres-checkup

Postgres Checkup (postgres-checkup) 是一种新型的诊断工具,用于深入分析 Postgres 数据库的健康状况。它检测数据库性能、可扩展性和安全性方面的当前和潜在问题。它还就如何解决或预防这些问题提出建议。

监控系统只会显示当前紧迫的问题。并且 postgres-checkup 将显示潜行的、更深层次的问题,这些问题可能会在未来打击你。它有助于解决许多已知的数据库管理问题和常见的陷阱。它旨在及早发现问题并提出预防问题的最佳方法。我们建议定期运行它们——每周、每月和每季度。并且在对数据库服务器应用任何重大更改之前和之后运行这些。无论是架构或配置参数还是集群设置更改。

1 它不引人注目:它对观测系统的影响接近于零。它不使用任何繁重的查询,保持资源使用率非常低,并避免产生“观察者效应”。 postgres-checkup 报告已在包含 500,000 多个表和 1,000,000 多个索引的真实数据库上成功测试。

2 零安装(在观察到的机器上):它能够分析任何 Linux 机器(包括虚拟机)以及云 Postgres 实例(如 Amazon RD 或 Google Cloud SQL),无需任何额外设置或任何更改。但是,它确实需要 DBA 通常拥有的特权访问权限。

3 复杂分析:与大多数仅提供原始数据的监控工具不同,postgres-checkup 结合了来自系统各个部分的数据(例如,内部 Postgres 统计信息与 autovacuum 设置和行为分析中有关系统资源的知识相结合)将数据加入到井中格式的报告旨在解决特定的 DBA 问题。此外,它还会分析主数据库服务器及其所有副本,这在索引分析或搜索设置偏差等情况下是必要的。

postgres-checkup 支持通过ssh连接到远程PG上执行采集,也支持通过pg连接进行采集。

因为生产环境下可能不容易让我们把pg的机器做ssh打通,因此下面的演示中,我只要在采集机器上安装相关的包即可,主要操作是通过psql去连接远程的pg数据库采集数据的。

采集机器上需要具备的环境:

代码语言:javascript
复制
采集机器上需要具备的环境:
bash
psql
coreutils
jq >= 1.5
go >= 1.17 (no binaries are shipped at the moment)
awk
sed
pandoc   # 如果要输出为html或pdf格式,则需要安装这个包
wkhtmltopdf >= 0.12.4  # 如果要输出为html或pdf格式,则需要安装这个包

1 安装依赖包

代码语言:javascript
复制
yum install git postgresql coreutils jq golang  # 如果已经安装过或者编译安装过,这里就不用yum二次安装了

2 编译代码

代码语言:javascript
复制
git clone https://gitlab.com/postgres-ai/postgres-checkup.git
# Use --branch to use specific release version. For example, to use version 1.1:
#   git clone --branch 1.1 https://gitlab.com/postgres-ai/postgres-checkup.git

如果下载包比较慢的话,可以直接下载tar.gz包,我这里用的是下载好的tar.gz包

cd postgres-checkup-master

cd ./pghrep
make main
cd ..

注意, checkup是按照database维度生成的报告,因此有多个库的话,需要采集多次!

3 生成markdown文档(默认格式就是markdown)

代码语言:javascript
复制
$ export PGPASSWORD='dts'
$ ./checkup -h 192.168.31.181 -p 1921  --username dts --dbname postgres --project prod1 -e 1

或者明确使用pg的连接方式
./checkup --pg-hostname 192.168.31.181 --pg-port 1921 --username dts --dbname mydatabase --connection-timeout 5 --statement-timeout 10 --project prod_app1 -e 1

4 生成html文档(可选,html的结果放到邮件里面更方便查看)

代码语言:javascript
复制
如果要生成html文档,需要先安装相关依赖包

# Optional (to generate PDF/HTML reports)
sudo yum install -y pandoc
wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
tar xvf wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
sudo mv wkhtmltox/bin/wkhtmlto* /usr/local/bin
sudo yum install -y libpng libjpeg openssl icu libX11 libXext libXrender xorg-x11-fonts-Type1 xorg-x11-fonts-75dpi
代码语言:javascript
复制
$ export PGPASSWORD='dts'
$ ./checkup -h 192.168.31.181 -p 1921  --username dts --dbname postgres --project prod1 -e 1 --html

或者明确使用pg的连接方式
./checkup --pg-hostname 192.168.31.181 --pg-port 1921 --username dts --dbname mydatabase --connection-timeout 5 --statement-timeout 10 --project prod_app1 -e 1 --html

因为我们这里没有用ssh方式探测,因此在运行日志里面有些报错,但是基本对指标采集上无影响(有些生产场景下,也不允许随意将db机器和其它节点进行ssh打通)

代码语言:javascript
复制
部分日志如下:
[2022-04-17T20:09:00+0800] Сonnection type (specified): PostgreSQL (192.168.31.181:1921)
[2022-04-17T20:09:00+0800] 
[2022-04-17T20:09:00+0800] ########## Perform checks for host '192.168.31.181':
[2022-04-17T20:09:00+0800] 
[2022-04-17T20:09:00+0800] === Run on '192.168.31.181': ./resources/checks/A001_system_info.sh ===
SSH is not supported, skipping...
[2022-04-17T20:09:00+0800] === End of running ===
[2022-04-17T20:09:00+0800] WARNING: check 'A001' failed with error ^^^
[2022-04-17T20:09:00+0800] 
省略部分
[2022-04-17T20:09:54+0800] K000: markdown reports saved at:
[2022-04-17T20:09:54+0800] './artifacts/prod_app1/md_reports/1_2022_04_17T12_52_08_+0800/K001.md'
[2022-04-17T20:09:54+0800] './artifacts/prod_app1/md_reports/1_2022_04_17T12_52_08_+0800/K002.md'
[2022-04-17T20:09:54+0800] './artifacts/prod_app1/md_reports/1_2022_04_17T12_52_08_+0800/K003.md'
[2022-04-17T20:09:55+0800] L001: markdown report saved at: './artifacts/prod_app1/md_reports/1_2022_04_17T12_52_08_+0800/L001.md'
[2022-04-17T20:09:55+0800] L003: markdown report saved at: './artifacts/prod_app1/md_reports/1_2022_04_17T12_52_08_+0800/L003.md'
[2022-04-17T20:10:01+0800] 
[2022-04-17T20:10:01+0800] Final .md report is ready at:
        './artifacts/prod_app1/md_reports/1_2022_04_17T12_52_08_+0800/0_Full_report.md'
[2022-04-17T20:10:01+0800] 
[2022-04-17T20:10:03+0800] Final .html report is ready at:
        './artifacts/prod_app1/md_reports/1_2022_04_17T12_52_08_+0800/0_Full_report.html'
[2022-04-17T20:10:03+0800]
[2022-04-17T20:10:03+0800] ALL DONE!

注意事项1,一些报告(例如 K003)需要两个快照,以计算指标的“增量”。因此,为了获得更好的结果,请使用以下示例,在高峰工作时间执行它,$DISTANCE 值从 10 分钟到几个小时:

代码语言:javascript
复制
# 下面这种通过增量采集的,可以捕获到top0-50 query等指标信息
$DISTANCE="1800" # 30 minutes

export PGPASSWORD='xxxx'

# 假设主节点master.pg.demo.com,还有2个从节点standby1.pg.demo.com 和 standby2.pg.demo.com
for host in master.pg.demo.com standby1.pg.demo.com standby2.pg.demo.com ; do
  ./checkup \
    -h "$host" \
    -p 5432 \
    --username postgres \
    --dbname postgres \
    --project prod1 \
    -e 1 \
    --file resources/checks/K000_query_analysis.sh   # the first snapshot is needed only for reports K***
done

sleep "$DISTANCE"

for host in master.pg.demo.com standby1.pg.demo.com standby2.pg.demo.com ; do
  ./checkup \
    -h "$host" \
    -p 5432 \
    --username postgres \
    --dbname postgres \
    --project prod1 \
    -e 1
done

使用增量采集后,采集结果中,会多出一项 K003 Top-50 Queries by total_time ,如下图:

postgres-checkup PG体检工具_体检
postgres-checkup PG体检工具_体检

注意事项2,我在执行checkup命令时候,有提示如下报错:

代码语言:javascript
复制
[2022-04-17T12:52:20+0800] === Run on '192.168.31.181': ./resources/checks/K000_query_analysis.sh ===
psql:<stdin>:45: ERROR:  column "total_time" does not exist
LINE 9:       total_time,
              ^
ERROR: To compare results, 2 runs are needed. Please run './checkup collect' once again for this epoch.
NOTICE: ^^ this is not a real error. Just run check again.
[2022-04-17T12:52:21+0800] === End of running ===
[2022-04-17T12:52:21+0800] WARNING: check 'K000' failed with error ^^^

看起来是某个sql问题,对比下看pg_stat_statements的列和sql里面的列的差异,发现是其中一个列不一致导致的:

代码语言:javascript
复制
=# \dx pg_stat_statements
                                          List of installed extensions
        Name        │ Version │ Schema │                              Description                               
────────────────────┼─────────┼────────┼────────────────────────────────────────────────────────────────────────
 pg_stat_statements │ 1.9     │ public │ track planning and execution statistics of all SQL statements executed
(1 row)

=# \d pg_stat_statements
                    View "public.pg_stat_statements"
       Column        │       Type       │ Collation │ Nullable │ Default 
─────────────────────┼──────────────────┼───────────┼──────────┼─────────
 userid              │ oid              │           │          │ 
 dbid                │ oid              │           │          │ 
 toplevel            │ boolean          │           │          │ 
 queryid             │ bigint           │           │          │ 
 query               │ text             │           │          │ 
 plans               │ bigint           │           │          │ 
 total_plan_time     │ double precision │           │          │ 
 min_plan_time       │ double precision │           │          │ 
 max_plan_time       │ double precision │           │          │ 
 mean_plan_time      │ double precision │           │          │ 
 stddev_plan_time    │ double precision │           │          │ 
 calls               │ bigint           │           │          │ 
 total_exec_time     │ double precision │           │          │ 
 min_exec_time       │ double precision │           │          │ 
 max_exec_time       │ double precision │           │          │ 
 mean_exec_time      │ double precision │           │          │ 
 stddev_exec_time    │ double precision │           │          │ 
 rows                │ bigint           │           │          │ 
 shared_blks_hit     │ bigint           │           │          │ 
 shared_blks_read    │ bigint           │           │          │ 
 shared_blks_dirtied │ bigint           │           │          │ 
 shared_blks_written │ bigint           │           │          │ 
 local_blks_hit      │ bigint           │           │          │ 
 local_blks_read     │ bigint           │           │          │ 
 local_blks_dirtied  │ bigint           │           │          │ 
 local_blks_written  │ bigint           │           │          │ 
 temp_blks_read      │ bigint           │           │          │ 
 temp_blks_written   │ bigint           │           │          │ 
 blk_read_time       │ double precision │           │          │ 
 blk_write_time      │ double precision │           │          │ 
 wal_records         │ bigint           │           │          │ 
 wal_fpi             │ bigint           │           │          │ 
 wal_bytes           │ numeric          │           │          │ 

脚本里面写的是 total_time ,在pg_stat_statements 1.9版本里面改为了 total_exec_time,我们改下脚本就可以了:

代码语言:javascript
复制
sed -i.bak 's#total_time#total_exec_time#g' ./resources/checks/K000_query_analysis.sh 

部署到生产的话,还有很多要完善的地方。例如先将库先提取出来,然后逐个进行检测。

代码语言:javascript
复制
# 还没完善,还需要加上不同集群的各实例的定期检测,并将结果定期邮件发出的功能

export PGPASSWORD='dts'

db_arry=$(echo "select datname from pg_database where datname not in ('template1','template0');" |psql -h 192.168.31.181 -p 1921 -Xqt --csv)
echo $db_arry

for dbname in ${db_arry} ; do
  ./checkup -h 192.168.31.181 -p 1921  --username dts --dbname ${dbname} --project prod_instance1_${dbname} -e 1 --html 
done
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-04-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档