diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c index 6688ab3..d60431d 100644 --- a/src/backend/commands/vacuumlazy.c +++ b/src/backend/commands/vacuumlazy.c @@ -186,6 +186,11 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt, BlockNumber new_rel_allvisible; TransactionId new_frozen_xid; MultiXactId new_min_multi; + PgStat_StatTabEntry *tabentry = NULL; + int64 dead_tuples = 0; + int64 new_dead_tuples = 0; + + /* measure elapsed time iff autovacuum logging requires it */ if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0) @@ -216,6 +221,16 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt, vacrelstats->pages_removed = 0; vacrelstats->lock_waiter_detected = false; + /* + * Get the data in the table's hashtable entry. + */ + if (IsUnderPostmaster) + { + tabentry = pgstat_fetch_stat_tabentry(RelationGetRelid(onerel)); + if (tabentry != NULL) + dead_tuples = tabentry->n_dead_tuples; + } + /* Open all indexes of the relation */ vac_open_indexes(onerel, RowExclusiveLock, &nindexes, &Irel); vacrelstats->hasindex = (nindexes > 0); @@ -296,10 +311,21 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt, new_frozen_xid, new_min_multi); + /* calculate the number of new dead tuples */ + if (IsUnderPostmaster) + { + /* clear and get the new stats for calculating proper dead tuples */ + pgstat_clear_snapshot(); + tabentry = pgstat_fetch_stat_tabentry(RelationGetRelid(onerel)); + if (tabentry != NULL) + new_dead_tuples = tabentry->n_dead_tuples - dead_tuples; + } + /* report results to the stats collector, too */ pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared, - new_rel_tuples); + new_rel_tuples, + new_dead_tuples); /* and log the action if appropriate */ if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0) diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index b5ce2f6..2434b1f 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -1317,7 +1317,8 @@ pgstat_report_autovac(Oid dboid) * --------- */ void -pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter tuples) +pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter tuples, + PgStat_Counter dead_tuples) { PgStat_MsgVacuum msg; @@ -1330,6 +1331,7 @@ pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter tuples) msg.m_autovacuum = IsAutoVacuumWorkerProcess(); msg.m_vacuumtime = GetCurrentTimestamp(); msg.m_tuples = tuples; + msg.m_dead_tuples = dead_tuples; pgstat_send(&msg, sizeof(msg)); } @@ -4800,8 +4802,7 @@ pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len) tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true); tabentry->n_live_tuples = msg->m_tuples; - /* Resetting dead_tuples to 0 is an approximation ... */ - tabentry->n_dead_tuples = 0; + tabentry->n_dead_tuples = msg->m_dead_tuples; if (msg->m_autovacuum) { diff --git a/src/include/pgstat.h b/src/include/pgstat.h index fb242e4..1d714a2 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -332,6 +332,7 @@ typedef struct PgStat_MsgVacuum bool m_autovacuum; TimestampTz m_vacuumtime; PgStat_Counter m_tuples; + PgStat_Counter m_dead_tuples; } PgStat_MsgVacuum; @@ -773,7 +774,7 @@ extern void pgstat_reset_single_counter(Oid objectid, PgStat_Single_Reset_Type t extern void pgstat_report_autovac(Oid dboid); extern void pgstat_report_vacuum(Oid tableoid, bool shared, - PgStat_Counter tuples); + PgStat_Counter tuples, PgStat_Counter dead_tuples); extern void pgstat_report_analyze(Relation rel, PgStat_Counter livetuples, PgStat_Counter deadtuples);