CREATE OR REPLACE FUNCTION pgcozy_init () RETURNS void AS $$ BEGIN IF (select count(*) from pg_extension where extname in ('pg_buffercache','pg_prewarm')) = 2 THEN RAISE NOTICE 'pg_buffercache and pg_prewarm exists continuing...'; drop schema IF EXISTS pgcozy cascade; create schema pgcozy; create table pgcozy.snapshots (id serial,snapshot_date date, snapshot jsonb); create unique index snapshots_uniq_idx on pgcozy.snapshots (id, snapshot_date); drop type cozy_type; create type cozy_type as (table_name text,block_no int, popularity int); RAISE NOTICE 'Everything is done, check pgcozy schema for more details.'; ELSE RAISE EXCEPTION 'pgcozy needs pg_buffercache and pg_prewarm extensions , install them and run pgcozy_init again.'; END IF; END $$ LANGUAGE 'plpgsql' ; CREATE OR REPLACE FUNCTION pgcozy_snapshot (a_pop int) RETURNS void AS $$ BEGIN IF a_pop >= 1 and a_pop <= 5 THEN RAISE NOTICE 'Getting a new snapshot...'; insert into pgcozy.snapshots (snapshot_date,snapshot) select now()::date, array_to_json(array_agg(row_to_json(r)))::jsonb FROM ( SELECT n.nspname||'.'|| c.relname as table_name ,b.relblocknumber as block_no,b.usagecount as popularity FROM pg_class c, pg_buffercache b , pg_database d , pg_namespace n where b.relfilenode = c.relfilenode and b.reldatabase=d.oid and n.oid = c.relnamespace and c.relkind in ('i','r') and b.isdirty='f' and b.usagecount >= a_pop and n.nspname !='pg_catalog' ) r ; ELSIF a_pop=0 THEN RAISE NOTICE 'Getting a new snapshot of all contents of pg_buffercache...'; insert into pgcozy.snapshots (snapshot_date,snapshot) select now()::date, array_to_json(array_agg(row_to_json(r)))::jsonb FROM ( SELECT n.nspname||'.'|| c.relname as table_name ,b.relblocknumber as block_no,b.usagecount as popularity FROM pg_class c, pg_buffercache b , pg_database d , pg_namespace n where b.relfilenode = c.relfilenode and b.reldatabase=d.oid and n.oid = c.relnamespace and c.relkind in ('i','r') and b.isdirty='f' and n.nspname !='pg_catalog' ) r ; RAISE NOTICE 'Snapshot Taken..'; ELSE RAISE EXCEPTION 'popularity should be between 0 and 5 --> %', a_pop USING HINT = 'Usage pgcozy_snapshot popularity 0-5, 0 snapshots all contents of pg_buffercache'; END IF; END $$ LANGUAGE 'plpgsql' ; CREATE OR REPLACE FUNCTION pgcozy_warm (snapshot_id int) RETURNS void AS $$ DECLARE v_rec record; BEGIN IF snapshot_id >0 THEN RAISE NOTICE 'warming up according to the snapshot... --> %', snapshot_id; FOR v_rec IN select table_name,block_no,popularity from jsonb_populate_recordset( NULL::cozy_type,(select snapshot from pgcozy.snapshots where pgcozy.snapshots.id = snapshot_id)) LOOP RAISE NOTICE 'Warming up % ...', quote_literal(v_rec.table_name) ||' block '|| v_rec.block_no ; EXECUTE 'select pg_prewarm ('|| quote_literal(v_rec.table_name)||','||quote_literal('buffer')||','||quote_literal('main') ||','||v_rec.block_no||','||v_rec.block_no||')'; end LOOP; RAISE NOTICE 'Done Warming up snapshot_id -->%', snapshot_id; ELSIF snapshot_id = 0 THEN RAISE NOTICE 'warming up acording to the latest pgcozy snapshot...'; FOR v_rec IN select table_name,block_no,popularity from jsonb_populate_recordset( NULL::cozy_type, (select snapshot from pgcozy.snapshots where pgcozy.snapshots.id = (select max(id) from pgcozy.snapshots) )), pgcozy.snapshots where id = (select max(id) from pgcozy.snapshots) LOOP RAISE NOTICE 'Warming up % ...', quote_literal(v_rec.table_name) ||' block '|| v_rec.block_no ; EXECUTE 'select pg_prewarm ('|| quote_literal(v_rec.table_name)||','||quote_literal('buffer')||','||quote_literal('main') ||','||v_rec.block_no||','||v_rec.block_no||')'; end LOOP; RAISE NOTICE 'Done Warming up according to the latest snapshot...'; ELSE RAISE EXCEPTION 'Nonexistent snapshot_id --> %', snapshot_id USING HINT = 'Usage pgcozy_warm (snapshot_id , 0 if you want to warm according to the latest snapshot'; END IF; END $$ LANGUAGE 'plpgsql' ;