首页 > 数据库 >postgresql 定时收集表和索引统计信息 转发:https://blog.csdn.net/weixin_33711641/article/details/89752462

postgresql 定时收集表和索引统计信息 转发:https://blog.csdn.net/weixin_33711641/article/details/89752462

时间:2024-08-20 10:06:44浏览次数:12  
标签:stat postgresql idx weixin blks tup read pg 33711641

--由于pg中表和索引的信息收集都是基于时间点的,对于以往的信息无法与现在的信息进行对比,故写下此工具进行统计信息收集

--创建数据信息的schema
create schema db_stat;
--创建收集信息的基础表
create table db_stat.snapshot_pg_stat_all_indexes
(relid int,indexrelid int,schemaname varchar(200),relname varchar(550),indexrelname varchar(550),idx_scan bigint,idx_tup_read bigint,idx_tup_fetch bigint,
snapid int,snap_create_time timestamp,host_ip cidr,host_port int,host_type varchar(20),comment varchar(500));
create index idx_stat_indexe_relname_indexrelname_createtime on db_stat.snapshot_pg_stat_all_indexes(relname varchar_pattern_ops,indexrelname varchar_pattern_ops,snap_create_time);
create index idx_stat_indexe_snapid on db_stat.snapshot_pg_stat_all_indexes(snapid);

create table db_stat.snapshot_pg_stat_all_tables
(relid int,schemaname varchar(200),relname varchar(550),seq_scan bigint,seq_tup_read bigint,idx_scan bigint,idx_tup_fetch bigint,n_tup_ins bigint,n_tup_upd bigint,
n_tup_del bigint,n_tup_hot_upd bigint,n_live_tup bigint,n_dead_tup bigint,last_vacuum timestamp,last_autovacuum timestamp,last_analyze timestamp,last_autoanalyze timestamp,vacuum_count bigint,autovacuum_count bigint,analyze_count bigint,autoanalyze_count bigint,
snapid int,snap_create_time timestamp,host_ip cidr,host_port int,host_type varchar(20),comment varchar(500));
create index idx_stat_table_relname_createtime on db_stat.snapshot_pg_stat_all_tables(relname varchar_pattern_ops,snap_create_time);
create index idx_stat_table_snapid on db_stat.snapshot_pg_stat_all_tables(snapid);

create table db_stat.snapshot_pg_statio_all_indexes
(relid int,indexrelid int,schemaname varchar(200),relname varchar(550),indexrelname varchar(550),idx_blks_read bigint,idx_blks_hit bigint,
snapid int,snap_create_time timestamp,host_ip cidr,host_port int,host_type varchar(20),comment varchar(500));
create index idx_statio_indexe_relname_indexrelname_createtime on db_stat.snapshot_pg_statio_all_indexes(relname varchar_pattern_ops,indexrelname varchar_pattern_ops,snap_create_time);
create index idx_statio_indexe_snapid on db_stat.snapshot_pg_statio_all_indexes(snapid);
create table db_stat.snapshot_pg_statio_all_tables
(relid int,schemaname varchar(200),relname varchar(550),heap_blks_read bigint,heap_blks_hit bigint,idx_blks_read bigint,idx_blks_hit bigint,toast_blks_read bigint,toast_blks_hit bigint,
tidx_blks_read bigint,tidx_blks_hit bigint,
snapid int,snap_create_time timestamp,host_ip cidr,host_port int,host_type varchar(20),comment varchar(500));
create index idx_statio_table_relname_createtime on db_stat.snapshot_pg_statio_all_tables(relname varchar_pattern_ops,snap_create_time);
create index idx_statio_table_snapid on db_stat.snapshot_pg_statio_all_tables(snapid);


--创建快照的序列
create sequence db_stat.seq_snapshot minvalue 1 maxvalue 99999999999999;

--每收集完信息之后,对时间,主机列等进行填充
create or replace function db_stat.process_snapshot_table(in i_host_ip cidr,in i_host_port int,in i_host_type varchar,in i_comment varchar default '') returns int as $$
declare
v_snapid int;
_detail text;
_hint text;
_message text;
begin
select nextval('db_stat.seq_snapshot') into v_snapid;
update db_stat.snapshot_pg_stat_all_indexes set snapid=v_snapid,snap_create_time=now(),host_ip=i_host_ip,host_port=i_host_port,host_type=i_host_type,comment=i_comment where snapid is null;
update db_stat.snapshot_pg_stat_all_tables set snapid=v_snapid,snap_create_time=now(),host_ip=i_host_ip,host_port=i_host_port,host_type=i_host_type,comment=i_comment where snapid is null;
update db_stat.snapshot_pg_statio_all_indexes set snapid=v_snapid,snap_create_time=now(),host_ip=i_host_ip,host_port=i_host_port,host_type=i_host_type,comment=i_comment where snapid is null;
update db_stat.snapshot_pg_statio_all_tables set snapid=v_snapid,snap_create_time=now(),host_ip=i_host_ip,host_port=i_host_port,host_type=i_host_type,comment=i_comment where snapid is null;
-- 返回值 1 代表成功,0 代表失败
return 1;
EXCEPTION WHEN others then
GET STACKED DIAGNOSTICS
_message = message_text,
_detail = pg_exception_detail,
_hint = pg_exception_hint;
raise notice 'message: %, detail: %, hint: %', _message, _detail, _hint;
return 0;
end;
$$ language plpgsql;


--收动进行信息采集,测试用
INSERT INTO db_stat.snapshot_pg_stat_all_indexes(relid ,indexrelid ,schemaname ,relname ,indexrelname,idx_scan ,idx_tup_read,idx_tup_fetch)
SELECT relid ,
indexrelid ,
schemaname ,
relname ,
indexrelname,
idx_scan ,
idx_tup_read,
idx_tup_fetch
FROM pg_stat_all_indexes;

INSERT INTO db_stat.snapshot_pg_stat_all_tables(relid ,schemaname ,relname ,seq_scan ,seq_tup_read ,idx_scan ,idx_tup_fetch ,n_tup_ins ,n_tup_upd ,n_tup_del ,n_tup_hot_upd ,n_live_tup ,n_dead_tup ,last_vacuum ,last_autovacuum ,last_analyze ,last_autoanalyze ,vacuum_count ,autovacuum_count ,analyze_count ,autoanalyze_count)
SELECT relid ,
schemaname ,
relname ,
seq_scan ,
seq_tup_read ,
idx_scan ,
idx_tup_fetch ,
n_tup_ins ,
n_tup_upd ,
n_tup_del ,
n_tup_hot_upd ,
n_live_tup ,
n_dead_tup ,
last_vacuum ,
last_autovacuum ,
last_analyze ,
last_autoanalyze ,
vacuum_count ,
autovacuum_count ,
analyze_count ,
autoanalyze_count
FROM pg_stat_all_tables;


INSERT INTO db_stat.snapshot_pg_statio_all_indexes(relid ,indexrelid ,schemaname ,relname ,indexrelname ,idx_blks_read ,idx_blks_hit)
SELECT relid ,
indexrelid ,
schemaname ,
relname ,
indexrelname ,
idx_blks_read ,
idx_blks_hit
FROM pg_statio_all_indexes;


INSERT INTO db_stat.snapshot_pg_statio_all_tables(relid ,schemaname ,relname ,heap_blks_read ,heap_blks_hit ,idx_blks_read ,idx_blks_hit ,toast_blks_read ,toast_blks_hit ,tidx_blks_read ,tidx_blks_hit)
SELECT relid ,
schemaname ,
relname ,
heap_blks_read ,
heap_blks_hit ,
idx_blks_read ,
idx_blks_hit ,
toast_blks_read ,
toast_blks_hit ,
tidx_blks_read ,
tidx_blks_hit
FROM pg_statio_all_tables;

--
select db_stat.process_snapshot_table('192.168.174.10',5432,'MASTER','');

--创建一个shell脚本,每天通过定时任务进行信息采集
cat snap_stat.sh

#!/bin/sh
source ~/.bash_profile
source /etc/profile
PSQL="psql"


help_msg (){
echo ""
echo "Usage:"
echo " -f 要输出结果的文件,如果为null,则默认为/tmp/snapshot_pg_stat.log"
echo " -u 数据库连接用户名,如果为null,则为postgresql默认"
echo " -d 连接的数据库名,如果为null,则为postgresql默认"
echo " -H 数据库的主机ip,如果为null,则为postgresql默认"
echo " -p 数据库的端口,如果为null,则为postgresql默认"
echo " -m 数据库的类型,MASTER为主,SLAVE为从"
echo ""
exit 0
}

# end functions

while getopts "f:u:d:H:p:m:" flag
do
case $flag in
f) FILENAME=$OPTARG
;;
u) USERNAME=$OPTARG
;;
d) DATABASE=$OPTARG
;;
H) HOST=$OPTARG
;;
p) PORT=$OPTARG
;;
m) DATABASE_TYPE=$OPTARG
;;
\?|h) help_msg
;;
esac
done


if [ $USERNAME"x" == "x" ]
then
USERNAME=postgres
fi

if [ $DATABASE"x" == "x" ]
then
DATABASE=postgres
fi

if [ $HOST"x" == "x" ]
then
help_msg
fi

if [ $PORT"x" == "x" ]
then
PORT=5432
fi

if [ $DATABASE_TYPE"x" == "x" ]
then
DATABASE_TYPE=MASTER
fi

if [ $FILENAME"x" == "x" ]
then
FILENAME=/tmp/snapshot_pg_stat.log
fi

OUTPUT_FILENAME=/tmp/snapshot_pg_stat.csv

echo "" > $FILENAME


if [ ! -f $FILENAME ]
then
touch $FILENAME
else
printf "" | tee -a $FILENAME
fi


echo "脚本于时间 `date "+%Y-%m-%d %H:%M:%S"` 开始执行" >> $FILENAME

echo "脚本开始于`date "+%Y-%m-%d %H:%M:%S"` 处理pg_stat_all_indexes表" >> $FILENAME
$PSQL -p $PORT -U $USERNAME -d $DATABASE -c "copy (select relid ,indexrelid ,schemaname ,relname ,indexrelname,idx_scan ,idx_tup_read,idx_tup_fetch from pg_stat_all_indexes) to '$OUTPUT_FILENAME' with csv"
$PSQL -p 5432 -U postgres -d postgres -h 192.168.174.11 -c "\copy db_stat.snapshot_pg_stat_all_indexes(relid ,indexrelid ,schemaname ,relname ,indexrelname,idx_scan ,idx_tup_read,idx_tup_fetch) from '$OUTPUT_FILENAME' with csv"
echo "脚本开始于`date "+%Y-%m-%d %H:%M:%S"` 处理pg_stat_all_tables表" >> $FILENAME
$PSQL -p $PORT -U $USERNAME -d $DATABASE -c "copy (select relid ,schemaname ,relname ,seq_scan ,seq_tup_read ,idx_scan ,idx_tup_fetch ,n_tup_ins ,n_tup_upd ,n_tup_del ,n_tup_hot_upd ,n_live_tup ,n_dead_tup ,last_vacuum ,last_autovacuum ,last_analyze ,last_autoanalyze ,vacuum_count ,autovacuum_count ,analyze_count ,autoanalyze_count from pg_stat_all_tables) to '$OUTPUT_FILENAME' with csv"
$PSQL -p 5432 -U postgres -d postgres -h 192.168.174.11 -c "\copy db_stat.snapshot_pg_stat_all_tables(relid ,schemaname ,relname ,seq_scan ,seq_tup_read ,idx_scan ,idx_tup_fetch ,n_tup_ins ,n_tup_upd ,n_tup_del ,n_tup_hot_upd ,n_live_tup ,n_dead_tup ,last_vacuum ,last_autovacuum ,last_analyze ,last_autoanalyze ,vacuum_count ,autovacuum_count ,analyze_count ,autoanalyze_count) from '$OUTPUT_FILENAME' with csv"
echo "脚本开始于`date "+%Y-%m-%d %H:%M:%S"` 处理pg_statio_all_indexes表" >> $FILENAME
$PSQL -p $PORT -U $USERNAME -d $DATABASE -c "copy (select relid ,indexrelid ,schemaname ,relname ,indexrelname ,idx_blks_read ,idx_blks_hit from pg_statio_all_indexes) to '$OUTPUT_FILENAME' with csv"
$PSQL -p 5432 -U postgres -d postgres -h 192.168.174.11 -c "\copy db_stat.snapshot_pg_statio_all_indexes(relid ,indexrelid ,schemaname ,relname ,indexrelname ,idx_blks_read ,idx_blks_hit) from '$OUTPUT_FILENAME' with csv"
echo "脚本开始于`date "+%Y-%m-%d %H:%M:%S"` 处理pg_statio_all_tables表" >> $FILENAME
$PSQL -p $PORT -U $USERNAME -d $DATABASE -c "copy (select relid ,schemaname ,relname ,heap_blks_read ,heap_blks_hit ,idx_blks_read ,idx_blks_hit ,toast_blks_read ,toast_blks_hit ,tidx_blks_read ,tidx_blks_hit from pg_statio_all_tables) to '$OUTPUT_FILENAME' with csv"
$PSQL -p 5432 -U postgres -d postgres -h 192.168.174.11 -c "\copy db_stat.snapshot_pg_statio_all_tables(relid ,schemaname ,relname ,heap_blks_read ,heap_blks_hit ,idx_blks_read ,idx_blks_hit ,toast_blks_read ,toast_blks_hit ,tidx_blks_read ,tidx_blks_hit) from '$OUTPUT_FILENAME' with csv"

$PSQL -p 5432 -U postgres -d postgres -h 192.168.174.11 -c "select db_stat.process_snapshot_table('$HOST',$PORT,'$DATABASE_TYPE','database stat snapshot');"

echo "############################################################################################" >> $FILENAME
echo "脚本于时间 `date "+%Y-%m-%d %H:%M:%S"` 结束执行" >> $FILENAME




--清空数据表
truncate table db_stat.snapshot_pg_stat_all_indexes ;
truncate table db_stat.snapshot_pg_stat_all_tables ;
truncate table db_stat.snapshot_pg_statio_all_indexes ;
truncate table db_stat.snapshot_pg_statio_all_tables ;

--手动执行shell脚本
./snap_stat.sh -d mydb -p 5432 -m SLAVE -u postgres -H 192.168.174.10
--定时任务,每天8点开始执行
8 8 * * * /db/pgsql/snap_stat.sh -d mydb -p 5435 -m SLAVE -u postgres -H 192.168.174.10



--查看使用比较少的索引
select *
from (
SELECT t.relname,
t.indexrelname ,
max(idx_scan)-min(idx_scan) AS diff_idx_scan,
max(idx_tup_read)-min(idx_tup_read) AS diff_idx_tup_read
FROM db_stat.snapshot_pg_stat_all_indexes t
--WHERE snap_create_time BETWEEN '2015-12-11' AND '2016-03-11'
GROUP BY t.relname, t.indexrelname) t1
order by diff_idx_scan,relname,indexrelname ;

--查看索引使用率趋势图
select relname,
indexrelname,
snap_day,
diff_idx_scan,
case when sum(diff_idx_scan) over w1 >0 then diff_idx_scan*100/sum(diff_idx_scan) over w1 else 0 end as diff_idx_scan_percent,
diff_idx_tup_read,
case when sum(diff_idx_tup_read) over w1 >0 then diff_idx_tup_read*100/sum(diff_idx_tup_read) over w1 else 0 end as diff_idx_tup_read_percent
from (
SELECT t.relname,
t.indexrelname,
date_trunc('hour', snap_create_time) snap_day,
t.idx_scan-lag(t.idx_scan,1) over w AS diff_idx_scan,
t.idx_tup_read - lag(t.idx_tup_read,1) over w AS diff_idx_tup_read
from db_stat.snapshot_pg_stat_all_indexes t
--where indexrelname in ('','')
WINDOW w AS (PARTITION BY t.relname,t.indexrelname ORDER BY date_trunc('hour', t.snap_create_time))
) t1
where diff_idx_scan is not null
WINDOW w1 as (PARTITION BY t1.relname,t1.indexrelname)
order by relname,indexrelname,snap_day;

标签:stat,postgresql,idx,weixin,blks,tup,read,pg,33711641
From: https://www.cnblogs.com/zclzc/p/18368883

相关文章

  • PostgreSQL数据库的安装与部署(Linux)
    CentOS安装PostgreSQL版本信息:   CentOS版本:CentOS-7-x86_64-Minimal-1810   PostgreSQL版本:PostgreSQL10.10,64-bit 第一部分:PostgresSQL的安装1、安装rpm文件yuminstallhttps://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redh......
  • 240815-PostgreSQL自带逻辑复制简单使用
    PostgreSQL自带逻辑复制简单使用一、逻辑复制说明角色IP端口数据库名用户名版本发布端192.168.198.1658432pubdbrepuserPostgreSQL13.13订阅端192.168.198.1628432subdbrepuserPostgreSQL13.13二、搭建逻辑复制环境2.1发布端配置发布端post......
  • 数据库技术核心:查询优化(PostgreSQL)
    文章目录案例1:使用合适的索引优化查询案例2:优化多表复杂联接查询案例3:优化多条件查询案例4:消除低效的联接查询案例5:包含多个联接和聚合的复杂查询案例6:消除低效的子查询案例7:复杂窗口函数和CTE(公用表表达式)案例8:适当的表结构设计与分区表优化案例9:使用物化视图......
  • Win 11 Postgresql 16 安装失败解决方案
    主要遇到以下两个问题一个是在安装时报错Problemrunningpost-installstep.InstallationmaynotcompletecorrectlyThedatabaseclusterinitialisationfailed.一个是在初始化时报错Theprogram"postgres"wasfoundby"initdb"butwasnotthesameversionasin......
  • 【PostgreSQL教程】PostgreSQL 高级篇之约束
    博主介绍:✌全网粉丝20W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。感兴趣的可以先......
  • postgresql常用快捷命令
    查看帮助信息通过此命令查看数据库命令帮助信息,本文中的所有命令都可以在帮助命令列表找到命令格式:?示例:\?查看所有数据库命令格式:\l示例:\l切换数据库命令格式:\c数据库名称示例:\ctest_database执行成功会切换到指定的数据库查看数据库对象的相关信息命......
  • 在Centos系统源码安装postgreSQL数据库及postGIS扩展
    本次安装的各版本如下postgresql-13.5.targeos-3.10.2gdal-3.4.1proj-8.2.1postgis-3.2.1一、安装postgreSQL1.1安装包下载地址选postgresql-13.5.tar.gz。使用工具将下载好的包传到服务器。解压,进入解压目录[root@localhostlocal]#yuminstallgccreadline-develzlib-d......
  • docker 运行 postgresql
    docker运行postgresql服务端及客户端 注意:是postgres不是postgre!!! 1.orb里设置{"registry-mirrors":["https://改成你的.mirror.aliyuncs.com","https://docker.888666222.xyz"],"ipv6":true} 2.访问https://docker.registry.cyo......
  • postgresql清理空闲连接
    问题今天突然无法连接postgresql,出现的异常如下:FATAL:sorry,toomanyclientsalready解决查看当前活跃和空闲连接selectpid,datname,application_name,client_addr,statefrompg_stat_activitywherestatein('idle','active');根据条件清理空闲连接s......
  • 揭开 PostgreSQL 默认权限的神秘面纱
    alterdefaultprivileges命令允许我们设置将应用于将来创建的对象的权限。需要注意的是,这不会影响分配给现有对象的权限;默认权限可以全局设置在当前数据库上,或者指定的schema上。 数据库使用者对默认权限的行为有很多误解,我经常听到一些抱怨,说即使为特定schema分配了默认......