On Thu, Feb 15, 2018 at 9:22 PM, Tim Cross <theophil...@gmail.com> wrote:

> Hi All,
>
> I was wondering if anyone has some pointers to
> sites/repositories/resources for scripts to perform basic database
> audits and health checks.
>
> situation: I have just commenced a DBA and developer role for an
> organisation with a number of Postgres databases (9.4 and 9.6
> versions). There has been no dedicated DBA and a number of the databases
> were setup by people with little to know Postgres or database
> experience. I need to get an overview on what I'm dealing with and start
> prioritising what to address first.
>
> It has been some years since I've done any real work with Postgres. Most
> of my technical work over the last 10 years has been with Oracle. I
> prefer to use scripts over GUI tools like pgAdmin and suspect that there
> is probably some good resources out there with existing scripts I can
> use as a starting point.
>
> Any pointers greatly appreciated.
>
> thanks,
>
> Tim
>
>
> --
> Tim Cross
>
>




























*Tim, Good luck to you. I have been in your situation a few times.I have
attached the following scripts which I use as a starterto get a general
idea of database status. All of the should run on both 9.4 & 9.4, but
sometimes catalog changes may fudge things up, so you may have to tweak a
bit. I have manymore general queries, so if you have any specific need,
letme know and I'll be glad to send if I have one that fits theneed.The
names should be self descriptive as to what the dobut except for
get_trans_min_cnt.sql (Transaction per minute) none have any DDL.
database_sizes.sqlbad_idx.sqlcache_hit_ratio.sqlget_trans_min_cnt.sqlget_version_num.sqlpg_runtime.sqlpg_stat_all_indexes.sqlpg_stat_all_tables.sqltable_sizes.sqltable_stats.sqluseless_indexes2.sqlPlease
also note I have bash script versions of the same, butas you did not state
the O/S, I felt the sql was best.*--
*Melvin Davidson*
I reserve the right to fantasize.  Whether or not you
wish to share my fantasy is entirely up to you.
SELECT oid, 
       datname, 
       pg_size_pretty(pg_database_size(datname))as size_pretty, 
       pg_database_size(datname) as size,
       (SELECT pg_size_pretty (SUM( pg_database_size(datname))::bigint)  
          FROM pg_database)  AS total,
       ((pg_database_size(datname) / (SELECT SUM( pg_database_size(datname))  
                                       FROM pg_database) ) * 100)::numeric(6,3) 
AS pct
  FROM pg_database 
  ORDER BY datname;
SELECT n.nspname, 
       i.relname, 
       i.indexrelname, 
       CASE WHEN idx.indisprimary 
            THEN 'pkey' 
            WHEN idx.indisunique 
            THEN 'uidx' 
            ELSE 'idx' 
        END AS type, 
        'INVALID' 
  FROM pg_stat_all_indexes i 
  JOIN pg_class c     ON (c.oid = i.relid) 
  JOIN pg_namespace n ON (n.oid = c.relnamespace) 
  JOIN pg_index idx   ON (idx.indexrelid =  i.indexrelid ) 
 WHERE idx.indisvalid = FALSE  
 ORDER BY 1, 2;
SELECT pg_stat_database.datname, 
       pg_stat_database.blks_read,
       pg_stat_database.blks_hit, 
       round((pg_stat_database.blks_hit::double precision 
              / (pg_stat_database.blks_read 
                 + pg_stat_database.blks_hit 
                 +1)::double precision * 100::double precision)::numeric, 2) AS 
cachehitratio
   FROM pg_stat_database
  WHERE pg_stat_database.datname !~ '^(template(0|1)|postgres)$'::text
  ORDER BY round((pg_stat_database.blks_hit::double precision 
                 / (pg_stat_database.blks_read 
                    + pg_stat_database.blks_hit 
                    + 1)::double precision * 100::double precision)::numeric, 
2) DESC;
BEGIN;

DROP TABLE IF EXISTS tmp_trans_stats;

CREATE TEMP TABLE tmp_trans_stats AS
SELECT 'start_cnt'::varchar(10) AS taken, 
       SUM(xact_commit + xact_rollback) AS cnt
  FROM pg_stat_database;

COMMIT;

SELECT pg_sleep(60);

INSERT INTO tmp_trans_stats
SELECT 'end_cnt'::varchar(10) AS taken,
       SUM(xact_commit + xact_rollback) AS cnt
  FROM pg_stat_database;
  
SELECT (
        (SELECT cnt 
          FROM tmp_trans_stats
         WHERE taken = 'end_cnt')
     - (SELECT cnt 
          FROM tmp_trans_stats
         WHERE taken = 'start_cnt')
       ) as tot_trans;
SELECT current_setting('server_version_num');
SELECT pg_postmaster_start_time() as pg_start, 
       current_timestamp - pg_postmaster_start_time() as runtime;
SELECT n.nspname as schema,
       i.relname as table,
       i.indexrelname as index,
       i.idx_scan,
       i.idx_tup_read,
       i.idx_tup_fetch,
       CASE WHEN idx.indisprimary
            THEN 'pkey'
            WHEN idx.indisunique
            THEN 'uidx'
            ELSE 'idx'
            END AS type,
           idx.indisexclusion,
       pg_get_indexdef(idx.indexrelid),
       CASE WHEN idx.indisvalid
            THEN 'valid'
            ELSE 'INVALID'
            END as statusi,
       pg_relation_size(quote_ident(n.nspname)|| '.' || quote_ident(i.relname)) 
as size_in_bytes,
       pg_size_pretty(pg_relation_size(quote_ident(n.nspname)|| '.' || 
quote_ident(i.relname))) as size
  FROM pg_stat_all_indexes i
  JOIN pg_class c ON (c.oid = i.relid)
  JOIN pg_namespace n ON (n.oid = c.relnamespace)
  JOIN pg_index idx ON (idx.indexrelid =  i.indexrelid )
 WHERE i.relname LIKE '%%'
   AND n.nspname NOT LIKE 'pg_%'
   AND NOT idx.indisunique = TRUE
   AND NOT idx.indisprimary 
--   AND i.indexrelname LIKE 'tmp%'
--   AND idx.indisvalid IS false
/*   AND NOT idx.indisprimary 
   AND NOT idx.indisunique
   AND idx_scan = 0
*/ ORDER BY 1, 2, 3;

SELECT n.nspname,
       s.relname,
       c.reltuples::bigint,
--       c.relfrozenxid,
       age(c.relfrozenxid) AS age_frozenxid,
--       n_live_tup,
       n_tup_ins,
       n_tup_upd,
       n_tup_del,
       date_trunc('second', last_vacuum) as last_vacuum,
       date_trunc('second', last_autovacuum) as last_autovacuum,
       date_trunc('second', last_analyze) as last_analyze,
       date_trunc('second', last_autoanalyze) as last_autoanalyze
       ,
       round( current_setting('autovacuum_vacuum_threshold')::integer + 
current_setting('autovacuum_vacuum_scale_factor')::numeric * C.reltuples) AS 
av_threshold 
/*       ,CASE WHEN reltuples > 0
              THEN round(100.0 * n_dead_tup / (reltuples))
            ELSE 0
       END AS pct_dead,
       CASE WHEN n_dead_tup > round( 
current_setting('autovacuum_vacuum_threshold')::integer + 
current_setting('autovacuum_vacuum_scale_factor')::numeric * C.reltuples) 
              THEN 'VACUUM'
            ELSE 'ok' 
        END AS "av_needed"
*/
  FROM pg_stat_all_tables s
  JOIN pg_class c ON c.oid = s.relid
  JOIN pg_namespace n ON (n.oid = c.relnamespace)
 WHERE s.relname NOT LIKE 'pg_%'
   AND s.relname NOT LIKE 'sql_%'
--   AND s.relname LIKE '%TBL%'
 ORDER by 1, 2;

SELECT n.nspname as schema,
       c.relname as table,
       a.rolname as owner,
       c.relfilenode as filename,
       c.reltuples::bigint,
       pg_size_pretty(pg_relation_size(n.nspname|| '.' || c.relname)) as size,
       pg_size_pretty(pg_total_relation_size(n.nspname|| '.' || c.relname)) as 
total_size,
       pg_relation_size(n.nspname|| '.' || c.relname) as size_bytes,
       pg_total_relation_size(n.nspname|| '.' || c.relname) as total_size_bytes,
       CASE WHEN c.reltablespace = 0
            THEN 'pg_default'
            ELSE (SELECT t.spcname 
                    FROM pg_tablespace t WHERE (t.oid = c.reltablespace) )      
              
        END as tablespace
FROM pg_class c
  JOIN pg_namespace n ON (n.oid = c.relnamespace)
  JOIN pg_authid a ON ( a.oid = c.relowner )
  WHERE n.nspname NOT LIKE 'pg_%' 
    AND relname NOT LIKE 'pg_%' 
    AND relname NOT LIKE 'information%' 
    AND relname NOT LIKE 'sql_%' 
    AND relkind IN ('r')
ORDER BY total_size_bytes DESC, 1, 2;
--LIMIT 10;
SELECT c.oid, 
       n.nspname as schema,
       c.relname as table, 
       pg_stat_get_last_vacuum_time(c.oid) as last_vacuum,
       pg_stat_get_tuples_inserted(c.oid) as inserted,
       pg_stat_get_tuples_updated(c.oid) as updated,
       pg_stat_get_tuples_deleted(c.oid) as deleted
  FROM pg_class c
  JOIN pg_namespace n ON (n.oid = c.relnamespace)
 WHERE nspname NOT IN ('information_schema', 'pg_toast', 'pg_catalog')
   and relkind = 'r'
 ORDER BY 2, 3;
SELECT n.nspname as schema,
       i.relname as table,
       i.indexrelname as index,
       i.idx_scan,
       i.idx_tup_read,
       i.idx_tup_fetch,
       pg_size_pretty(pg_relation_size(quote_ident(n.nspname) || '.' || 
quote_ident(i.relname))) AS table_size, 
       pg_size_pretty(pg_relation_size(quote_ident(n.nspname) || '.' || 
quote_ident(i.indexrelname))) AS index_size,
       pg_get_indexdef(idx.indexrelid) as idx_definition
  FROM pg_stat_all_indexes i
  JOIN pg_class c ON (c.oid = i.relid)
  JOIN pg_namespace n ON (n.oid = c.relnamespace)
  JOIN pg_index idx ON (idx.indexrelid =  i.indexrelid )
 WHERE i.idx_scan = 0
   AND n.nspname <> 'pg_catalog'
   AND NOT idx.indisprimary
   AND NOT idx.indisunique
 ORDER BY 1, 2, 3;


Reply via email to