diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 34f9d93b42..1f091d55d3 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -3,7 +3,7 @@ * * Copyright (c) 1996-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.19 2005/08/13 19:02:33 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.20 2005/08/15 16:25:17 tgl Exp $ */ CREATE VIEW pg_roles AS @@ -190,7 +190,7 @@ CREATE VIEW pg_stat_all_tables AS FROM pg_class C LEFT JOIN pg_index I ON C.oid = I.indrelid LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) - WHERE C.relkind = 'r' + WHERE C.relkind IN ('r', 't') GROUP BY C.oid, N.nspname, C.relname; CREATE VIEW pg_stat_sys_tables AS @@ -223,7 +223,7 @@ CREATE VIEW pg_statio_all_tables AS pg_class T ON C.reltoastrelid = T.oid LEFT JOIN pg_class X ON T.reltoastidxid = X.oid LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) - WHERE C.relkind = 'r' + WHERE C.relkind IN ('r', 't') GROUP BY C.oid, N.nspname, C.relname, T.oid, X.oid; CREATE VIEW pg_statio_sys_tables AS @@ -248,7 +248,7 @@ CREATE VIEW pg_stat_all_indexes AS pg_index X ON C.oid = X.indrelid JOIN pg_class I ON I.oid = X.indexrelid LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) - WHERE C.relkind = 'r'; + WHERE C.relkind IN ('r', 't'); CREATE VIEW pg_stat_sys_indexes AS SELECT * FROM pg_stat_all_indexes @@ -272,7 +272,7 @@ CREATE VIEW pg_statio_all_indexes AS pg_index X ON C.oid = X.indrelid JOIN pg_class I ON I.oid = X.indexrelid LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) - WHERE C.relkind = 'r'; + WHERE C.relkind IN ('r', 't'); CREATE VIEW pg_statio_sys_indexes AS SELECT * FROM pg_statio_all_indexes diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 3b3093727f..9aeecec7a6 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -10,15 +10,15 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.3 2005/08/11 21:11:44 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.4 2005/08/15 16:25:17 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" #include -#include #include +#include #include #include "access/genam.h" @@ -86,6 +86,7 @@ typedef struct autovac_dbase typedef struct autovac_table { Oid relid; + Oid toastrelid; bool dovacuum; bool doanalyze; int vacuum_cost_delay; @@ -101,8 +102,10 @@ static void process_whole_db(void); static void do_autovacuum(PgStat_StatDBEntry *dbentry); static List *autovac_get_database_list(void); static void test_rel_for_autovac(Oid relid, PgStat_StatTabEntry *tabentry, - Form_pg_class classForm, Form_pg_autovacuum avForm, - List **vacuum_tables); + Form_pg_class classForm, + Form_pg_autovacuum avForm, + List **vacuum_tables, + List **toast_table_ids); static void autovacuum_do_vac_analyze(List *relids, bool dovacuum, bool doanalyze, bool freeze); @@ -386,12 +389,21 @@ AutoVacMain(int argc, char *argv[]) if (db) { + /* + * Report autovac startup to the stats collector. We deliberately + * do this before InitPostgres, so that the last_autovac_time will + * get updated even if the connection attempt fails. This is to + * prevent autovac from getting "stuck" repeatedly selecting an + * unopenable database, rather than making any progress on stuff + * it can connect to. + */ + pgstat_report_autovac(db->oid); + /* * Connect to the selected database */ InitPostgres(db->name, NULL); SetProcessingMode(NormalProcessing); - pgstat_report_autovac(); set_ps_display(db->name); ereport(LOG, (errmsg("autovacuum: processing database \"%s\"", db->name))); @@ -538,6 +550,7 @@ do_autovacuum(PgStat_StatDBEntry *dbentry) HeapTuple tuple; HeapScanDesc relScan; List *vacuum_tables = NIL; + List *toast_table_ids = NIL; ListCell *cell; PgStat_StatDBEntry *shared; @@ -558,9 +571,25 @@ do_autovacuum(PgStat_StatDBEntry *dbentry) classRel = heap_open(RelationRelationId, AccessShareLock); avRel = heap_open(AutovacuumRelationId, AccessShareLock); + /* + * Scan pg_class and determine which tables to vacuum. + * + * The stats subsystem collects stats for toast tables independently + * of the stats for their parent tables. We need to check those stats + * since in cases with short, wide tables there might be proportionally + * much more activity in the toast table than in its parent. + * + * Since we can only issue VACUUM against the parent table, we need to + * transpose a decision to vacuum a toast table into a decision to vacuum + * its parent. There's no point in considering ANALYZE on a toast table, + * either. To support this, we keep a list of OIDs of toast tables that + * need vacuuming alongside the list of regular tables. Regular tables + * will be entered into the table list even if they appear not to need + * vacuuming; we go back and re-mark them after finding all the + * vacuumable toast tables. + */ relScan = heap_beginscan(classRel, SnapshotNow, 0, NULL); - /* Scan pg_class looking for tables to vacuum */ while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); @@ -571,9 +600,9 @@ do_autovacuum(PgStat_StatDBEntry *dbentry) ScanKeyData entry[1]; Oid relid; - /* Skip non-table entries. */ - /* XXX possibly allow RELKIND_TOASTVALUE entries here too? */ - if (classForm->relkind != RELKIND_RELATION) + /* Consider only regular and toast tables. */ + if (classForm->relkind != RELKIND_RELATION && + classForm->relkind != RELKIND_TOASTVALUE) continue; /* @@ -607,7 +636,7 @@ do_autovacuum(PgStat_StatDBEntry *dbentry) HASH_FIND, NULL); test_rel_for_autovac(relid, tabentry, classForm, avForm, - &vacuum_tables); + &vacuum_tables, &toast_table_ids); systable_endscan(avScan); } @@ -625,6 +654,22 @@ do_autovacuum(PgStat_StatDBEntry *dbentry) CHECK_FOR_INTERRUPTS(); + /* + * Check to see if we need to force vacuuming of this table because + * its toast table needs it. + */ + if (OidIsValid(tab->toastrelid) && !tab->dovacuum && + list_member_oid(toast_table_ids, tab->toastrelid)) + { + tab->dovacuum = true; + elog(DEBUG2, "autovac: VACUUM %u because of TOAST table", + tab->relid); + } + + /* Otherwise, ignore table if it needs no work */ + if (!tab->dovacuum && !tab->doanalyze) + continue; + /* Set the vacuum cost parameters for this table */ VacuumCostDelay = tab->vacuum_cost_delay; VacuumCostLimit = tab->vacuum_cost_limit; @@ -643,7 +688,7 @@ do_autovacuum(PgStat_StatDBEntry *dbentry) * test_rel_for_autovac * * Check whether a table needs to be vacuumed or analyzed. Add it to the - * output list if so. + * appropriate output list if so. * * A table needs to be vacuumed if the number of dead tuples exceeds a * threshold. This threshold is calculated as @@ -670,7 +715,8 @@ static void test_rel_for_autovac(Oid relid, PgStat_StatTabEntry *tabentry, Form_pg_class classForm, Form_pg_autovacuum avForm, - List **vacuum_tables) + List **vacuum_tables, + List **toast_table_ids) { Relation rel; float4 reltuples; /* pg_class.reltuples */ @@ -764,12 +810,10 @@ test_rel_for_autovac(Oid relid, PgStat_StatTabEntry *tabentry, * will be reset too. */ - elog(DEBUG2, "%s: vac: %.0f (threshold %.0f), anl: %.0f (threshold %.0f)", + elog(DEBUG3, "%s: vac: %.0f (threshold %.0f), anl: %.0f (threshold %.0f)", RelationGetRelationName(rel), vactuples, vacthresh, anltuples, anlthresh); - Assert(CurrentMemoryContext == AutovacMemCxt); - /* Determine if this table needs vacuum or analyze. */ dovacuum = (vactuples > vacthresh); doanalyze = (anltuples > anlthresh); @@ -778,23 +822,40 @@ test_rel_for_autovac(Oid relid, PgStat_StatTabEntry *tabentry, if (relid == StatisticRelationId) doanalyze = false; - if (dovacuum || doanalyze) + Assert(CurrentMemoryContext == AutovacMemCxt); + + if (classForm->relkind == RELKIND_RELATION) { - autovac_table *tab; + if (dovacuum || doanalyze) + elog(DEBUG2, "autovac: will%s%s %s", + (dovacuum ? " VACUUM" : ""), + (doanalyze ? " ANALYZE" : ""), + RelationGetRelationName(rel)); - elog(DEBUG2, "will%s%s %s", - (dovacuum ? " VACUUM" : ""), - (doanalyze ? " ANALYZE" : ""), - RelationGetRelationName(rel)); + /* + * we must record tables that have a toast table, even if we currently + * don't think they need vacuuming. + */ + if (dovacuum || doanalyze || OidIsValid(classForm->reltoastrelid)) + { + autovac_table *tab; - tab = (autovac_table *) palloc(sizeof(autovac_table)); - tab->relid = relid; - tab->dovacuum = dovacuum; - tab->doanalyze = doanalyze; - tab->vacuum_cost_limit = vac_cost_limit; - tab->vacuum_cost_delay = vac_cost_delay; + tab = (autovac_table *) palloc(sizeof(autovac_table)); + tab->relid = relid; + tab->toastrelid = classForm->reltoastrelid; + tab->dovacuum = dovacuum; + tab->doanalyze = doanalyze; + tab->vacuum_cost_limit = vac_cost_limit; + tab->vacuum_cost_delay = vac_cost_delay; - *vacuum_tables = lappend(*vacuum_tables, tab); + *vacuum_tables = lappend(*vacuum_tables, tab); + } + } + else + { + Assert(classForm->relkind == RELKIND_TOASTVALUE); + if (dovacuum) + *toast_table_ids = lappend_oid(*toast_table_ids, relid); } RelationClose(rel); diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index bbb1027fa2..0d1128d74e 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -13,7 +13,7 @@ * * Copyright (c) 2001-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.105 2005/08/11 21:11:44 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.106 2005/08/15 16:25:17 tgl Exp $ * ---------- */ #include "postgres.h" @@ -651,10 +651,12 @@ pgstat_beterm(int pid) * pgstat_report_autovac() - * * Called from autovacuum.c to report startup of an autovacuum process. + * We are called before InitPostgres is done, so can't rely on MyDatabaseId; + * the db OID must be passed in, instead. * ---------- */ void -pgstat_report_autovac(void) +pgstat_report_autovac(Oid dboid) { PgStat_MsgAutovacStart msg; @@ -662,7 +664,7 @@ pgstat_report_autovac(void) return; pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_AUTOVAC_START); - msg.m_databaseid = MyDatabaseId; + msg.m_databaseid = dboid; msg.m_start_time = GetCurrentTimestamp(); pgstat_send(&msg, sizeof(msg)); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 069a236ddb..abbcc2522c 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.298 2005/08/13 19:02:34 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.299 2005/08/15 16:25:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200508131 +#define CATALOG_VERSION_NO 200508151 #endif diff --git a/src/include/pgstat.h b/src/include/pgstat.h index f747928a22..5118fbc51d 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -5,7 +5,7 @@ * * Copyright (c) 2001-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.35 2005/08/11 21:11:49 tgl Exp $ + * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.36 2005/08/15 16:25:18 tgl Exp $ * ---------- */ #ifndef PGSTAT_H @@ -384,7 +384,7 @@ extern void pgstat_bestart(void); extern void pgstat_ping(void); extern void pgstat_report_activity(const char *what); extern void pgstat_report_tabstat(void); -extern void pgstat_report_autovac(void); +extern void pgstat_report_autovac(Oid dboid); extern void pgstat_report_vacuum(Oid tableoid, bool shared, bool analyze, PgStat_Counter tuples); extern void pgstat_report_analyze(Oid tableoid, bool shared, diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 55b0653a3b..756a716eca 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1286,16 +1286,16 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem pg_settings | SELECT a.name, a.setting, a.category, a.short_desc, a.extra_desc, a.context, a.vartype, a.source, a.min_val, a.max_val FROM pg_show_all_settings() a(name text, setting text, category text, short_desc text, extra_desc text, context text, vartype text, source text, min_val text, max_val text); pg_shadow | SELECT pg_authid.rolname AS usename, pg_authid.oid AS usesysid, pg_authid.rolcreatedb AS usecreatedb, pg_authid.rolsuper AS usesuper, pg_authid.rolcatupdate AS usecatupd, pg_authid.rolpassword AS passwd, (pg_authid.rolvaliduntil)::abstime AS valuntil, pg_authid.rolconfig AS useconfig FROM pg_authid WHERE pg_authid.rolcanlogin; pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.rolname AS usename, pg_stat_get_backend_activity(s.backendid) AS current_query, pg_stat_get_backend_activity_start(s.backendid) AS query_start, pg_stat_get_backend_start(s.backendid) AS backend_start, pg_stat_get_backend_client_addr(s.backendid) AS client_addr, pg_stat_get_backend_client_port(s.backendid) AS client_port FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_authid u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.oid)); - pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char"); - pg_stat_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, sum(pg_stat_get_numscans(i.indexrelid)) AS idx_scan, sum(pg_stat_get_tuples_fetched(i.indexrelid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char") GROUP BY c.oid, n.nspname, c.relname; + pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 't'::"char")); + pg_stat_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, sum(pg_stat_get_numscans(i.indexrelid)) AS idx_scan, sum(pg_stat_get_tuples_fetched(i.indexrelid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 't'::"char")) GROUP BY c.oid, n.nspname, c.relname; pg_stat_database | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit FROM pg_database d; pg_stat_sys_indexes | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (((pg_stat_all_indexes.schemaname = 'pg_catalog'::name) OR (pg_stat_all_indexes.schemaname = 'pg_toast'::name)) OR (pg_stat_all_indexes.schemaname = 'information_schema'::name)); pg_stat_sys_tables | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE (((pg_stat_all_tables.schemaname = 'pg_catalog'::name) OR (pg_stat_all_tables.schemaname = 'pg_toast'::name)) OR (pg_stat_all_tables.schemaname = 'information_schema'::name)); pg_stat_user_indexes | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (((pg_stat_all_indexes.schemaname <> 'pg_catalog'::name) AND (pg_stat_all_indexes.schemaname <> 'pg_toast'::name)) AND (pg_stat_all_indexes.schemaname <> 'information_schema'::name)); pg_stat_user_tables | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE (((pg_stat_all_tables.schemaname <> 'pg_catalog'::name) AND (pg_stat_all_tables.schemaname <> 'pg_toast'::name)) AND (pg_stat_all_tables.schemaname <> 'information_schema'::name)); - pg_statio_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, (pg_stat_get_blocks_fetched(i.oid) - pg_stat_get_blocks_hit(i.oid)) AS idx_blks_read, pg_stat_get_blocks_hit(i.oid) AS idx_blks_hit FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char"); + pg_statio_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, (pg_stat_get_blocks_fetched(i.oid) - pg_stat_get_blocks_hit(i.oid)) AS idx_blks_read, pg_stat_get_blocks_hit(i.oid) AS idx_blks_hit FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 't'::"char")); pg_statio_all_sequences | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS blks_read, pg_stat_get_blocks_hit(c.oid) AS blks_hit FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'S'::"char"); - pg_statio_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS heap_blks_read, pg_stat_get_blocks_hit(c.oid) AS heap_blks_hit, sum((pg_stat_get_blocks_fetched(i.indexrelid) - pg_stat_get_blocks_hit(i.indexrelid))) AS idx_blks_read, sum(pg_stat_get_blocks_hit(i.indexrelid)) AS idx_blks_hit, (pg_stat_get_blocks_fetched(t.oid) - pg_stat_get_blocks_hit(t.oid)) AS toast_blks_read, pg_stat_get_blocks_hit(t.oid) AS toast_blks_hit, (pg_stat_get_blocks_fetched(x.oid) - pg_stat_get_blocks_hit(x.oid)) AS tidx_blks_read, pg_stat_get_blocks_hit(x.oid) AS tidx_blks_hit FROM ((((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_class t ON ((c.reltoastrelid = t.oid))) LEFT JOIN pg_class x ON ((t.reltoastidxid = x.oid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char") GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid; + pg_statio_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS heap_blks_read, pg_stat_get_blocks_hit(c.oid) AS heap_blks_hit, sum((pg_stat_get_blocks_fetched(i.indexrelid) - pg_stat_get_blocks_hit(i.indexrelid))) AS idx_blks_read, sum(pg_stat_get_blocks_hit(i.indexrelid)) AS idx_blks_hit, (pg_stat_get_blocks_fetched(t.oid) - pg_stat_get_blocks_hit(t.oid)) AS toast_blks_read, pg_stat_get_blocks_hit(t.oid) AS toast_blks_hit, (pg_stat_get_blocks_fetched(x.oid) - pg_stat_get_blocks_hit(x.oid)) AS tidx_blks_read, pg_stat_get_blocks_hit(x.oid) AS tidx_blks_hit FROM ((((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_class t ON ((c.reltoastrelid = t.oid))) LEFT JOIN pg_class x ON ((t.reltoastidxid = x.oid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 't'::"char")) GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid; pg_statio_sys_indexes | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (((pg_statio_all_indexes.schemaname = 'pg_catalog'::name) OR (pg_statio_all_indexes.schemaname = 'pg_toast'::name)) OR (pg_statio_all_indexes.schemaname = 'information_schema'::name)); pg_statio_sys_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (((pg_statio_all_sequences.schemaname = 'pg_catalog'::name) OR (pg_statio_all_sequences.schemaname = 'pg_toast'::name)) OR (pg_statio_all_sequences.schemaname = 'information_schema'::name)); pg_statio_sys_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (((pg_statio_all_tables.schemaname = 'pg_catalog'::name) OR (pg_statio_all_tables.schemaname = 'pg_toast'::name)) OR (pg_statio_all_tables.schemaname = 'information_schema'::name));