Commit b4b6923e authored by Tom Lane's avatar Tom Lane

Fix VACUUM so that it always updates pg_class.reltuples/relpages.

When we added the ability for vacuum to skip heap pages by consulting the
visibility map, we made it just not update the reltuples/relpages
statistics if it skipped any pages.  But this could leave us with extremely
out-of-date stats for a table that contains any unchanging areas,
especially for TOAST tables which never get processed by ANALYZE.  In
particular this could result in autovacuum making poor decisions about when
to process the table, as in recent report from Florian Helmberger.  And in
general it's a bad idea to not update the stats at all.  Instead, use the
previous values of reltuples/relpages as an estimate of the tuple density
in unvisited pages.  This approach results in a "moving average" estimate
of reltuples, which should converge to the correct value over multiple
VACUUM and ANALYZE cycles even when individual measurements aren't very
good.

This new method for updating reltuples is used by both VACUUM and ANALYZE,
with the result that we no longer need the grotty interconnections that
caused ANALYZE to not update the stats depending on what had happened
in the parent VACUUM command.

Also, fix the logic for skipping all-visible pages during VACUUM so that it
looks ahead rather than behind to decide what to do, as per a suggestion
from Greg Stark.  This eliminates useless scanning of all-visible pages at
the start of the relation or just after a not-all-visible page.  In
particular, the first few pages of the relation will not be invariably
included in the scanned pages, which seems to help in not overweighting
them in the reltuples estimate.

