Hi hackers,
I think having number of index scans of the last vacuum in pg_stat_all_tables can be helpful. This value shows how efficiently vacuums have performed and can be an indicator to increase maintenance_work_mem.
It was proposed previously[1], but it was not accepted due to the limitation of stats collector. Statistics are now stored in shared memory, so we got more rooms to store statistics. I think this statistics is still valuable for some people, so I am proposing this again.
Best wishes, -- Ken Kato Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION[1] https://www.postgresql.org/message-id/20171010.192616.108347483.horiguchi.kyotaro%40lab.ntt.co.jp
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 4549c2560e..bd7bfa7d9d 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -4557,6 +4557,16 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i daemon </para></entry> </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>last_vacuum_index_scans</structfield> <type>bigint</type> + </para> + <para> + Number of splitted index scans performed during the the last vacuum + on this table + </para> + </row> </tbody> </tgroup> </table> diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index b802ed247e..bf47d6837d 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -625,7 +625,8 @@ heap_vacuum_rel(Relation rel, VacuumParams *params, rel->rd_rel->relisshared, Max(vacrel->new_live_tuples, 0), vacrel->recently_dead_tuples + - vacrel->missed_dead_tuples); + vacrel->missed_dead_tuples, + vacrel->num_index_scans); pgstat_progress_end_command(); if (instrument) diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index fedaed533b..475551d9b3 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -676,7 +676,9 @@ CREATE VIEW pg_stat_all_tables AS pg_stat_get_vacuum_count(C.oid) AS vacuum_count, pg_stat_get_autovacuum_count(C.oid) AS autovacuum_count, pg_stat_get_analyze_count(C.oid) AS analyze_count, - pg_stat_get_autoanalyze_count(C.oid) AS autoanalyze_count + pg_stat_get_autoanalyze_count(C.oid) AS autoanalyze_count, + pg_stat_get_last_vacuum_index_scans(C.oid) AS last_vacuum_index_scans + FROM pg_class C LEFT JOIN pg_index I ON C.oid = I.indrelid LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) diff --git a/src/backend/utils/activity/pgstat_relation.c b/src/backend/utils/activity/pgstat_relation.c index a846d9ffb6..ffc9daf944 100644 --- a/src/backend/utils/activity/pgstat_relation.c +++ b/src/backend/utils/activity/pgstat_relation.c @@ -208,8 +208,8 @@ pgstat_drop_relation(Relation rel) * Report that the table was just vacuumed. */ void -pgstat_report_vacuum(Oid tableoid, bool shared, - PgStat_Counter livetuples, PgStat_Counter deadtuples) +pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter livetuples, + PgStat_Counter deadtuples, PgStat_Counter num_index_scans) { PgStat_EntryRef *entry_ref; PgStatShared_Relation *shtabentry; @@ -232,6 +232,7 @@ pgstat_report_vacuum(Oid tableoid, bool shared, tabentry->n_live_tuples = livetuples; tabentry->n_dead_tuples = deadtuples; + tabentry->n_index_scans = num_index_scans; /* * It is quite possible that a non-aggressive VACUUM ended up skipping diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 893690dad5..57d1de52e6 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -179,6 +179,20 @@ pg_stat_get_dead_tuples(PG_FUNCTION_ARGS) PG_RETURN_INT64(result); } +Datum +pg_stat_get_last_vacuum_index_scans(PG_FUNCTION_ARGS) +{ + Oid relid = PG_GETARG_OID(0); + int64 result; + PgStat_StatTabEntry *tabentry; + + if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) + result = 0; + else + result = tabentry->n_index_scans; + + PG_RETURN_INT64(result); +} Datum pg_stat_get_mod_since_analyze(PG_FUNCTION_ARGS) diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index a77b293723..d061cd2d8d 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5331,6 +5331,10 @@ proname => 'pg_stat_get_autoanalyze_count', provolatile => 's', proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', prosrc => 'pg_stat_get_autoanalyze_count' }, +{ oid => '3813', descr => 'statistics: last vacuum index scans for a table', + proname => 'pg_stat_get_last_vacuum_index_scans', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_last_vacuum_index_scans' }, { oid => '1936', descr => 'statistics: currently active backend IDs', proname => 'pg_stat_get_backend_idset', prorows => '100', proretset => 't', provolatile => 's', proparallel => 'r', prorettype => 'int4', diff --git a/src/include/pgstat.h b/src/include/pgstat.h index ac28f813b4..89989c8c19 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -366,6 +366,7 @@ typedef struct PgStat_StatTabEntry PgStat_Counter n_live_tuples; PgStat_Counter n_dead_tuples; + PgStat_Counter n_index_scans; PgStat_Counter changes_since_analyze; PgStat_Counter inserts_since_vacuum; @@ -506,7 +507,9 @@ extern void pgstat_assoc_relation(Relation rel); extern void pgstat_unlink_relation(Relation rel); extern void pgstat_report_vacuum(Oid tableoid, bool shared, - PgStat_Counter livetuples, PgStat_Counter deadtuples); + PgStat_Counter livetuples, + PgStat_Counter deadtuples, + PgStat_Counter num_index_scans); extern void pgstat_report_analyze(Relation rel, PgStat_Counter livetuples, PgStat_Counter deadtuples, bool resetcounter); diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index fc3cde3226..e93445378c 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1796,7 +1796,8 @@ pg_stat_all_tables| SELECT c.oid AS relid, pg_stat_get_vacuum_count(c.oid) AS vacuum_count, pg_stat_get_autovacuum_count(c.oid) AS autovacuum_count, pg_stat_get_analyze_count(c.oid) AS analyze_count, - pg_stat_get_autoanalyze_count(c.oid) AS autoanalyze_count + pg_stat_get_autoanalyze_count(c.oid) AS autoanalyze_count, + pg_stat_get_last_vacuum_index_scans(C.oid) AS last_vacuum_index_scans FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) @@ -2137,7 +2138,8 @@ pg_stat_sys_tables| SELECT pg_stat_all_tables.relid, pg_stat_all_tables.vacuum_count, pg_stat_all_tables.autovacuum_count, pg_stat_all_tables.analyze_count, - pg_stat_all_tables.autoanalyze_count + pg_stat_all_tables.autoanalyze_count, + pg_stat_all_tables.last_vacuum_index_scans FROM pg_stat_all_tables WHERE ((pg_stat_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'information_schema'::name])) OR (pg_stat_all_tables.schemaname ~ '^pg_toast'::text)); pg_stat_user_functions| SELECT p.oid AS funcid, @@ -2181,7 +2183,8 @@ pg_stat_user_tables| SELECT pg_stat_all_tables.relid, pg_stat_all_tables.vacuum_count, pg_stat_all_tables.autovacuum_count, pg_stat_all_tables.analyze_count, - pg_stat_all_tables.autoanalyze_count + pg_stat_all_tables.autoanalyze_count, + pg_stat_all_tables.last_vacuum_index_scans FROM pg_stat_all_tables WHERE ((pg_stat_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_stat_all_tables.schemaname !~ '^pg_toast'::text)); pg_stat_wal| SELECT w.wal_records,