Skip to content

Commit

Permalink
Report index vacuum progress.
Browse files Browse the repository at this point in the history
This commit adds two columns: indexes_total and indexes_processed, to
pg_stat_progress_vacuum system view to show the index vacuum
progress. These numbers are reported in the "vacuuming indexes" and
"cleaning up indexes" phases.

This uses the new parallel message type for progress reporting added
by be06506e7.

Bump catversion because this changes the definition of
pg_stat_progress_vacuum.

Author: Sami Imseih
Reviewed by: Masahiko Sawada, Michael Paquier, Nathan Bossart, Andres Freund
Discussion: https://www.postgresql.org/message-id/flat/5478DFCD-2333-401A-B2F0-0D186AB09228@amazon.com
  • Loading branch information
MasahikoSawada committed Jul 11, 2023
1 parent f188972 commit 46ebdfe
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 13 deletions.
23 changes: 23 additions & 0 deletions doc/src/sgml/monitoring.sgml
Expand Up @@ -6110,6 +6110,29 @@ FROM pg_stat_get_backend_idset() AS backendid;
Number of dead tuples collected since the last index vacuum cycle.
</para></entry>
</row>

<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>indexes_total</structfield> <type>bigint</type>
</para>
<para>
Total number of indexes that will be vacuumed or cleaned up. This
number is reported at the beginning of the
<literal>vacuuming indexes</literal> phase or the
<literal>cleaning up indexes</literal> phase.
</para></entry>
</row>

<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>indexes_processed</structfield> <type>bigint</type>
</para>
<para>
Number of indexes processed. This counter only advances when the
phase is <literal>vacuuming indexes</literal> or
<literal>cleaning up indexes</literal>.
</para></entry>
</row>
</tbody>
</tgroup>
</table>
Expand Down
70 changes: 61 additions & 9 deletions src/backend/access/heap/vacuumlazy.c
Expand Up @@ -2319,6 +2319,17 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
{
bool allindexes = true;
double old_live_tuples = vacrel->rel->rd_rel->reltuples;
const int progress_start_index[] = {
PROGRESS_VACUUM_PHASE,
PROGRESS_VACUUM_INDEXES_TOTAL
};
const int progress_end_index[] = {
PROGRESS_VACUUM_INDEXES_TOTAL,
PROGRESS_VACUUM_INDEXES_PROCESSED,
PROGRESS_VACUUM_NUM_INDEX_VACUUMS
};
int64 progress_start_val[2];
int64 progress_end_val[3];

Assert(vacrel->nindexes > 0);
Assert(vacrel->do_index_vacuuming);
Expand All @@ -2331,9 +2342,13 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
return false;
}

/* Report that we are now vacuuming indexes */
pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
PROGRESS_VACUUM_PHASE_VACUUM_INDEX);
/*
* Report that we are now vacuuming indexes and the number of indexes to
* vacuum.
*/
progress_start_val[0] = PROGRESS_VACUUM_PHASE_VACUUM_INDEX;
progress_start_val[1] = vacrel->nindexes;
pgstat_progress_update_multi_param(2, progress_start_index, progress_start_val);

if (!ParallelVacuumIsActive(vacrel))
{
Expand All @@ -2346,6 +2361,10 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
old_live_tuples,
vacrel);

/* Report the number of indexes vacuumed */
pgstat_progress_update_param(PROGRESS_VACUUM_INDEXES_PROCESSED,
idx + 1);

if (lazy_check_wraparound_failsafe(vacrel))
{
/* Wraparound emergency -- end current index scan */
Expand Down Expand Up @@ -2380,14 +2399,17 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
Assert(allindexes || VacuumFailsafeActive);

/*
* Increase and report the number of index scans.
* Increase and report the number of index scans. Also, we reset
* PROGRESS_VACUUM_INDEXES_TOTAL and PROGRESS_VACUUM_INDEXES_PROCESSED.
*
* We deliberately include the case where we started a round of bulk
* deletes that we weren't able to finish due to the failsafe triggering.
*/
vacrel->num_index_scans++;
pgstat_progress_update_param(PROGRESS_VACUUM_NUM_INDEX_VACUUMS,
vacrel->num_index_scans);
progress_end_val[0] = 0;
progress_end_val[1] = 0;
progress_end_val[2] = vacrel->num_index_scans;
pgstat_progress_update_multi_param(3, progress_end_index, progress_end_val);

return allindexes;
}
Expand Down Expand Up @@ -2624,6 +2646,12 @@ lazy_check_wraparound_failsafe(LVRelState *vacrel)

if (unlikely(vacuum_xid_failsafe_check(&vacrel->cutoffs)))
{
const int progress_index[] = {
PROGRESS_VACUUM_INDEXES_TOTAL,
PROGRESS_VACUUM_INDEXES_PROCESSED
};
int64 progress_val[2] = {0, 0};

VacuumFailsafeActive = true;

/*
Expand All @@ -2638,6 +2666,9 @@ lazy_check_wraparound_failsafe(LVRelState *vacrel)
vacrel->do_index_cleanup = false;
vacrel->do_rel_truncate = false;

/* Reset the progress counters */
pgstat_progress_update_multi_param(2, progress_index, progress_val);

ereport(WARNING,
(errmsg("bypassing nonessential maintenance of table \"%s.%s.%s\" as a failsafe after %d index scans",
vacrel->dbname, vacrel->relnamespace, vacrel->relname,
Expand All @@ -2664,13 +2695,27 @@ lazy_cleanup_all_indexes(LVRelState *vacrel)
{
double reltuples = vacrel->new_rel_tuples;
bool estimated_count = vacrel->scanned_pages < vacrel->rel_pages;
const int progress_start_index[] = {
PROGRESS_VACUUM_PHASE,
PROGRESS_VACUUM_INDEXES_TOTAL
};
const int progress_end_index[] = {
PROGRESS_VACUUM_INDEXES_TOTAL,
PROGRESS_VACUUM_INDEXES_PROCESSED
};
int64 progress_start_val[2];
int64 progress_end_val[2] = {0, 0};

Assert(vacrel->do_index_cleanup);
Assert(vacrel->nindexes > 0);

/* Report that we are now cleaning up indexes */
pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
PROGRESS_VACUUM_PHASE_INDEX_CLEANUP);
/*
* Report that we are now cleaning up indexes and the number of indexes to
* cleanup.
*/
progress_start_val[0] = PROGRESS_VACUUM_PHASE_INDEX_CLEANUP;
progress_start_val[1] = vacrel->nindexes;
pgstat_progress_update_multi_param(2, progress_start_index, progress_start_val);

if (!ParallelVacuumIsActive(vacrel))
{
Expand All @@ -2682,6 +2727,10 @@ lazy_cleanup_all_indexes(LVRelState *vacrel)
vacrel->indstats[idx] =
lazy_cleanup_one_index(indrel, istat, reltuples,
estimated_count, vacrel);

/* Report the number of indexes cleaned up */
pgstat_progress_update_param(PROGRESS_VACUUM_INDEXES_PROCESSED,
idx + 1);
}
}
else
Expand All @@ -2691,6 +2740,9 @@ lazy_cleanup_all_indexes(LVRelState *vacrel)
vacrel->num_index_scans,
estimated_count);
}

/* Reset the progress counters */
pgstat_progress_update_multi_param(2, progress_end_index, progress_end_val);
}

/*
Expand Down
3 changes: 2 additions & 1 deletion src/backend/catalog/system_views.sql
Expand Up @@ -1192,7 +1192,8 @@ CREATE VIEW pg_stat_progress_vacuum AS
END AS phase,
S.param2 AS heap_blks_total, S.param3 AS heap_blks_scanned,
S.param4 AS heap_blks_vacuumed, S.param5 AS index_vacuum_count,
S.param6 AS max_dead_tuples, S.param7 AS num_dead_tuples
S.param6 AS max_dead_tuples, S.param7 AS num_dead_tuples,
S.param8 AS indexes_total, S.param9 AS indexes_processed
FROM pg_stat_get_progress_info('VACUUM') AS S
LEFT JOIN pg_database D ON S.datid = D.oid;

Expand Down
9 changes: 8 additions & 1 deletion src/backend/commands/vacuumparallel.c
Expand Up @@ -30,6 +30,7 @@
#include "access/table.h"
#include "access/xact.h"
#include "catalog/index.h"
#include "commands/progress.h"
#include "commands/vacuum.h"
#include "optimizer/paths.h"
#include "pgstat.h"
Expand Down Expand Up @@ -631,7 +632,7 @@ parallel_vacuum_process_all_indexes(ParallelVacuumState *pvs, int num_index_scan
vacuum));
}

/* Reset the parallel index processing counter */
/* Reset the parallel index processing and progress counters */
pg_atomic_write_u32(&(pvs->shared->idx), 0);

/* Setup the shared cost-based vacuum delay and launch workers */
Expand Down Expand Up @@ -902,6 +903,12 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel,
pvs->status = PARALLEL_INDVAC_STATUS_COMPLETED;
pfree(pvs->indname);
pvs->indname = NULL;

/*
* Call the parallel variant of pgstat_progress_incr_param so workers can
* report progress of index vacuum to the leader.
*/
pgstat_progress_parallel_incr_param(PROGRESS_VACUUM_INDEXES_PROCESSED, 1);
}

/*
Expand Down
2 changes: 1 addition & 1 deletion src/include/catalog/catversion.h
Expand Up @@ -57,6 +57,6 @@
*/

/* yyyymmddN */
#define CATALOG_VERSION_NO 202307072
#define CATALOG_VERSION_NO 202307111

#endif
2 changes: 2 additions & 0 deletions src/include/commands/progress.h
Expand Up @@ -25,6 +25,8 @@
#define PROGRESS_VACUUM_NUM_INDEX_VACUUMS 4
#define PROGRESS_VACUUM_MAX_DEAD_TUPLES 5
#define PROGRESS_VACUUM_NUM_DEAD_TUPLES 6
#define PROGRESS_VACUUM_INDEXES_TOTAL 7
#define PROGRESS_VACUUM_INDEXES_PROCESSED 8

/* Phases of vacuum (as advertised via PROGRESS_VACUUM_PHASE) */
#define PROGRESS_VACUUM_PHASE_SCAN_HEAP 1
Expand Down
4 changes: 3 additions & 1 deletion src/test/regress/expected/rules.out
Expand Up @@ -2044,7 +2044,9 @@ pg_stat_progress_vacuum| SELECT s.pid,
s.param4 AS heap_blks_vacuumed,
s.param5 AS index_vacuum_count,
s.param6 AS max_dead_tuples,
s.param7 AS num_dead_tuples
s.param7 AS num_dead_tuples,
s.param8 AS indexes_total,
s.param9 AS indexes_processed
FROM (pg_stat_get_progress_info('VACUUM'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, param17, param18, param19, param20)
LEFT JOIN pg_database d ON ((s.datid = d.oid)));
pg_stat_recovery_prefetch| SELECT stats_reset,
Expand Down

0 comments on commit 46ebdfe

Please sign in to comment.