Back-patch to 8.4, where the visibility map was introduced.
parent 3001b763
...@@ -84,8 +84,7 @@ static MemoryContext anl_context = NULL; ...@@ -84,8 +84,7 @@ static MemoryContext anl_context = NULL;
static BufferAccessStrategy vac_strategy; static BufferAccessStrategy vac_strategy;
static void do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, static void do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, bool inh);
bool update_reltuples, bool inh);
static void BlockSampler_Init(BlockSampler bs, BlockNumber nblocks, static void BlockSampler_Init(BlockSampler bs, BlockNumber nblocks,
int samplesize); int samplesize);
static bool BlockSampler_HasMore(BlockSampler bs); static bool BlockSampler_HasMore(BlockSampler bs);
...@@ -115,18 +114,9 @@ static bool std_typanalyze(VacAttrStats *stats); ...@@ -115,18 +114,9 @@ static bool std_typanalyze(VacAttrStats *stats);
/* /*
* analyze_rel() -- analyze one relation * analyze_rel() -- analyze one relation
*
* If update_reltuples is true, we update reltuples and relpages columns
* in pg_class. Caller should pass false if we're part of VACUUM ANALYZE,
* and the VACUUM didn't skip any pages. We only have an approximate count,
* so we don't want to overwrite the accurate values already inserted by the
* VACUUM in that case. VACUUM always scans all indexes, however, so the
* pg_class entries for indexes are never updated if we're part of VACUUM
* ANALYZE.
*/ */
void void
analyze_rel(Oid relid, VacuumStmt *vacstmt, analyze_rel(Oid relid, VacuumStmt *vacstmt, BufferAccessStrategy bstrategy)
BufferAccessStrategy bstrategy, bool update_reltuples)
{ {
Relation onerel; Relation onerel;
...@@ -238,13 +228,13 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt, ...@@ -238,13 +228,13 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
/* /*
* Do the normal non-recursive ANALYZE. * Do the normal non-recursive ANALYZE.
*/ */
do_analyze_rel(onerel, vacstmt, update_reltuples, false); do_analyze_rel(onerel, vacstmt, false);
/* /*
* If there are child tables, do recursive ANALYZE. * If there are child tables, do recursive ANALYZE.
*/ */
if (onerel->rd_rel->relhassubclass) if (onerel->rd_rel->relhassubclass)
do_analyze_rel(onerel, vacstmt, false, true); do_analyze_rel(onerel, vacstmt, true);
/* /*
* Close source relation now, but keep lock so that no one deletes it * Close source relation now, but keep lock so that no one deletes it
...@@ -267,8 +257,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt, ...@@ -267,8 +257,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
* do_analyze_rel() -- analyze one relation, recursively or not * do_analyze_rel() -- analyze one relation, recursively or not
*/ */
static void static void
do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, bool inh)
bool update_reltuples, bool inh)
{ {
int attr_cnt, int attr_cnt,
tcnt, tcnt,
...@@ -437,9 +426,9 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, ...@@ -437,9 +426,9 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
} }
/* /*
* Quit if no analyzable columns and no pg_class update needed. * Quit if no analyzable columns.
*/ */
if (attr_cnt <= 0 && !analyzableindex && !update_reltuples) if (attr_cnt <= 0 && !analyzableindex)
goto cleanup; goto cleanup;
/* /*
...@@ -549,10 +538,10 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, ...@@ -549,10 +538,10 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
} }
/* /*
* Update pages/tuples stats in pg_class, but not if we're inside a VACUUM * Update pages/tuples stats in pg_class ... but not if we're doing
* that got a more precise number. * inherited stats.
*/ */
if (update_reltuples) if (!inh)
vac_update_relstats(onerel, vac_update_relstats(onerel,
RelationGetNumberOfBlocks(onerel), RelationGetNumberOfBlocks(onerel),
totalrows, hasindex, InvalidTransactionId); totalrows, hasindex, InvalidTransactionId);
...@@ -562,7 +551,7 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, ...@@ -562,7 +551,7 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
* VACUUM ANALYZE, don't overwrite the accurate count already inserted by * VACUUM ANALYZE, don't overwrite the accurate count already inserted by
* VACUUM. * VACUUM.
*/ */
if (!(vacstmt->options & VACOPT_VACUUM)) if (!inh && !(vacstmt->options & VACOPT_VACUUM))
{ {
for (ind = 0; ind < nindexes; ind++) for (ind = 0; ind < nindexes; ind++)
{ {
...@@ -577,13 +566,12 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, ...@@ -577,13 +566,12 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
} }
/* /*
* Report ANALYZE to the stats collector, too; likewise, tell it to adopt * Report ANALYZE to the stats collector, too. However, if doing
* these numbers only if we're not inside a VACUUM that got a better * inherited stats we shouldn't report, because the stats collector only
* number. However, a call with inh = true shouldn't reset the stats. * tracks per-table stats.
*/ */
if (!inh) if (!inh)
pgstat_report_analyze(onerel, update_reltuples, pgstat_report_analyze(onerel, totalrows, totaldeadrows);
totalrows, totaldeadrows);
/* We skip to here if there were no analyzable columns */ /* We skip to here if there were no analyzable columns */
cleanup: cleanup:
...@@ -1243,18 +1231,19 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows, ...@@ -1243,18 +1231,19 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
qsort((void *) rows, numrows, sizeof(HeapTuple), compare_rows); qsort((void *) rows, numrows, sizeof(HeapTuple), compare_rows);
/* /*
* Estimate total numbers of rows in relation. * Estimate total numbers of rows in relation. For live rows, use
* vac_estimate_reltuples; for dead rows, we have no source of old
* information, so we have to assume the density is the same in unseen
* pages as in the pages we scanned.
*/ */
*totalrows = vac_estimate_reltuples(onerel, true,
totalblocks,
bs.m,
liverows);
if (bs.m > 0) if (bs.m > 0)
{ *totaldeadrows = floor((deadrows / bs.m) * totalblocks + 0.5);
*totalrows = floor((liverows * totalblocks) / bs.m + 0.5);
*totaldeadrows = floor((deadrows * totalblocks) / bs.m + 0.5);
}
else else
{
*totalrows = 0.0;
*totaldeadrows = 0.0; *totaldeadrows = 0.0;
}
/* /*
* Emit some interesting relation info * Emit some interesting relation info
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
*/ */
#include "postgres.h" #include "postgres.h"
#include <math.h>
#include "access/clog.h" #include "access/clog.h"
#include "access/genam.h" #include "access/genam.h"
#include "access/heapam.h" #include "access/heapam.h"
...@@ -62,7 +64,7 @@ static BufferAccessStrategy vac_strategy; ...@@ -62,7 +64,7 @@ static BufferAccessStrategy vac_strategy;
static List *get_rel_oids(Oid relid, const RangeVar *vacrel); static List *get_rel_oids(Oid relid, const RangeVar *vacrel);
static void vac_truncate_clog(TransactionId frozenXID); static void vac_truncate_clog(TransactionId frozenXID);
static bool vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, static bool vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast,
bool for_wraparound, bool *scanned_all); bool for_wraparound);
/* /*
...@@ -219,12 +221,10 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast, ...@@ -219,12 +221,10 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
foreach(cur, relations) foreach(cur, relations)
{ {
Oid relid = lfirst_oid(cur); Oid relid = lfirst_oid(cur);
bool scanned_all = false;
if (vacstmt->options & VACOPT_VACUUM) if (vacstmt->options & VACOPT_VACUUM)
{ {
if (!vacuum_rel(relid, vacstmt, do_toast, for_wraparound, if (!vacuum_rel(relid, vacstmt, do_toast, for_wraparound))
&scanned_all))
continue; continue;
} }
...@@ -241,7 +241,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast, ...@@ -241,7 +241,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
PushActiveSnapshot(GetTransactionSnapshot()); PushActiveSnapshot(GetTransactionSnapshot());
} }
analyze_rel(relid, vacstmt, vac_strategy, !scanned_all); analyze_rel(relid, vacstmt, vac_strategy);
if (use_own_xacts) if (use_own_xacts)
{ {
...@@ -453,6 +453,79 @@ vacuum_set_xid_limits(int freeze_min_age, ...@@ -453,6 +453,79 @@ vacuum_set_xid_limits(int freeze_min_age,
} }
/*
* vac_estimate_reltuples() -- estimate the new value for pg_class.reltuples
*
* If we scanned the whole relation then we should just use the count of
* live tuples seen; but if we did not, we should not trust the count
* unreservedly, especially not in VACUUM, which may have scanned a quite
* nonrandom subset of the table. When we have only partial information,
* we take the old value of pg_class.reltuples as a measurement of the
* tuple density in the unscanned pages.
*
* This routine is shared by VACUUM and ANALYZE.
*/
double
vac_estimate_reltuples(Relation relation, bool is_analyze,
BlockNumber total_pages,
BlockNumber scanned_pages,
double scanned_tuples)
{
BlockNumber old_rel_pages = relation->rd_rel->relpages;
double old_rel_tuples = relation->rd_rel->reltuples;
double old_density;
double new_density;
double multiplier;
double updated_density;
/* If we did scan the whole table, just use the count as-is */
if (scanned_pages >= total_pages)
return scanned_tuples;
/*
* If scanned_pages is zero but total_pages isn't, keep the existing
* value of reltuples.
*/
if (scanned_pages == 0)
return old_rel_tuples;
/*
* If old value of relpages is zero, old density is indeterminate; we
* can't do much except scale up scanned_tuples to match total_pages.
*/
if (old_rel_pages == 0)
return floor((scanned_tuples / scanned_pages) * total_pages + 0.5);
/*
* Okay, we've covered the corner cases. The normal calculation is to
* convert the old measurement to a density (tuples per page), then
* update the density using an exponential-moving-average approach,
* and finally compute reltuples as updated_density * total_pages.
*
* For ANALYZE, the moving average multiplier is just the fraction of
* the table's pages we scanned. This is equivalent to assuming
* that the tuple density in the unscanned pages didn't change. Of
* course, it probably did, if the new density measurement is different.
* But over repeated cycles, the value of reltuples will converge towards
* the correct value, if repeated measurements show the same new density.
*
* For VACUUM, the situation is a bit different: we have looked at a
* nonrandom sample of pages, but we know for certain that the pages we
* didn't look at are precisely the ones that haven't changed lately.
* Thus, there is a reasonable argument for doing exactly the same thing
* as for the ANALYZE case, that is use the old density measurement as
* the value for the unscanned pages.
*
* This logic could probably use further refinement.
*/
old_density = old_rel_tuples / old_rel_pages;
new_density = scanned_tuples / scanned_pages;
multiplier = (double) scanned_pages / (double) total_pages;
updated_density = old_density + (new_density - old_density) * multiplier;
return floor(updated_density * total_pages + 0.5);
}
/* /*
* vac_update_relstats() -- update statistics for one relation * vac_update_relstats() -- update statistics for one relation
* *
...@@ -480,7 +553,7 @@ vacuum_set_xid_limits(int freeze_min_age, ...@@ -480,7 +553,7 @@ vacuum_set_xid_limits(int freeze_min_age,
* somebody vacuuming pg_class might think they could delete a tuple * somebody vacuuming pg_class might think they could delete a tuple
* marked with xmin = our xid. * marked with xmin = our xid.
* *
* This routine is shared by VACUUM and stand-alone ANALYZE. * This routine is shared by VACUUM and ANALYZE.
*/ */
void void
vac_update_relstats(Relation relation, vac_update_relstats(Relation relation,
...@@ -758,14 +831,10 @@ vac_truncate_clog(TransactionId frozenXID) ...@@ -758,14 +831,10 @@ vac_truncate_clog(TransactionId frozenXID)
* many small transactions. Otherwise, two-phase locking would require * many small transactions. Otherwise, two-phase locking would require
* us to lock the entire database during one pass of the vacuum cleaner. * us to lock the entire database during one pass of the vacuum cleaner.
* *
* We'll return true in *scanned_all if the vacuum scanned all heap
* pages, and updated pg_class.
*
* At entry and exit, we are not inside a transaction. * At entry and exit, we are not inside a transaction.
*/ */
static bool static bool
vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound, vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
bool *scanned_all)
{ {
LOCKMODE lmode; LOCKMODE lmode;
Relation onerel; Relation onerel;
...@@ -775,9 +844,6 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound, ...@@ -775,9 +844,6 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
int save_sec_context; int save_sec_context;
int save_nestlevel; int save_nestlevel;
if (scanned_all)
*scanned_all = false;
/* Begin a transaction for vacuuming this relation */ /* Begin a transaction for vacuuming this relation */
StartTransactionCommand(); StartTransactionCommand();
...@@ -971,7 +1037,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound, ...@@ -971,7 +1037,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
vacstmt->freeze_min_age, vacstmt->freeze_table_age); vacstmt->freeze_min_age, vacstmt->freeze_table_age);
} }
else else
lazy_vacuum_rel(onerel, vacstmt, vac_strategy, scanned_all); lazy_vacuum_rel(onerel, vacstmt, vac_strategy);
/* Roll back any GUC changes executed by index functions */ /* Roll back any GUC changes executed by index functions */
AtEOXact_GUC(false, save_nestlevel); AtEOXact_GUC(false, save_nestlevel);
...@@ -997,7 +1063,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound, ...@@ -997,7 +1063,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
* totally unimportant for toast relations. * totally unimportant for toast relations.
*/ */
if (toast_relid != InvalidOid) if (toast_relid != InvalidOid)
vacuum_rel(toast_relid, vacstmt, false, for_wraparound, NULL); vacuum_rel(toast_relid, vacstmt, false, for_wraparound);
/* /*
* Now release the session-level lock on the master table. * Now release the session-level lock on the master table.
......
This diff is collapsed.
...@@ -1246,8 +1246,7 @@ pgstat_report_autovac(Oid dboid) ...@@ -1246,8 +1246,7 @@ pgstat_report_autovac(Oid dboid)
* --------- * ---------
*/ */
void void
pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts, pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter tuples)
PgStat_Counter tuples)
{ {
PgStat_MsgVacuum msg; PgStat_MsgVacuum msg;
...@@ -1257,7 +1256,6 @@ pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts, ...@@ -1257,7 +1256,6 @@ pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts,
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_VACUUM); pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_VACUUM);
msg.m_databaseid = shared ? InvalidOid : MyDatabaseId; msg.m_databaseid = shared ? InvalidOid : MyDatabaseId;
msg.m_tableoid = tableoid; msg.m_tableoid = tableoid;
msg.m_adopt_counts = adopt_counts;
msg.m_autovacuum = IsAutoVacuumWorkerProcess(); msg.m_autovacuum = IsAutoVacuumWorkerProcess();
msg.m_vacuumtime = GetCurrentTimestamp(); msg.m_vacuumtime = GetCurrentTimestamp();
msg.m_tuples = tuples; msg.m_tuples = tuples;
...@@ -1271,7 +1269,7 @@ pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts, ...@@ -1271,7 +1269,7 @@ pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts,
* -------- * --------
*/ */
void void
pgstat_report_analyze(Relation rel, bool adopt_counts, pgstat_report_analyze(Relation rel,
PgStat_Counter livetuples, PgStat_Counter deadtuples) PgStat_Counter livetuples, PgStat_Counter deadtuples)
{ {
PgStat_MsgAnalyze msg; PgStat_MsgAnalyze msg;
...@@ -1308,7 +1306,6 @@ pgstat_report_analyze(Relation rel, bool adopt_counts, ...@@ -1308,7 +1306,6 @@ pgstat_report_analyze(Relation rel, bool adopt_counts,
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ANALYZE); pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ANALYZE);
msg.m_databaseid = rel->rd_rel->relisshared ? InvalidOid : MyDatabaseId; msg.m_databaseid = rel->rd_rel->relisshared ? InvalidOid : MyDatabaseId;
msg.m_tableoid = RelationGetRelid(rel); msg.m_tableoid = RelationGetRelid(rel);
msg.m_adopt_counts = adopt_counts;
msg.m_autovacuum = IsAutoVacuumWorkerProcess(); msg.m_autovacuum = IsAutoVacuumWorkerProcess();
msg.m_analyzetime = GetCurrentTimestamp(); msg.m_analyzetime = GetCurrentTimestamp();
msg.m_live_tuples = livetuples; msg.m_live_tuples = livetuples;
...@@ -4197,7 +4194,6 @@ pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len) ...@@ -4197,7 +4194,6 @@ pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len)
tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true); tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true);
if (msg->m_adopt_counts)
tabentry->n_live_tuples = msg->m_tuples; tabentry->n_live_tuples = msg->m_tuples;
/* Resetting dead_tuples to 0 is an approximation ... */ /* Resetting dead_tuples to 0 is an approximation ... */
tabentry->n_dead_tuples = 0; tabentry->n_dead_tuples = 0;
...@@ -4233,11 +4229,8 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len) ...@@ -4233,11 +4229,8 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len)
tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true); tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true);
if (msg->m_adopt_counts)
{
tabentry->n_live_tuples = msg->m_live_tuples; tabentry->n_live_tuples = msg->m_live_tuples;
tabentry->n_dead_tuples = msg->m_dead_tuples; tabentry->n_dead_tuples = msg->m_dead_tuples;
}
/* /*
* We reset changes_since_analyze to zero, forgetting any changes that * We reset changes_since_analyze to zero, forgetting any changes that
......
...@@ -142,6 +142,10 @@ extern void vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast, ...@@ -142,6 +142,10 @@ extern void vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
extern void vac_open_indexes(Relation relation, LOCKMODE lockmode, extern void vac_open_indexes(Relation relation, LOCKMODE lockmode,
int *nindexes, Relation **Irel); int *nindexes, Relation **Irel);
extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode); extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode);
extern double vac_estimate_reltuples(Relation relation, bool is_analyze,
BlockNumber total_pages,
BlockNumber scanned_pages,
double scanned_tuples);
extern void vac_update_relstats(Relation relation, extern void vac_update_relstats(Relation relation,
BlockNumber num_pages, BlockNumber num_pages,
double num_tuples, double num_tuples,
...@@ -157,10 +161,10 @@ extern void vacuum_delay_point(void); ...@@ -157,10 +161,10 @@ extern void vacuum_delay_point(void);
/* in commands/vacuumlazy.c */ /* in commands/vacuumlazy.c */
extern void lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt, extern void lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
BufferAccessStrategy bstrategy, bool *scanned_all); BufferAccessStrategy bstrategy);
/* in commands/analyze.c */ /* in commands/analyze.c */
extern void analyze_rel(Oid relid, VacuumStmt *vacstmt, extern void analyze_rel(Oid relid, VacuumStmt *vacstmt,
BufferAccessStrategy bstrategy, bool update_reltuples); BufferAccessStrategy bstrategy);
#endif /* VACUUM_H */ #endif /* VACUUM_H */
...@@ -322,7 +322,6 @@ typedef struct PgStat_MsgVacuum ...@@ -322,7 +322,6 @@ typedef struct PgStat_MsgVacuum
PgStat_MsgHdr m_hdr; PgStat_MsgHdr m_hdr;
Oid m_databaseid; Oid m_databaseid;
Oid m_tableoid; Oid m_tableoid;
bool m_adopt_counts;
bool m_autovacuum; bool m_autovacuum;
TimestampTz m_vacuumtime; TimestampTz m_vacuumtime;
PgStat_Counter m_tuples; PgStat_Counter m_tuples;
...@@ -339,7 +338,6 @@ typedef struct PgStat_MsgAnalyze ...@@ -339,7 +338,6 @@ typedef struct PgStat_MsgAnalyze
PgStat_MsgHdr m_hdr; PgStat_MsgHdr m_hdr;
Oid m_databaseid; Oid m_databaseid;
Oid m_tableoid; Oid m_tableoid;
bool m_adopt_counts;
bool m_autovacuum; bool m_autovacuum;
TimestampTz m_analyzetime; TimestampTz m_analyzetime;
PgStat_Counter m_live_tuples; PgStat_Counter m_live_tuples;
...@@ -706,9 +704,9 @@ extern void pgstat_reset_shared_counters(const char *); ...@@ -706,9 +704,9 @@ extern void pgstat_reset_shared_counters(const char *);
extern void pgstat_reset_single_counter(Oid objectid, PgStat_Single_Reset_Type type); extern void pgstat_reset_single_counter(Oid objectid, PgStat_Single_Reset_Type type);
extern void pgstat_report_autovac(Oid dboid); extern void pgstat_report_autovac(Oid dboid);
extern void pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts, extern void pgstat_report_vacuum(Oid tableoid, bool shared,
PgStat_Counter tuples); PgStat_Counter tuples);
extern void pgstat_report_analyze(Relation rel, bool adopt_counts, extern void pgstat_report_analyze(Relation rel,
PgStat_Counter livetuples, PgStat_Counter deadtuples); PgStat_Counter livetuples, PgStat_Counter deadtuples);
extern void pgstat_report_recovery_conflict(int reason); extern void pgstat_report_recovery_conflict(int reason);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment