Skip to content

Instantly share code, notes, and snippets.

@mbarany
Last active January 27, 2024 23:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbarany/3146d44de1ba34742919fbcd00b7bf4f to your computer and use it in GitHub Desktop.
Save mbarany/3146d44de1ba34742919fbcd00b7bf4f to your computer and use it in GitHub Desktop.
Postgres Commands
# Postgres Commands
-- List Tables
SELECT n.nspname, c.relname
FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE c.relkind = 'r'
AND n.nspname <> 'information_schema'
AND n.nspname !~ '^pg_';
-- Get Table Sizes
SELECT nspname || '.' || relname AS "relation",
pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
AND C.relkind <> 'i'
AND nspname !~ '^pg_toast'
ORDER BY pg_total_relation_size(C.oid) DESC;
-- Get DB Names & Sizes
SELECT
t1.datname AS db_name,
pg_size_pretty(pg_database_size(t1.datname)) AS db_size
FROM pg_database t1
ORDER BY pg_database_size(t1.datname) DESC;
-- Get Current Queries
SELECT pid, age(clock_timestamp(), query_start), usename, query
FROM pg_stat_activity
WHERE query != '<IDLE>' AND query NOT ILIKE '%pg_stat_activity%'
ORDER BY age desc;
-- Terminate with PID
SELECT pg_terminate_backend(<PID>);
-- Refresh query stats for table
ANALYZE <table_name>;
-- Clean up dead rows & refresh query stats for table
VACUUM ANALYZE <table_name>;
SELECT
*
FROM
pg_settings
WHERE
name LIKE '%autovacuum%';
SELECT relname, reloptions, *
FROM pg_class;
WITH raw_data AS (
SELECT
pg_namespace.nspname,
pg_class.relname,
pg_class.oid AS relid,
pg_class.reltuples::numeric,
pg_stat_all_tables.n_dead_tup,
pg_stat_all_tables.n_mod_since_analyze,
(SELECT split_part(x, '=', 2) FROM unnest(pg_class.reloptions) q (x) WHERE x ~ '^autovacuum_analyze_scale_factor=' ) as c_analyze_factor,
(SELECT split_part(x, '=', 2) FROM unnest(pg_class.reloptions) q (x) WHERE x ~ '^autovacuum_analyze_threshold=' ) as c_analyze_threshold,
(SELECT split_part(x, '=', 2) FROM unnest(pg_class.reloptions) q (x) WHERE x ~ '^autovacuum_vacuum_scale_factor=' ) as c_vacuum_factor,
(SELECT split_part(x, '=', 2) FROM unnest(pg_class.reloptions) q (x) WHERE x ~ '^autovacuum_vacuum_threshold=' ) as c_vacuum_threshold,
to_char(pg_stat_all_tables.last_vacuum, 'YYYY-MM-DD HH24:MI:SS') as last_vacuum,
to_char(pg_stat_all_tables.last_autovacuum, 'YYYY-MM-DD HH24:MI:SS') as last_autovacuum
FROM
pg_class
JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
LEFT OUTER JOIN pg_stat_all_tables ON pg_class.oid = pg_stat_all_tables.relid
WHERE
n_dead_tup IS NOT NULL
AND nspname NOT IN ('information_schema', 'pg_catalog')
AND nspname NOT LIKE 'pg_toast%'
AND pg_class.relkind = 'r'
), data AS (
SELECT
*,
COALESCE(raw_data.c_analyze_factor, current_setting('autovacuum_analyze_scale_factor'))::float8 AS analyze_factor,
COALESCE(raw_data.c_analyze_threshold, current_setting('autovacuum_analyze_threshold'))::float8 AS analyze_threshold,
COALESCE(raw_data.c_vacuum_factor, current_setting('autovacuum_vacuum_scale_factor'))::float8 AS vacuum_factor,
COALESCE(raw_data.c_vacuum_threshold, current_setting('autovacuum_vacuum_threshold'))::float8 AS vacuum_threshold
FROM raw_data
)
SELECT
relid,
nspname,
relname,
reltuples,
n_dead_tup,
ROUND(reltuples * vacuum_factor + vacuum_threshold) AS v_threshold,
n_mod_since_analyze,
ROUND(reltuples * analyze_factor + analyze_threshold) AS a_threshold,
c_analyze_factor as caf,
c_analyze_threshold as cat,
c_vacuum_factor as cvf,
c_vacuum_threshold as cvt,
analyze_factor as af,
analyze_threshold as at,
vacuum_factor as vf,
vacuum_threshold as vt,
last_vacuum,
last_autovacuum
FROM
data
ORDER BY n_dead_tup DESC;
-- Show schema privileges
\dn+
-- Table access privileges
\dp
-- Default access privileges
\ddp
-- Count Estimate
SELECT reltuples AS estimate FROM pg_class WHERE relname = 'table_name';
SELECT relname table_name, n_dead_tup dead_tuples, n_live_tup live_tuples, ROUND(n_dead_tup::numeric / NULLIF(n_live_tup, 0), 4) dead_tuple_percentage, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC NULLS LAST, relname;
-- Concurrent indexes show up as invalid. This query shows any invalid index
SELECT * FROM pg_class, pg_index WHERE pg_index.indisvalid = false AND pg_index.indexrelid = pg_class.oid;
-- Get index statistics
SELECT
t.schemaname,
t.tablename,
c.reltuples::bigint AS num_rows,
pg_relation_size(c.oid) AS table_size,
psai.indexrelname AS index_name,
pg_relation_size(i.indexrelid) AS index_size,
CASE WHEN i.indisunique THEN 'Y' ELSE 'N' END AS "unique",
psai.idx_scan AS number_of_scans,
psai.idx_tup_read AS tuples_read,
psai.idx_tup_fetch AS tuples_fetched
FROM
pg_tables t
LEFT JOIN pg_class c ON t.tablename = c.relname
LEFT JOIN pg_index i ON c.oid = i.indrelid
LEFT JOIN pg_stat_all_indexes psai ON i.indexrelid = psai.indexrelid
WHERE
t.schemaname NOT IN ('pg_catalog', 'information_schema', 'pglogical')
ORDER BY 1, 2, index_name;
-- Get the datetime of last reset
SELECT datname, stats_reset
FROM pg_stat_database
ORDER BY datname;
SELECT query,
calls,
total_time,
blk_read_time,
blk_write_time,
rows,
shared_blks_hit,
shared_blks_read,
shared_blks_dirtied,
shared_blks_written,
local_blks_hit,
local_blks_read,
local_blks_dirtied,
local_blks_written,
temp_blks_read,
temp_blks_written
FROM pg_stat_statements
ORDER BY blk_read_time DESC, blk_write_time DESC;
-- Revoke default privileges from 'public' role
\c mydatabase
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON DATABASE mydatabase FROM PUBLIC;
-- Read-only role
\c mydatabase
CREATE USER readonly WITH ENCRYPTED PASSWORD 'my_password';
GRANT CONNECT ON DATABASE mydatabase TO readonly;
GRANT USAGE ON SCHEMA public TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;
ALTER DEFAULT PRIVILEGES GRANT SELECT ON SEQUENCES TO readonly;
-- Read/write role
\c mydatabase
CREATE USER readwrite WITH ENCRYPTED PASSWORD 'my_password';
GRANT CONNECT ON DATABASE mydatabase TO readwrite;
GRANT USAGE, CREATE ON SCHEMA public TO readwrite;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO readwrite;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO readwrite;
ALTER DEFAULT PRIVILEGES GRANT USAGE, SELECT, UPDATE ON SEQUENCES TO readwrite;
-- DDL/Read/write role
\c mydatabase
CREATE USER app_user WITH ENCRYPTED PASSWORD 'my_password';
GRANT CONNECT ON DATABASE mydatabase TO app_user;
GRANT USAGE, CREATE ON SCHEMA public TO app_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO app_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO app_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO app_user;
ALTER DEFAULT PRIVILEGES GRANT ALL PRIVILEGES ON SEQUENCES TO app_user;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment