diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-04-03 16:27:32 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-04-03 16:27:32 +0000 |
commit | affdd52d5fd5818954f0ef62278e84774549f8ee (patch) | |
tree | 20af01140f78af9ecd654c5d73c72bf5f079fe28 /src/backend/postmaster/pgstat.c | |
parent | db6c80de8b48afedb38e1f88d72546ee6338d7d6 (diff) | |
download | postgresql-affdd52d5fd5818954f0ef62278e84774549f8ee.tar.gz postgresql-affdd52d5fd5818954f0ef62278e84774549f8ee.zip |
Teach ANALYZE to distinguish dead and in-doubt tuples, which it formerly
classed all as "dead"; also get it to count DEAD item pointers as dead rows,
instead of ignoring them as before. Also improve matters so that tuples
previously inserted or deleted by our own transaction are handled nicely:
the stats collector's live-tuple and dead-tuple counts will end up correct
after our transaction ends, regardless of whether we end in commit or abort.
While there's more work that could be done to improve the counting of in-doubt
tuples in both VACUUM and ANALYZE, this commit is enough to alleviate some
known bad behaviors in 8.3; and the other stuff that's been discussed seems
like research projects anyway.
Pavan Deolasee and Tom Lane
Diffstat (limited to 'src/backend/postmaster/pgstat.c')
-rw-r--r-- | src/backend/postmaster/pgstat.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index eaf0491933d..73a772d444e 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -13,7 +13,7 @@ * * Copyright (c) 2001-2008, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.169 2008/01/01 19:45:51 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.169.2.1 2008/04/03 16:27:32 tgl Exp $ * ---------- */ #include "postgres.h" @@ -1036,7 +1036,7 @@ pgstat_report_vacuum(Oid tableoid, bool shared, * -------- */ void -pgstat_report_analyze(Oid tableoid, bool shared, PgStat_Counter livetuples, +pgstat_report_analyze(Relation rel, PgStat_Counter livetuples, PgStat_Counter deadtuples) { PgStat_MsgAnalyze msg; @@ -1044,10 +1044,36 @@ pgstat_report_analyze(Oid tableoid, bool shared, PgStat_Counter livetuples, if (pgStatSock < 0 || !pgstat_track_counts) return; + /* + * Unlike VACUUM, ANALYZE might be running inside a transaction that + * has already inserted and/or deleted rows in the target table. + * ANALYZE will have counted such rows as live or dead respectively. + * Because we will report our counts of such rows at transaction end, + * we should subtract off these counts from what we send to the collector + * now, else they'll be double-counted after commit. (This approach also + * ensures that the collector ends up with the right numbers if we abort + * instead of committing.) + */ + if (rel->pgstat_info != NULL) + { + PgStat_TableXactStatus *trans; + + for (trans = rel->pgstat_info->trans; trans; trans = trans->upper) + { + livetuples -= trans->tuples_inserted - trans->tuples_deleted; + deadtuples -= trans->tuples_deleted; + } + /* count stuff inserted by already-aborted subxacts, too */ + deadtuples -= rel->pgstat_info->t_counts.t_new_dead_tuples; + /* Since ANALYZE's counts are estimates, we could have underflowed */ + livetuples = Max(livetuples, 0); + deadtuples = Max(deadtuples, 0); + } + pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ANALYZE); - msg.m_databaseid = shared ? InvalidOid : MyDatabaseId; - msg.m_tableoid = tableoid; - msg.m_autovacuum = IsAutoVacuumWorkerProcess(); /* is this autovacuum? */ + msg.m_databaseid = rel->rd_rel->relisshared ? InvalidOid : MyDatabaseId; + msg.m_tableoid = RelationGetRelid(rel); + msg.m_autovacuum = IsAutoVacuumWorkerProcess(); /* is this autovacuum? */ msg.m_analyzetime = GetCurrentTimestamp(); msg.m_live_tuples = livetuples; msg.m_dead_tuples = deadtuples; |