Skip to main content

Postgres Database

A free and open-source relational database.

  • Some helpful SQL for managing database in notes

Resources

Sites

Notes

Permissions

-- Check privileges on tables
SELECT *
FROM information_schema.role_table_grants
WHERE grantee = 'your_role_name';

-- Check privileges on schema
-- Check what privilges are granted on schemas
SELECT
r.usename AS grantor,
e.usename AS grantee,
nspname,
privilege_type,
is_grantable
FROM pg_namespace
JOIN LATERAL (SELECT * FROM aclexplode(nspacl) AS x) a ON true
JOIN pg_user e ON a.grantee = e.usesysid
JOIN pg_user r ON a.grantor = r.usesysid

-- Check the default privileges set for future objects
SELECT pgn.nspname, pga.* FROM pg_default_acl pga
LEFT JOIN pg_namespace pgn ON pga.defaclnamespace=pgn.oid;

-- GRANT and REVOKE
GRANT USAGE ON SCHEMA public TO new_user;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO new_user;
GRANT SELECT ON ALL TABLES IN SCHEMA schema_name TO new_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON special_schema.special_table TO new_user;
REVOKE SELECT ON secrets FROM new_user;

-- Alter owner
ALTER TABLE schema.table_name OWNER TO backend_app_migrations;
ALTER TYPE schema.type_name OWNER TO backend_app_migrations;

-- GRANT read on all existing tables
DO
$do$
DECLARE
sch text;
BEGIN
FOR sch IN
SELECT nspname FROM pg_namespace WHERE nspname NOT ILIKE 'pg_temp_%' AND nspname NOT ILIKE 'pg_toast%'
AND nspname <> 'pg_catalog' AND nspname <> 'information_schema'
LOOP
-- Grant access to existing schemas and tables
EXECUTE format($$ GRANT USAGE ON SCHEMA %I TO readaccess $$, sch);
EXECUTE format($$ GRANT SELECT ON ALL TABLES IN SCHEMA %I TO readaccess $$, sch);
END LOOP;
END;
$do$;

-- GRANT read on all future tables
ALTER DEFAULT PRIVILEGES FOR USER backend_app_migrations GRANT SELECT ON TABLES TO readaccess;

-- Change password
ALTER ROLE <role_name_here> WITH PASSWORD 'strong-generated-password';

Debug slow DB

-- Check if any transaction is running for a long time
-- Change the `WHERE` clause to find different kinds of activity
SELECT *
FROM pg_catalog.pg_stat_activity
WHERE state = 'active';

-- Check for uncommited PREPARED statements
SELECT gid, prepared, owner,
database, transaction AS xmin
FROM pg_prepared_xacts
ORDER BY age(transaction) DESC;

-- If yes, and it's safe to kill, kill it by PID
SELECT pg_cancel_backend(7489);

-- Check stats on vacuuming
SELECT schemaname, relname, n_tup_del, n_dead_tup, last_vacuum, last_autovacuum, *
FROM pg_catalog.pg_stat_all_tables
ORDER BY n_dead_tup DESC;

-- Vacuum and analyze the tables
VACUUM VERBOSE ANALYZE syncable_entities, syncable_entity_syncs;

-- Check connection stats
SELECT usename, client_addr, count(*)
FROM pg_stat_activity
GROUP BY client_addr, usename
ORDER BY count DESC;