Statistics generated on: '|| now();
select 'on database: '||current_database()||'' as info;
select 'by user: '||user as info;
select 'using: pg2html.sql v.1.0.25-alfa6' as info;
select ' Software by ' as info;
select 'Meo
'
as info;
select '
' as info;
select '
Summary
' as info;
select '
Item', '
Value' as info;
select '
'||' Database :', '',
'
'||current_database()
union
select '
'||' Version :', '',
'
'||substring(version() for position('on' in version())-1)
union
select '
'||' DB Size:', '',
'
'||pg_size_pretty(sum(pg_database_size(datname)))
from pg_database;
select '
'||' Created :',
'', '
'|| (pg_stat_file('base/'||oid ||'/PG_VERSION')).modification
from pg_database
where datname='template0';
select '
'||' Started :',
'', '
'||pg_postmaster_start_time()
union
select '
'||' Memory buffers (MB) :',
'', '
'||trunc(sum(setting::int*8)/1024)
from pg_settings
where name like '%buffers'
union
select '
'||' Work area (MB) :',
'', '
'||trunc(sum(setting::int)/1024)
from pg_settings
where name like '%mem'
union
select '
'||' Wal Archiving :',
'', '
'||setting
from pg_settings
where name like 'archive_mode';
select '
'||' Databases :', '', '
'||count(*)
from pg_database
where not datistemplate
union
select '
'||' Defined Users/Roles :',
'', '
'||sum(case when rolcanlogin then 1 else 0 end)||
' / '|| sum(case when rolcanlogin then 0 else 1 end)
from pg_roles
union
select '
'||' Defined Schemata :',
'', '
'||count(distinct relowner)
from pg_class
union
select '
'||' Defined Tables :',
'', '
'||count(*)
from pg_class
where relkind='r';
select '
'||' Sessions :', '', '
'||count(*)
from pg_stat_activity
union
select '
'||' Sessions (active) :', '', '
'||count(*)
from pg_stat_activity
where state = 'active';
select '
'||' Host IP :',
'', '
'||inet_server_addr()
union
select '
'||' Port :',
'', '
'||inet_server_port()
order by 2;
select '
' as info;
select '
' as info;
select '
Version
' as info;
select '
'||version()||'
';
select '
' as info;
select '
Version check
' ;
select '
Version',
'
Supported',
'
Last major release (N or N-2)',
'
Last minor release (N or N-1)',
'
Notes';
SELECT '
'||substring(version() for position('on' in version())-1);
SELECT '
', CASE WHEN trunc(cast(current_setting('server_version_num')
as integer)/100)
in (1000, 1100, 1200, 1300, 1400, 1500) THEN 'YES'
ELSE 'NO' END;
SELECT '
', CASE WHEN trunc(cast(current_setting('server_version_num')
as integer)/100)
in (1300, 1400, 1500) THEN 'YES'
ELSE 'NO' END; -- last2 release
SELECT '
', CASE WHEN cast(current_setting('server_version_num')as integer)
in (90623,90624, 100023,100022, 110019,110018,110020, 120014,120013,120015,
130010,130009,130011,
140007,140006,140008, 150000,150001,150003) THEN 'YES'
ELSE 'NO' END; -- last2 update
select '
'||pg_size_pretty(sum(pg_database_size(datname))::int8)
from pg_database;
select '
' as info;
select '
' as info;
select '
Tablespaces
' as info;
select '
Name', '
Owner', '
Location' as info;
select '
'||spcname, '
',pg_catalog.pg_get_userbyid(spcowner),
'
',pg_catalog.pg_tablespace_location(oid)
from pg_tablespace
order by oid;
select '
' as info;
select '
' as info;
select '
Schema/Object Matrix
' as info;
select '
Schema
Owner',
'
Table',
'
Index',
'
View',
'
Sequence',
'
Composite type',
'
Foreign table',
'
TOAST table',
'
Materialized view',
'
Partitioned table',
'
Partitioned index',
'
Unlogged',
'
Temporary',
'
TOTAL'
as info;
select '
'||nspname, '
'||rolname,
'
'||sum(case when relkind='r' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='i' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='v' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='S' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='c' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='f' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='t' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='m' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='p' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='I' THEN 1 ELSE 0 end),
'
'||sum(case when relpersistence='u' THEN 1 ELSE 0 end),
'
'||sum(case when relpersistence='t' THEN 1 ELSE 0 end),
'
'||count(*)
from pg_class, pg_roles, pg_namespace
where relowner=pg_roles.oid
and relnamespace=pg_namespace.oid
group by rolname, nspname
order by nspname, rolname;
select '
TOTAL
TOTAL',
'
'||sum(case when relkind='r' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='i' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='v' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='S' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='c' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='f' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='t' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='m' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='p' THEN 1 ELSE 0 end),
'
'||sum(case when relkind='I' THEN 1 ELSE 0 end),
'
'||sum(case when relpersistence='u' THEN 1 ELSE 0 end),
'
'||sum(case when relpersistence='t' THEN 1 ELSE 0 end),
'
'||count(*)
from pg_class;
select '
' as info;
select '
' as info;
select '
Partitions
' as info;
select '
Schema
Owner',
'
Object Type',
'
Partitioned Objects',
'
Partitions';
select '
'||nspname, '
'||rolname, '
'||t.relkind,
'
', count(distinct t.relname),
'
', count(*)
from pg_class t, pg_inherits i, pg_class p, pg_roles r, pg_namespace n
where i.inhparent = t.oid
and p.oid = i.inhrelid
and t.relowner=r.oid
and t.relnamespace=n.oid
group by rolname, nspname, t.relkind
order by t.relkind desc, nspname, rolname;
select '
' as info;
select '
' as info;
select '
Owner/Function Matrix
' as info;
select '
Owner',
'
Functions',
'
Procedures',
'
TOTAL'
as info;
select '
'||rolname,
'
'||sum(case when prokind='p' THEN 0 ELSE 1 end),
'
'||sum(case when prokind='p' THEN 1 ELSE 0 end),
'
'||count(*)
from pg_proc, pg_roles, pg_language
where proowner=pg_roles.oid
and prolang=pg_language.oid
group by rolname
order by rolname;
select '
TOTAL',
'
'||sum(case when prokind='p' THEN 0 ELSE 1 end),
'
'||sum(case when prokind='p' THEN 1 ELSE 0 end),
'
'||count(*)
from pg_proc, pg_language
where prolang=pg_language.oid;
select '
' as info;
select '
' as info;
select '
Space Usage
' as info;
select '
Owner',
'
Table#',
'
Tables rows',
'
Tables KBytes',
'
Indexes KBytes',
'
TOAST KBytes',
'
Total KBytes'
as info;
select '
'||rolname,
'
'||to_char(sum(case when relkind='r' THEN 1 ELSE 0 end),'999G999G999G999G999G999G999'),
'
'||to_char(sum(case when relkind='r' THEN greatest(reltuples,0) ELSE 0 end),'999G999G999G999G999G999G999'),
'
'||to_char(trunc(sum(case when relkind='r' THEN cast(1 as bigint)* relpages *8 ELSE 0 end)),'999G999G999G999G999G999G999'),
'
'||to_char(trunc(sum(case when relkind='i' THEN cast(1 as bigint)* relpages *8 ELSE 0 end)),'999G999G999G999G999G999G999'),
'
'||to_char(trunc(sum(case when relkind='t' THEN cast(1 as bigint)* relpages *8 ELSE 0 end)),'999G999G999G999G999G999G999'),
'
'||to_char(trunc(sum(cast(1 as bigint)* relpages *8)),'999G999G999G999G999G999G999')
from pg_class, pg_roles
where relowner=pg_roles.oid
group by rolname
order by rolname;
select '
TOTAL',
'
'||to_char(sum(case when relkind='r' THEN 1 ELSE 0 end),'999G999G999G999G999G999G999'),
'
'||to_char(sum(case when relkind='r' THEN reltuples ELSE 0 end),'999G999G999G999G999G999G999'),
'
'||to_char(trunc(sum(case when relkind='r' THEN cast(1 as bigint)* relpages *8 ELSE 0 end)),'999G999G999G999G999G999G999'),
'
'||to_char(trunc(sum(case when relkind='i' THEN cast(1 as bigint)* relpages *8 ELSE 0 end)),'999G999G999G999G999G999G999'),
'
'||to_char(trunc(sum(case when relkind='t' THEN cast(1 as bigint)* relpages *8 ELSE 0 end)),'999G999G999G999G999G999G999'),
'
'||to_char(trunc(sum(cast(1 as bigint)* relpages *8)),'999G999G999G999G999G999G999')
from pg_class, pg_roles
where relowner=pg_roles.oid;
select '
'||last_analyze
from pg_stat_all_tables
where n_dead_tup>1000
and n_dead_tup>n_live_tup*0.05
order by n_dead_tup desc
limit 20;
select '
' as info;
select '
Bloated tables (estimated size)
' as info;
select '
Table',
'
Fillfactor',
'
Table Size',
'
HR Size',
'
Bloat',
'
HR Bloat',
'
Bloat%'
as info;
SELECT '
'||schemaname||'.'||tblname, '
'||fillfactor,
'
'||bs*tblpages AS real_size, '
'||pg_size_pretty(bs*tblpages) as HR_size,
'
', CASE WHEN tblpages - est_tblpages_ff > 0
THEN (tblpages-est_tblpages_ff)*bs
ELSE 0
END AS bloat_size,
'
', CASE WHEN tblpages - est_tblpages_ff > 0
THEN pg_size_pretty( ((tblpages-est_tblpages_ff)*bs)::bigint)
ELSE '0'
END AS hr_bloat_size,
'
', CASE WHEN tblpages > 0 AND tblpages - est_tblpages_ff > 0
THEN round(100*(tblpages - est_tblpages_ff)/tblpages::float)
ELSE 0
END, '%'
FROM (
SELECT ceil( reltuples / ( (bs-page_hdr)*fillfactor/(tpl_size*100) ) ) + ceil( toasttuples / 4 ) AS est_tblpages_ff,
tblpages, fillfactor, bs, tblid, schemaname, tblname, heappages, toastpages, is_na
FROM (
SELECT
( 4 + tpl_hdr_size + tpl_data_size + (2*ma)
- CASE WHEN tpl_hdr_size%ma = 0 THEN ma ELSE tpl_hdr_size%ma END
- CASE WHEN ceil(tpl_data_size)::int%ma = 0 THEN ma ELSE ceil(tpl_data_size)::int%ma END
) AS tpl_size, bs - page_hdr AS size_per_block, (heappages + toastpages) AS tblpages, heappages,
toastpages, reltuples, toasttuples, bs, page_hdr, tblid, schemaname, tblname, fillfactor, is_na
FROM (
SELECT
tbl.oid AS tblid, ns.nspname AS schemaname, tbl.relname AS tblname, tbl.reltuples,
tbl.relpages AS heappages, coalesce(toast.relpages, 0) AS toastpages,
coalesce(toast.reltuples, 0) AS toasttuples,
coalesce(substring(
array_to_string(tbl.reloptions, ' ')
FROM 'fillfactor=([0-9]+)')::smallint, 100) AS fillfactor,
current_setting('block_size')::numeric AS bs,
CASE WHEN version()~'mingw32' OR version()~'64-bit|x86_64|ppc64|ia64|amd64' THEN 8 ELSE 4 END AS ma,
24 AS page_hdr,
23 + CASE WHEN MAX(coalesce(s.null_frac,0)) > 0 THEN ( 7 + count(s.attname) ) / 8 ELSE 0::int END
+ CASE WHEN bool_or(att.attname = 'oid' and att.attnum < 0) THEN 4 ELSE 0 END AS tpl_hdr_size,
sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 0) ) AS tpl_data_size,
bool_or(att.atttypid = 'pg_catalog.name'::regtype)
OR sum(CASE WHEN att.attnum > 0 THEN 1 ELSE 0 END) <> count(s.attname) AS is_na
FROM pg_attribute AS att
JOIN pg_class AS tbl ON att.attrelid = tbl.oid
JOIN pg_namespace AS ns ON ns.oid = tbl.relnamespace
LEFT JOIN pg_stats AS s ON s.schemaname=ns.nspname
AND s.tablename = tbl.relname AND s.inherited=false AND s.attname=att.attname
LEFT JOIN pg_class AS toast ON tbl.reltoastrelid = toast.oid
WHERE NOT att.attisdropped
AND tbl.relkind in ('r','m')
GROUP BY 1,2,3,4,5,6,7,8,9,10
ORDER BY 2,3
) AS s
) AS s2
) AS s3
where not is_na
and tblpages-est_tblpages_ff>0
ORDER BY 6 desc limit 20;
select '
Bloated tables (estimated percentage)
' as info;
select '
Table',
'
Fillfactor',
'
Table Size',
'
HR Size',
'
Bloat',
'
HR Bloat',
'
Bloat%'
as info;
SELECT '
'||schemaname||'.'||tblname, '
'||fillfactor,
'
'||bs*tblpages AS real_size, '
'||pg_size_pretty(bs*tblpages) as HR_size,
'
', CASE WHEN tblpages - est_tblpages_ff > 0
THEN (tblpages-est_tblpages_ff)*bs
ELSE 0
END AS bloat_size,
'
', CASE WHEN tblpages - est_tblpages_ff > 0
THEN pg_size_pretty( ((tblpages-est_tblpages_ff)*bs)::bigint)
ELSE '0'
END AS hr_bloat_size,
'
', CASE WHEN tblpages > 0 AND tblpages - est_tblpages_ff > 0
THEN round(100*(tblpages - est_tblpages_ff)/tblpages::float)
ELSE 0
END, '%'
FROM (
SELECT ceil( reltuples / ( (bs-page_hdr)*fillfactor/(tpl_size*100) ) ) + ceil( toasttuples / 4 ) AS est_tblpages_ff,
tblpages, fillfactor, bs, tblid, schemaname, tblname, heappages, toastpages, is_na
FROM (
SELECT
( 4 + tpl_hdr_size + tpl_data_size + (2*ma)
- CASE WHEN tpl_hdr_size%ma = 0 THEN ma ELSE tpl_hdr_size%ma END
- CASE WHEN ceil(tpl_data_size)::int%ma = 0 THEN ma ELSE ceil(tpl_data_size)::int%ma END
) AS tpl_size, bs - page_hdr AS size_per_block, (heappages + toastpages) AS tblpages, heappages,
toastpages, reltuples, toasttuples, bs, page_hdr, tblid, schemaname, tblname, fillfactor, is_na
FROM (
SELECT
tbl.oid AS tblid, ns.nspname AS schemaname, tbl.relname AS tblname, tbl.reltuples,
tbl.relpages AS heappages, coalesce(toast.relpages, 0) AS toastpages,
coalesce(toast.reltuples, 0) AS toasttuples,
coalesce(substring(
array_to_string(tbl.reloptions, ' ')
FROM 'fillfactor=([0-9]+)')::smallint, 100) AS fillfactor,
current_setting('block_size')::numeric AS bs,
CASE WHEN version()~'mingw32' OR version()~'64-bit|x86_64|ppc64|ia64|amd64' THEN 8 ELSE 4 END AS ma,
24 AS page_hdr,
23 + CASE WHEN MAX(coalesce(s.null_frac,0)) > 0 THEN ( 7 + count(s.attname) ) / 8 ELSE 0::int END
+ CASE WHEN bool_or(att.attname = 'oid' and att.attnum < 0) THEN 4 ELSE 0 END AS tpl_hdr_size,
sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 0) ) AS tpl_data_size,
bool_or(att.atttypid = 'pg_catalog.name'::regtype)
OR sum(CASE WHEN att.attnum > 0 THEN 1 ELSE 0 END) <> count(s.attname) AS is_na
FROM pg_attribute AS att
JOIN pg_class AS tbl ON att.attrelid = tbl.oid
JOIN pg_namespace AS ns ON ns.oid = tbl.relnamespace
LEFT JOIN pg_stats AS s ON s.schemaname=ns.nspname
AND s.tablename = tbl.relname AND s.inherited=false AND s.attname=att.attname
LEFT JOIN pg_class AS toast ON tbl.reltoastrelid = toast.oid
WHERE NOT att.attisdropped
AND tbl.relkind in ('r','m')
GROUP BY 1,2,3,4,5,6,7,8,9,10
ORDER BY 2,3
) AS s
) AS s2
) AS s3
where not is_na
and tblpages-est_tblpages_ff>0
and tblpages>2
ORDER BY 10 desc limit 5;
select '
' as info;
select '
Database max age
' as info;
select '
Database',
'
Max XID age',
'
% Wraparound'
as info;
SELECT '
'||datname||'
', age(datfrozenxid), '
',
(age(datfrozenxid)::numeric/2000000000*100)::numeric(4,2) as "% Wraparound"
FROM pg_database
ORDER BY 2 DESC;
select '
' as info;
select '
Relations too aged
' as info;
select '
Schema', '
Relation',
'
XID age'
as info;
SELECT '
'|| nspname ||'
'|| relname ||'
', age(relfrozenxid)
FROM pg_class
JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
WHERE relkind = 'r'
AND age(relfrozenxid)> 2^28
ORDER by 2 DESC;
select '
' as info;
select '
' as info;
select '
Users/Roles
' as info;
select '
Role',
'
Login',
'
Inherit',
'
Superuser',
'
Expiry time',
'
Config'
as info;
select '
'||rolname,
'
'||rolcanlogin,
'
'||rolinherit,
'
'||rolsuper,
'
',rolvaliduntil,
'
'||rolconfig::text
from pg_roles
order by rolcanlogin desc, rolname;
select '
TOTAL Users',
'
'||count(*)
from pg_roles where rolcanlogin;
select '
TOTAL Roles',
'
'||count(*)
from pg_roles where not rolcanlogin;
select '
Same as user'
from pg_shadow
where substr(passwd,4) = md5(usename||usename)
order by usename;
select '
',usename, '
', passwd, '
Empty password'
from pg_shadow
where passwd is null
order by usename;
select '
',usename, '
', passwd, '
Unencrypted password'
from pg_shadow
where passwd not like 'md5%' and passwd not like 'SCRAM%'
order by usename;
select '
';
select '
';
select '
HBA Rules
' as info;
select '
Type','
Database',
'
User', '
Address', '
Netmask',
'
Auth', '
Options', '
Error';
select '
',type,
'
',database, '
',user_name, '
',address, '
',netmask,
'
',auth_method, '
',options, '
',error
from pg_hba_file_rules
order by line_number;
select '
';
select '
';
select '
PGAudit logged Objects
' as info;
select '
Schema', '
Table', '
Privilege';
SELECT '
',table_schema, '
',table_name, '
',privilege_type
FROM information_schema.role_table_grants
WHERE grantee in ('rds_pgaudit', 'auditor', 'pgaudit')
ORDER BY table_schema, table_name;
select '
';
select '
' as info;
select '
';
select '
Per-User Sessions
'
as info;
select '
User', '
Database',
'
Count', '
Active' ;
select '
',usename,
'
',datname,
'
', count(*),
'
', sum(case when state='active' then 1 else 0 end)
from pg_stat_activity
group by usename, datname
order by 6 desc, 1;
select '
TOTAL (', count(distinct usename),
' distinct users)
'|| count(*)
from pg_stat_activity;
select '
' as info;
select '
Per-Host Sessions
'
as info;
select '
User', '
Database',
'
Count', '
Active' ;
select '
', client_addr,
'
',datname,
'
', count(*),
'
', sum(case when state='active' then 1 else 0 end)
from pg_stat_activity
group by client_addr, datname
order by 6 desc, 1
limit 20;
select '
TOTAL (', count(distinct client_addr),
' distinct clients)
'|| count(*)
from pg_stat_activity;
select '
' as info;
select '
Sessions
'
as info;
select '
Pid',
'
Database',
'
User',
'
Address',
'
State',
'
Query start',
'
Backend',
'
SQL' ;
select '
',pid,
'
',datname,
'
',usename,
'
',client_addr,
'
',state,
'
',query_start,
'
',backend_type,
'
',query
from pg_stat_activity
where pid<>pg_backend_pid()
order by state, pid;
select '
' as info;
select '
' as info;
select '
Locks
'
as info;
select '
Pid',
'
Type',
'
Database',
'
Relation',
'
Mode',
'
Granted'
as info;
select '
',pid,
'
',locktype,
'
', datname,
'
', relname,
'
',mode,
'
',granted
from pg_locks l
left join pg_catalog.pg_database d on d.oid = l.database
left join pg_catalog.pg_class r on r.oid = l.relation
order by granted, pid
limit 50;
select '
...';
select '
' as info;
select '
' as info;
select '
Blocking Locks
'
as info;
select '
Blocked Pid',
'
Blocked User',
'
Blocking Pid',
'
Blocking User',
'
Blocked Statement',
'
Blocking Statement'
as info;
SELECT '
',blocked_locks.pid AS blocked_pid,
'
',blocked_activity.usename AS blocked_user,
'
',blocking_locks.pid AS blocking_pid,
'
',blocking_activity.usename AS blocking_user,
'
',blocked_activity.query AS blocked_statement,
'
',blocking_activity.query AS current_statement_in_blocking_process
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks ON blocking_locks.locktype = blocked_locks.locktype
AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.GRANTED;
select '
' as info;
select '
' as info;
select '
Memory
' as info;
select '
Element',
'
KB',
'
Description'
as info;
select '
'||name,
'
'||setting::int*8,
'
'||short_desc
from pg_settings
where name like '%buffers';
select '
'||name,
'
'||setting::int,
'
'||short_desc
from pg_settings
where name like '%mem';
select '
' as info;
select '
Buffer Cache Contents
' as info;
select '
Class','
Kind',
'
Buffers',
'
Buffered',
'
Buffers%',
'
Relation%',
'
Avg. usage'
as info;
SELECT '
', c.relname, '
', c.relkind, '
', count(*),
'
', pg_size_pretty(count(*) * 8192),
'
', round(100.0 * count(*)/(SELECT setting FROM pg_settings WHERE name='shared_buffers')::integer,1),
'
', round(avg(usagecount),2)
FROM pg_class c
INNER JOIN pg_buffercache b ON b.relfilenode = c.relfilenode
INNER JOIN pg_database d ON (b.reldatabase = d.oid AND d.datname = current_database())
WHERE pg_relation_size(c.oid) > 0
GROUP BY c.oid, c.relname, c.relkind
ORDER BY 6 DESC
LIMIT 20;
select '
' as info;
SELECT 'Buffer Cache size: ', pg_size_pretty(setting::bigint*8192::bigint)
FROM pg_settings
WHERE name='shared_buffers';
SELECT ' Estimated Minimal Buffer Cache size: ', pg_size_pretty(count(*) * 8192)
FROM pg_buffercache
WHERE usagecount >= 3;
select '
' as info;
select '
' as info;
select '
Database Statistics' as info;
select '
Database',
'
Backends',
'
Commit',
'
TPS',
'
Rollback',
'
Read',
'
Hit',
'
Hit Ratio%',
'
Return',
'
Fetch',
'
Insert',
'
Update',
'
Delete'
as info;
select '
'||datname,
'
'||numbackends,
'
'||xact_commit,
'
'||round(xact_commit/EXTRACT( EPOCH FROM (now()-stats_reset))::decimal,2),
'
'||tup_deleted
from pg_stat_database
where datname not like 'template%';
select '
' as info;
select '
BG Writer statistics' as info;
select '
checkpoints_timed',
'
checkpoints_req ',
'
buffers_checkpoint ',
'
buffers_clean ',
'
maxwritten_clean ',
'
buffers_backend ',
'
buffers_alloc ',
'
Minutes between checkpoints ';
select '
'||checkpoints_timed,
'
'|| checkpoints_req,
'
'|| buffers_checkpoint,
'
'|| buffers_clean,
'
'|| maxwritten_clean,
'
'|| buffers_backend,
'
'|| buffers_alloc
from pg_stat_bgwriter;
select '
'|| seconds_since_start / total_checkpoints / 60 AS mbc
from (SELECT EXTRACT(EPOCH FROM (now() - pg_postmaster_start_time())) AS seconds_since_start,
(checkpoints_timed+checkpoints_req) AS total_checkpoints
FROM pg_stat_bgwriter
) AS sub;
select '
' as info;
select '
Cache statistics' as info;
select '
Object Type
#Read',
'
#Hit ',
'
Hit Ratio% ';
SELECT '
Table',
'
'||sum(heap_blks_read) as heap_read,
'
'||sum(heap_blks_hit) as heap_hit,
'
'||trunc(100*sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)),2) as ratio
FROM
pg_statio_user_tables;
SELECT '
Index',
'
'||sum(idx_blks_read) as idx_read,
'
'||sum(idx_blks_hit) as idx_hit,
'
'||trunc(100*(sum(idx_blks_hit) - sum(idx_blks_read)) / nullif(sum(idx_blks_hit),0),2) as ratio
FROM
pg_statio_user_indexes;
select '
' as info;
SELECT cast(current_setting('server_version_num')as integer)>= 110000 as version_11p
\gset var_
SELECT cast(current_setting('server_version_num')as integer)>= 120000 as version_12p
\gset var_
SELECT cast(current_setting('server_version_num')as integer)>= 130000 as version_13p
\gset var_
SELECT cast(current_setting('server_version_num')as integer)>= 140000 as version_14p
\gset var_
SELECT cast(current_setting('server_version_num')as integer)>= 150000 as version_15p
\gset var_
SELECT cast(current_setting('server_version_num')as integer)>= 160000 as version_16p
\gset var_
select '
' as info;
select '
Statement statistics' as info;
select '
Query',
'
User',
'
Calls',
'
Average (sec.)',
'
Max (sec.)',
'
Total Time',
'
I/O Time',
'
Rows',
'
Hit Ratio%'
as info;
\if :var_version_13p
SELECT '
'||round((wal_bytes::numeric::numeric)/(1024*1024),0)
FROM pg_stat_statements
WHERE pg_get_userbyid(userid) not in ('enterprisedb') -- Comment if needed
ORDER BY (total_exec_time::numeric/calls::numeric) DESC
LIMIT 10;
\else
SELECT '
'||round((100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0)),2) AS hit_percent
FROM pg_stat_statements
WHERE pg_get_userbyid(userid) not in ('enterprisedb') -- Comment if needed
ORDER BY (total_time::numeric/calls::numeric) DESC
LIMIT 10;
\endif
select '
' as info;
select '
' as info;
select '
Database',
'
DBcpu',
'
IOcpu'
as info;
\if :var_version_13p
\if :var_version_14p
select '
', datname,
'
', round(sum( (total_exec_time)/(EXTRACT(EPOCH FROM (now()-stats_reset))*1000) )::numeric,5) DBcpu,
'
', round(sum( (blk_read_time+blk_write_time)/(EXTRACT(EPOCH FROM (now()-stats_reset))*1000) )::numeric,5) IOcpu
from pg_stat_statements, pg_database, pg_stat_statements_info
where pg_stat_statements.dbid=pg_database.oid
group by datname;
select '
TOTAL
', round(sum( (total_exec_time)/(EXTRACT(EPOCH FROM (now()-stats_reset))*1000) )::numeric,5) DBcpu,
'
', round(sum( (blk_read_time+blk_write_time)/(EXTRACT(EPOCH FROM (now()-stats_reset))*1000) )::numeric,5) IOcpu
from pg_stat_statements, pg_stat_statements_info;
\else
select '
', datname,
'
', round(sum( (total_exec_time)/(EXTRACT(EPOCH FROM (now()-pg_postmaster_start_time()))*1000) )::numeric,5) DBcpu,
'
', round(sum( (blk_read_time+blk_write_time)/(EXTRACT(EPOCH FROM (now()-pg_postmaster_start_time()))*1000) )::numeric,5) IOcpu
from pg_stat_statements, pg_database
where pg_stat_statements.dbid=pg_database.oid
group by datname;
select '
TOTAL
', round(sum( (total_exec_time)/(EXTRACT(EPOCH FROM (now()-pg_postmaster_start_time()))*1000) )::numeric,5) DBcpu,
'
', round(sum( (blk_read_time+blk_write_time)/(EXTRACT(EPOCH FROM (now()-pg_postmaster_start_time()))*1000) )::numeric,5) IOcpu
from pg_stat_statements;
\endif
\else
select '
', datname,
'
', round(sum( (total_time)/(EXTRACT(EPOCH FROM (now()-pg_postmaster_start_time()))*1000) )::numeric,5) DBcpu,
'
', round(sum( (blk_read_time+blk_write_time)/(EXTRACT(EPOCH FROM (now()-pg_postmaster_start_time()))*1000) )::numeric,5) IOcpu
from pg_stat_statements, pg_database
where pg_stat_statements.dbid=pg_database.oid
group by datname;
select '
TOTAL
', round(sum( (total_time)/(EXTRACT(EPOCH FROM (now()-pg_postmaster_start_time()))*1000) )::numeric,5) DBcpu,
'
', round(sum( (blk_read_time+blk_write_time)/(EXTRACT(EPOCH FROM (now()-pg_postmaster_start_time()))*1000) )::numeric,5) IOcpu
from pg_stat_statements;
\endif
select '
' as info;
select '
Tables statistics' as info;
select '
Schema
Table',
'
Seq. Readed Tuples',
'
Idx. Readed Tuples',
'
Sequential Scan',
'
Index Scan',
'
Insert',
'
Update',
'
Hot Update',
'
Delete',
'
Index Usage Ratio%',
'
HOT Update Ratio%';
select '
'||schemaname,
'
'||relname,
'
'||coalesce(seq_tup_read, 0),
'
'||coalesce(idx_tup_fetch, 0),
'
'||coalesce(seq_scan, 0),
'
'||coalesce(idx_scan, 0),
'
'||coalesce(n_tup_ins, 0),
'
'||coalesce(n_tup_upd, 0),
'
'||coalesce(n_tup_hot_upd, 0),
'
'||coalesce(n_tup_del, 0),
'
'||coalesce(idx_scan*100/nullif(idx_scan+seq_scan,0), -1) as idx_hit_ratio,
'
'||coalesce(n_tup_hot_upd*100/nullif(n_tup_upd,0), -1) as hot_hit_ratio
from pg_stat_user_tables
order by (coalesce(seq_tup_read,0) +coalesce(idx_tup_fetch,0) +coalesce(n_tup_ins,0) +
coalesce(n_tup_upd,0) +coalesce(n_tup_del,0)) desc
limit 20;
select '
' as info;
select '
Tables caching' as info;
select '
Schema
Table',
'
Heap Reads',
'
Index Reads',
'
TOAST Reads',
'
Heap Hit Ratio%',
'
Index Hit Ratio%',
'
TOAST Hit Ratio%';
select '
'||schemaname,
'
'||relname,
'
'||coalesce(heap_blks_read, 0),
'
'||coalesce(idx_blks_read, 0),
'
'||coalesce(toast_blks_read, 0),
'
'||coalesce(heap_blks_hit*100/nullif(heap_blks_read+heap_blks_hit,0), -1) as tb_hit_ratio,
'
'||coalesce(idx_blks_hit*100/nullif(idx_blks_read+idx_blks_hit,0), -1) as idx_hit_ratio,
'
'||coalesce(toast_blks_hit*100/nullif(toast_blks_read+toast_blks_hit,0), -1) as toast_hit_ratio
from pg_statio_user_tables
where heap_blks_read>0
order by heap_blks_read desc
limit 20;
select '
' as info;
select '
' as info;
select '
Partitioning Details
' as info;
select '
Schema
Owner',
'
Partitioned Object',
'
Partition',
'
Expression',
'
Tuples';
select '
'||nspname, '
'||rolname,
'
', t.relname,
'
', p.relname,
'
', pg_get_expr(p.relpartbound, p.oid, true),
'
', p.reltuples, ' / ', t.reltuples
from pg_class t, pg_inherits i, pg_class p, pg_roles r, pg_namespace n
where i.inhparent = t.oid
and p.oid = i.inhrelid
and t.relowner=r.oid
and t.relnamespace=n.oid
and p.relkind='r';
select '
', seq_tup_read
FROM pg_stat_user_tables
WHERE seq_scan + idx_scan > 1
AND 100 * idx_scan / (seq_scan + idx_scan) < 95
ORDER BY n_live_tup DESC
LIMIT 32;
select '
' as info;
select '
Invalid indexes' as info;
select '
Schema', '
Index';
SELECT '
'|| nspname ||'
'|| relname
FROM pg_class, pg_index, pg_namespace
WHERE pg_index.indisvalid = false
AND pg_class.relnamespace = pg_namespace.oid
AND pg_index.indexrelid = pg_class.oid;
select '
' as info;
select '
Missing indexes' as info;
select '
Schema
Relation', '
Contraint
Issue',
'
#Table Scan
Parent', '
Columns';
WITH fk_actions ( code, action ) AS (
VALUES ( 'a', 'error' ),
( 'r', 'restrict' ),
( 'c', 'cascade' ),
( 'n', 'set null' ),
( 'd', 'set default' )
),
fk_list AS (
SELECT pg_constraint.oid as fkoid, conrelid, confrelid as parentid,
conname, relname, nspname,
fk_actions_update.action as update_action,
fk_actions_delete.action as delete_action,
conkey as key_cols
FROM pg_constraint
JOIN pg_class ON conrelid = pg_class.oid
JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
JOIN fk_actions AS fk_actions_update ON confupdtype = fk_actions_update.code
JOIN fk_actions AS fk_actions_delete ON confdeltype = fk_actions_delete.code
WHERE contype = 'f'
),
fk_attributes AS (
SELECT fkoid, conrelid, attname, attnum
FROM fk_list
JOIN pg_attribute
ON conrelid = attrelid
AND attnum = ANY( key_cols )
ORDER BY fkoid, attnum
),
fk_cols_list AS (
SELECT fkoid, array_agg(attname) as cols_list
FROM fk_attributes
GROUP BY fkoid
),
index_list AS (
SELECT indexrelid as indexid,
pg_class.relname as indexname,
indrelid,
indkey,
indpred is not null as has_predicate,
pg_get_indexdef(indexrelid) as indexdef
FROM pg_index
JOIN pg_class ON indexrelid = pg_class.oid
WHERE indisvalid
),
fk_index_match AS (
SELECT fk_list.*,
indexid,
indexname,
indkey::int[] as indexatts,
has_predicate,
indexdef,
array_length(key_cols, 1) as fk_colcount,
array_length(indkey,1) as index_colcount,
round(pg_relation_size(conrelid)/(1024^2)::numeric) as table_mb,
cols_list
FROM fk_list
JOIN fk_cols_list USING (fkoid)
LEFT OUTER JOIN index_list
ON conrelid = indrelid
AND (indkey::int2[])[0:(array_length(key_cols,1) -1)] @> key_cols
),
fk_perfect_match AS (
SELECT fkoid
FROM fk_index_match
WHERE (index_colcount - 1) <= fk_colcount
AND NOT has_predicate
AND indexdef LIKE '%USING btree%'
),
fk_index_check AS (
SELECT 'no index' as issue, *, 1 as issue_sort
FROM fk_index_match
WHERE indexid IS NULL
UNION ALL
SELECT 'questionable index' as issue, *, 2
FROM fk_index_match
WHERE indexid IS NOT NULL
AND fkoid NOT IN (
SELECT fkoid
FROM fk_perfect_match)
),
parent_table_stats AS (
SELECT fkoid, tabstats.relname as parent_name,
(n_tup_ins + n_tup_upd + n_tup_del + n_tup_hot_upd) as parent_writes,
round(pg_relation_size(parentid)/(1024^2)::numeric) as parent_mb
FROM pg_stat_user_tables AS tabstats
JOIN fk_list
ON relid = parentid
),
fk_table_stats AS (
SELECT fkoid,
(n_tup_ins + n_tup_upd + n_tup_del + n_tup_hot_upd) as writes,
seq_scan as table_scans
FROM pg_stat_user_tables AS tabstats
JOIN fk_list
ON relid = conrelid
)
SELECT '
', nspname as schema_name,
'
', relname as table_name,
'
', conname as fk_name,
'
', issue,
'
', table_scans,
'
', parent_name,
'
', cols_list
FROM fk_index_check
JOIN parent_table_stats USING (fkoid)
JOIN fk_table_stats USING (fkoid)
WHERE table_mb > 5
AND ( writes > 1000
OR parent_writes > 1000
OR parent_mb > 10 )
ORDER BY table_scans DESC, table_mb DESC, table_name, fk_name
LIMIT 64;
select '
' as info;
select '
Unused indexes' as info;
select '
Schema
Table', '
Index', '
Size';
SELECT '
',s.schemaname, '
',s.relname,
'
',s.indexrelname, '
',pg_relation_size(s.indexrelid)
FROM pg_catalog.pg_stat_user_indexes s
JOIN pg_catalog.pg_index i ON s.indexrelid = i.indexrelid
WHERE s.idx_scan = 0
AND 0 <>ALL (i.indkey)
AND NOT i.indisunique
AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_constraint c
WHERE c.conindid = s.indexrelid)
ORDER BY pg_relation_size(s.indexrelid) DESC
LIMIT 64;
select '
' as info;
select '
All indexes DDLs (up to 1000)' as info;
select '
Schema
Relation',
'
Index
DDL';
SELECT '
',schemaname, '
',tablename,
'
',indexname, '
',indexdef
FROM pg_indexes
WHERE schemaname not in ('pg_catalog')
AND tablename not like 'pgstatspack%'
ORDER BY schemaname, tablename, indexname
LIMIT 1000;
select '
' as info;
select '
Tuning Parameters
'
as info;
select '
Parameter',
'
Value',
'
Min',
'
Max',
'
Unit',
'
Description'
as info;
select '
',name,'
',replace(replace(setting,'<','<'),'>','>'),
'
',min_val,'
',max_val,
'
',unit, '
',short_desc
from pg_settings
where name in ('max_connections','shared_buffers','effective_cache_size','work_mem', 'wal_buffers',
'checkpoint_completion_target', 'checkpoint_segments', 'synchronous_commit', 'wal_writer_delay',
'max_fsm_pages','fsync','commit_delay','commit_siblings','random_page_cost',
'checkpoint_timeout', 'max_wal_size',
'bgwriter_lru_maxpages', 'bgwriter_lru_multiplier', ' bgwriter_delay',
'autovacuum_vacuum_cost_limit', 'autovacuum_vacuum_cost_delay')
order by name;
select '
' as info;
select '
' as info;
select '
Biggest Objects
'
as info;
select '
Object',
'
Type',
'
Owner', '
Schema',
'
Bytes',
'
Rows'
as info;
select '
'||relname,
'
'||case WHEN relkind='r' THEN 'Table'
WHEN relkind='i' THEN 'Index'
WHEN relkind='t' THEN 'TOAST Table'
ELSE relkind||'' end,
'
'||to_char(reltuples,'999G999G999G999G999G999G999')
from pg_class, pg_roles, pg_catalog.pg_namespace n
where relowner=pg_roles.oid
and n.oid=pg_class.relnamespace
order by relpages desc, reltuples desc
limit 32;
select '
'||to_char(t.reltuples,'999G999G999G999G999G999G999')
from pg_class t, pg_roles, pg_catalog.pg_namespace n, pg_class r
where t.relowner=pg_roles.oid
and n.oid=r.relnamespace
and r.reltoastrelid = t.oid
and t.relkind='t'
and t.reltuples>0
order by pg_relation_size(t.oid) desc
limit 10;
select '
' as info;
select '
' as info;
select '
Procedural Languages
'
as info;
select '
Available languages' as info;
select '
'||lanname
from pg_language;
select '
PL Objects
';
select '
Owner',
'
Kind',
'
Language',
'
Count',
'
Source size'
as info;
select '
'||o.rolname,
'
'||case when f.prokind='f' then 'Function'
when f.prokind='a' then 'Aggregate func.'
when f.prokind='w' then 'Window func.'
when f.prokind='p' then 'Procedure'
else 'Other' end,
'
'||l.lanname, '
'||count(*),
'
'||sum(char_length(prosrc))
from pg_proc f, pg_roles o, pg_language l
where f.proowner=o.oid
and f.prolang=l.oid
group by o.rolname, l.lanname, prokind
order by o.rolname, prokind, l.lanname;
select '
' as info;
-- regexp_split_to_table(prosrc, E'\n')
select '
' as info;
select '
Data Types - Details
' ;
select '
Data Types
'
as info;
select '
Owner',
'
Data type',
'
Count'
as info;
select '
'||o.rolname, '
'||t.typname, '
'||count(*)
from pg_attribute a, pg_class r, pg_roles o, pg_type t
where a.attrelid=r.oid
and a.atttypid=t.oid
and r.relowner=o.oid
and o.rolname not in ('enterprisedb', 'postgres')
group by o.rolname, t.typname
order by o.rolname, t.typname;
select '
' as info;
select '
' as info;
select '
Physical Backup
'
as info;
select '
Parameter',
'
Value'
as info;
select '
',name,'
',setting
from pg_settings
where name in ('archive_mode', 'archive_timeout')
order by name;
select '
Write xlog location',
'
'||pg_current_wal_lsn();
select '
Insert xlog location',
'
'||pg_current_wal_insert_lsn();
select '
' as info;
select '
' as info;
select '
Archiver Statistics
'
as info;
select '
Archived Count ',
'
Last Archived WAL ',
'
Last Archived Time ',
'
Failed Count ',
'
Last Failed WAL ',
'
Last Failed Time ',
'
Statistics Reset ',
'
Archiving ',
'
WALS ps '
as info;
select '
',archived_count, '
',last_archived_wal, '
',last_archived_time, '
',failed_count,
'
',last_failed_wal, '
',last_failed_time, '
',stats_reset,
'
', current_setting('archive_mode')::BOOLEAN
AND (last_failed_wal IS NULL
OR last_failed_wal <= last_archived_wal),
'
', CAST (archived_count AS NUMERIC) / EXTRACT (EPOCH FROM age(now(), stats_reset))
from pg_stat_archiver;
select '
' as info;
select '
' as info;
select '
Replication
'
as info;
select '
Parameter',
'
Value'
as info;
select '
In Recovery Mode',
'
'||pg_is_in_recovery()||'';
select '
',name,'
',replace(replace(setting,'<','<'),'>','>')
from pg_settings
where name in ('wal_level', 'archive_command', 'hot_standby', 'max_wal_senders', 'checkpoint_segments', 'max_wal_size', 'archive_mode',
'max_standby_archive_delay', 'max_standby_streaming_delay', 'hot_standby_feedback',
'wal_keep_segments', 'wal_keep_size', 'synchronous_standby_names', 'recovery_target_timeline',
'wal_receiver_create_temp_slot', 'max_slot_wal_keep_size', 'ignore_invalid_pages',
'primary_slot_name', 'primary_conninfo', 'max_slot_wal_keep_size',
'vacuum_defer_cleanup_age')
order by name;
select '
' as info;
select '
Master Statistics
' ;
select '
Client', '
State', '
Sync',
'
Current Snapshot', '
Sent loc.',
'
Write loc.', '
Flush loc.', '
Replay loc.', '
Backend Start';
select '
Write lag', '
Flush lag', '
Replay lag';
select '
',client_addr, '
', state, '
', sync_state, '
', txid_current_snapshot(),
'
', sent_lsn, '
',write_lsn, '
',flush_lsn, '
',replay_lsn,
'
', backend_start, '
',write_lag, '
',flush_lag, '
',replay_lag
from pg_stat_replication;
select '
' as info;
select '
Replication Slots
' ;
select '
Name', '
Type', '
Active',
'
XMIN', '
Catalog XMIN', '
Restart LSN';
select '
',slot_name, '
', slot_type, '
', active,
'
', xmin, '
', catalog_xmin, '
', restart_lsn
from pg_replication_slots;
select '
' as info;
select '
Slave Statistics
' ;
select '
Last Replication','
Replication Delay','
Current Snapshot',
'
Receive loc.','
Replay loc.';
select '
', now() - pg_last_xact_replay_timestamp(),
'
', CASE WHEN pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn() THEN 0
ELSE EXTRACT (EPOCH FROM now() - pg_last_xact_replay_timestamp()) END,
'
', case when pg_is_in_recovery() then txid_current_snapshot() else null end,
'
', pg_last_wal_receive_lsn(),
'
', pg_last_wal_replay_lsn();
select '
' as info;
select '
WAL Receiver
' ;
select '
PID','
Status','
Connection',
'
Latest LSN','
Latest time';
select '
',pid, '
', status, '
', conninfo,
'
', latest_end_lsn, '
', latest_end_time
from pg_stat_wal_receiver;
select '
' as info;
select '
Logical Replication - Subscriptions
' ;
select '
Subscription Name','
Pid','
Relation OID',
'
Received','
Last Message Send','
Last Message Receipt',
'
Latest location','
Latest time';
select '
',subname, '
',pid, '
',relid, '
',received_lsn, '
',last_msg_send_time,
'
',last_msg_receipt_time, '
',latest_end_lsn, '
',latest_end_time
from pg_stat_subscription
order by subname;
select '
' as info;
select '
Logical Replication - Details
' ;
select '
Publications
' ;
select '
Publication Name','
Owner',
'
All tables', '
Insert', '
Update', '
Delete';
select '
',pubname, '
',rolname,
'
',puballtables, '
', pubinsert, '
', pubupdate, '
', pubdelete
from pg_publication p, pg_roles a
where a.oid=p.pubowner
order by pubname;
select '
Publication Name','
Schema','
Table';
select '
',pubname, '
',schemaname, '
',tablename
from pg_publication_tables
order by pubname, tablename;
select '
';
select '
Subscriptions
' ;
select '
Subscription Name','
Database','
Owner',
'
Enabled', '
Sync. Commit', '
Slot ', '
Connection ';
select '
',subname, '
',datname, '
',rolname,
'
',subenabled, '
', subsynccommit, '
', subslotname, '
', subconninfo
from pg_subscription s, pg_database d, pg_roles a
where d.oid=s.subdbid
and a.oid=s.subowner
order by subname;
select '
Subscription Name','
Schema','
Table',
'
State', '
LSN';
select '
',subname, '
', '
',relname,
'
',srsubstate, '
', srsublsn
from pg_subscription_rel r, pg_subscription s, pg_class c
where s.oid=r.srsubid
and c.oid=r.srrelid
order by subname, relname;
select '
';
select '
';
select '
' as info;
select '
Extensions
'
as info;
select '
Name',
'
Default Version',
'
Installed Version',
'
Description'
as info;
select '
',name,'
',default_version,'
',installed_version,'
',comment
from pg_available_extensions
order by case when installed_version is null then 1 else 0 end, name;
select '
postgis
PostGIS installed (pre-extensions check)' pg
from pg_proc
where proname='postgis_version';
select '
' as info;
select '
' as info;
select '
NLS Settings
'
as info;
select '
Parameter',
'
Value',
'
Description'
as info;
select '
',name,'
',setting,
'
',short_desc
from pg_settings
where name like 'lc%'
order by name;
select '
' as info;
select '
' as info;
select '
Configured Parameters
'
as info;
select '
Parameter',
'
Value',
'
Description',
'
Source'
as info;
select '
',name,'
',
replace(replace(
case when unit='kB' then pg_size_pretty(setting::bigint*1024)
when unit='8kB' then pg_size_pretty(setting::bigint*1024*8)
when unit='B' then pg_size_pretty(setting::bigint)
when unit='MB' then pg_size_pretty(setting::bigint*1024*1024)
else coalesce(setting||' '||unit,setting) end,
'<','<'),'>','>'),
'
',short_desc, '
',source
from pg_settings
where source not in ('default', 'override', 'client')
order by name;
select '
' as info;
select '
' as info;
select '
PostgreSQL Parameters
'
as info;
select '
Parameter',
'
Value',
'
Min',
'
Max',
'
Description',
'
Category',
'
Context',
'
Source'
as info;
select '
',name,'
',
replace(replace(
case when unit='kB' then pg_size_pretty(setting::bigint*1024)
when unit='8kB' then pg_size_pretty(setting::bigint*1024*8)
when unit='B' then pg_size_pretty(setting::bigint)
when unit='MB' then pg_size_pretty(setting::bigint*1024*1024)
else coalesce(setting||' '||unit,setting) end,
'<','<'),'>','>'),
'
',min_val,'
',max_val,
'
',short_desc, '
',category, '
',context, '
',source
from pg_settings
order by name;
select '
' as info;
select '
' as info;
select '
HBA file
';
select '
' as info;
select pg_read_file('pg_hba.conf',1,10240);
select '
' as info;
-- SELECT * from pg_catalog.pg_read_file('pg_hba.conf');
-- WITH f(name) AS (VALUES('pg_hba.conf'))
-- SELECT pg_catalog.pg_read_file(name, 0, (pg_catalog.pg_stat_file(name)).size) FROM f;
select '
' as info;
select '
WAL files (20)
';
select '
' as info;
\pset tuples_only
\a
select * from pg_ls_waldir() order by modification desc limit 20;
select pg_size_pretty(sum(size)) as WAL_total_size from pg_ls_waldir();
\pset tuples_only
\a
select '
' as info;
/* Extensions info dynamic part */
select '
' as info;
select '
Optional informations
' as info;
SELECT
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='pg_stat_statements' and installed_version is not null) as pg_stat_statements,
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='pg_buffercache' and installed_version is not null) as pg_buffercache,
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='pgstattuple' and installed_version is not null) as pgstattuple,
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='pg_freespacemap' and installed_version is not null) as pg_freespacemap,
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='sslinfo' and installed_version is not null) as sslinfo,
EXISTS (SELECT 1 FROM pg_stat_ssl WHERE ssl limit 1) as ssl_active,
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='pgaudit' and installed_version is not null) as pgaudit,
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='pgrowlocks' and installed_version is not null) as pgrowlocks,
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='postgis' and installed_version is not null) as postgis,
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='edbspl') as edb,
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='aurora_stat_utils') as aurora,
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='aurora_stat_utils') as aurora_stat,
EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='apg_plan_mgmt') as qpm
\gset opt_
-- pg_stat_statements are pg_buffercache are too important to be "optional"
\if :opt_pgstattuple
select '
' as info;
select '
Bloat detailed informations for biggest tables (can be time expensive: uncomment if needed)
';
select '
' as info;
\pset tuples_only
\a
\if 0
select relname Relation, (pgstattuple(pg_class.oid::regclass)).*
from pg_class, pg_roles, pg_catalog.pg_namespace n
where relowner=pg_roles.oid
and n.oid=pg_class.relnamespace
and relkind = 'r'
order by relpages desc, reltuples desc
limit 50;
\endif
\pset tuples_only
\a
select '
' as info;
\endif
\if :opt_sslinfo
select '
' as info;
select '
SSL Informations on current connection
';
select '
SSL Usage','
SSL Version',
'
SSL Cipher',
'
Client Certificate'
as info;
SELECT '
', ssl_is_used(), '
', ssl_version(), '
', ssl_cipher(), '
', ssl_client_cert_present();
select '
' as info;
\endif
\if :opt_ssl_active
select '
' as info;
select '
SSL Informations on all connections
';
select '
' as info;
select * from pg_stat_ssl;
select '
' as info;
\endif
\if :var_version_12p
select '
' as info;
select '
Additional PG12+ Statistics
';
select '
' as info;
\pset tuples_only
\a
select *
from pg_stats_ext;
SELECT *
from pg_stat_gssapi;
-- pg_stat_progress_cluster pg_stat_progress_create_index
\pset tuples_only
\a
select '
' as info;
\endif
\if :var_version_13p
select '
' as info;
select '
Additional PG13+ Statistics
';
select '
' as info;
\pset tuples_only
\a
select replace(replace(name, '<', '-'), '>', '-') as name, off, size, allocated_size
from pg_shmem_allocations
order by allocated_size desc;
SELECT *
from pg_stat_slru;
-- pg_stat_progress_analyze pg_stat_progress_basebackup
\pset tuples_only
\a
select '
' as info;
\endif
\if :var_version_14p
select '
' as info;
select '
Additional PG14+ Statistics
';
select '
' as info;
\pset tuples_only
\a
select *,
pg_size_pretty(wal_bytes/extract(epoch from (now()-stats_reset)/3600)) wal_hour
from pg_stat_wal;
SELECT *
from pg_backend_memory_contexts
ORDER BY used_bytes DESC LIMIT 10;
SELECT *
from pg_stat_replication_slots;
SELECT *
from pg_stat_statements_info;
SELECT *
from pg_stats_ext_exprs;
\pset tuples_only
\a
select '
' as info;
\endif
\if :var_version_15p
select '
' as info;
select '
Additional PG15+ Statistics
';
select '
' as info;
\pset tuples_only
\a
select *
from pg_parameter_acl;
-- pg_publication_namespace
\pset tuples_only
\a
select '
' as info;
\endif
\if :var_version_16p
select '
' as info;
select '
Additional PG16+ Statistics
';
select '
' as info;
\pset tuples_only
\a
select 'No new system catalog views';
\pset tuples_only
\a
select '
' as info;
\endif
\if :opt_postgis
select '
' as info;
select '
Postgis Statistics
';
select '
' as info;
\pset tuples_only
\a
select 'PostgreSQL Version: ', version();
select 'PostGIS Version: ', PostGIS_version();
select 'PostGIS Full Version: ', PostGIS_full_version();
SELECT 'Extension: ', name, installed_version
FROM pg_available_extensions WHERE name like 'postgis%'
ORDER BY name;
select 'GIS Objects: ', count(*)
from geometry_columns;
select 'GiST Indexes: ', count(*)
from pg_index, pg_class, pg_roles
where pg_index.indrelid=pg_class.oid
and relowner=pg_roles.oid
and upper(pg_get_indexdef(indexrelid)) like '%GIST%';
select 'Projection: ', substr(proj4text, 1,10), count(*)
from spatial_ref_sys
group by substr(proj4text, 1,10);
\pset tuples_only
\a
select '
' as info;
\endif
\if :opt_edb
select '
' as info;
select '
Additional EnterpriseDB Advanced Server Statistics
';
select '
' as info;
\pset tuples_only
\a
select *
from all_policies;
select *
from all_directories;
select *
from all_db_links;
select *
from product_component_version;
\if :var_version_14p
select *
from all_objects
where schema_name not in ('SYS')
order by last_ddl_time desc
limit 20;
select *
from all_users
order by creation_date desc
limit 20;
\endif
select *
from session_waits;
select *
from system_waits;
select *
from session_waits_history
limit 50;
select *
from system_waits_history
limit 50;
\pset tuples_only
\a
select '
Statistics generated on: '|| current_date || ' ' ||localtime as info;
select ' More info on' as info;
select 'this site' as info;
select 'or contact' as info;
select 'Meo.