diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/analyze.c | 16 | ||||
-rw-r--r-- | src/backend/commands/vacuum.c | 3 | ||||
-rw-r--r-- | src/backend/commands/vacuumlazy.c | 3 | ||||
-rw-r--r-- | src/backend/postmaster/autovacuum.c | 5 | ||||
-rw-r--r-- | src/backend/postmaster/pgstat.c | 221 | ||||
-rw-r--r-- | src/include/pgstat.h | 39 |
6 files changed, 152 insertions, 135 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 0739db99f50..aa41cd3d4c4 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.144 2009/12/29 20:11:44 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.145 2009/12/30 20:32:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -535,16 +535,13 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, } /* - * Update pages/tuples stats in pg_class. + * Update pages/tuples stats in pg_class, but not if we're inside a + * VACUUM that got a more precise number. */ if (update_reltuples) - { vac_update_relstats(onerel, RelationGetNumberOfBlocks(onerel), totalrows, hasindex, InvalidTransactionId); - /* report results to the stats collector, too */ - pgstat_report_analyze(onerel, totalrows, totaldeadrows); - } /* * Same for indexes. Vacuum always scans all indexes, so if we're part of @@ -565,6 +562,13 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, } } + /* + * Report ANALYZE to the stats collector, too; likewise, tell it to + * adopt these numbers only if we're not inside a VACUUM that got a + * better number. + */ + pgstat_report_analyze(onerel, update_reltuples, totalrows, totaldeadrows); + /* We skip to here if there were no analyzable columns */ cleanup: diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 0049b7c9731..f43a74c475d 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.400 2009/12/29 20:11:44 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.401 2009/12/30 20:32:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1332,7 +1332,6 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared, true, - (vacstmt->options & VACOPT_ANALYZE) != 0, vacrelstats->rel_tuples); return heldoff; diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c index acc6c427075..e899781cf61 100644 --- a/src/backend/commands/vacuumlazy.c +++ b/src/backend/commands/vacuumlazy.c @@ -29,7 +29,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.125 2009/12/19 01:32:34 sriggs Exp $ + * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.126 2009/12/30 20:32:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -237,7 +237,6 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt, pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared, vacrelstats->scanned_all, - (vacstmt->options & VACOPT_ANALYZE) != 0, vacrelstats->rel_tuples); /* and log the action if appropriate */ diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index e4ab771b7f6..0b30253c67d 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -55,7 +55,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.105 2009/11/16 21:32:06 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.106 2009/12/30 20:32:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2591,8 +2591,7 @@ relation_needs_vacanalyze(Oid relid, { reltuples = classForm->reltuples; vactuples = tabentry->n_dead_tuples; - anltuples = tabentry->n_live_tuples + tabentry->n_dead_tuples - - tabentry->last_anl_tuples; + anltuples = tabentry->changes_since_analyze; vacthresh = (float4) vac_base_thresh + vac_scale_factor * reltuples; anlthresh = (float4) anl_base_thresh + anl_scale_factor * reltuples; diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index ab88a59eea4..84fea028074 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -13,7 +13,7 @@ * * Copyright (c) 2001-2009, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.194 2009/12/27 19:40:07 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.195 2009/12/30 20:32:14 tgl Exp $ * ---------- */ #include "postgres.h" @@ -195,6 +195,7 @@ static int pgStatXactRollback = 0; typedef struct TwoPhasePgStatRecord { PgStat_Counter tuples_inserted; /* tuples inserted in xact */ + PgStat_Counter tuples_updated; /* tuples updated in xact */ PgStat_Counter tuples_deleted; /* tuples deleted in xact */ Oid t_id; /* table's OID */ bool t_shared; /* is it a shared catalog? */ @@ -1184,8 +1185,8 @@ pgstat_report_autovac(Oid dboid) * --------- */ void -pgstat_report_vacuum(Oid tableoid, bool shared, bool scanned_all, - bool analyze, PgStat_Counter tuples) +pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts, + PgStat_Counter tuples) { PgStat_MsgVacuum msg; @@ -1195,9 +1196,8 @@ pgstat_report_vacuum(Oid tableoid, bool shared, bool scanned_all, pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_VACUUM); msg.m_databaseid = shared ? InvalidOid : MyDatabaseId; msg.m_tableoid = tableoid; - msg.m_scanned_all = scanned_all; - msg.m_analyze = analyze; - msg.m_autovacuum = IsAutoVacuumWorkerProcess(); /* is this autovacuum? */ + msg.m_adopt_counts = adopt_counts; + msg.m_autovacuum = IsAutoVacuumWorkerProcess(); msg.m_vacuumtime = GetCurrentTimestamp(); msg.m_tuples = tuples; pgstat_send(&msg, sizeof(msg)); @@ -1210,8 +1210,8 @@ pgstat_report_vacuum(Oid tableoid, bool shared, bool scanned_all, * -------- */ void -pgstat_report_analyze(Relation rel, PgStat_Counter livetuples, - PgStat_Counter deadtuples) +pgstat_report_analyze(Relation rel, bool adopt_counts, + PgStat_Counter livetuples, PgStat_Counter deadtuples) { PgStat_MsgAnalyze msg; @@ -1235,10 +1235,10 @@ pgstat_report_analyze(Relation rel, PgStat_Counter livetuples, for (trans = rel->pgstat_info->trans; trans; trans = trans->upper) { livetuples -= trans->tuples_inserted - trans->tuples_deleted; - deadtuples -= trans->tuples_deleted; + deadtuples -= trans->tuples_updated + trans->tuples_deleted; } /* count stuff inserted by already-aborted subxacts, too */ - deadtuples -= rel->pgstat_info->t_counts.t_new_dead_tuples; + deadtuples -= rel->pgstat_info->t_counts.t_delta_dead_tuples; /* Since ANALYZE's counts are estimates, we could have underflowed */ livetuples = Max(livetuples, 0); deadtuples = Max(deadtuples, 0); @@ -1247,7 +1247,8 @@ pgstat_report_analyze(Relation rel, PgStat_Counter livetuples, pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ANALYZE); msg.m_databaseid = rel->rd_rel->relisshared ? InvalidOid : MyDatabaseId; msg.m_tableoid = RelationGetRelid(rel); - msg.m_autovacuum = IsAutoVacuumWorkerProcess(); /* is this autovacuum? */ + msg.m_adopt_counts = adopt_counts; + msg.m_autovacuum = IsAutoVacuumWorkerProcess(); msg.m_analyzetime = GetCurrentTimestamp(); msg.m_live_tuples = livetuples; msg.m_dead_tuples = deadtuples; @@ -1559,12 +1560,9 @@ pgstat_count_heap_insert(Relation rel) if (pgstat_track_counts && pgstat_info != NULL) { + /* We have to log the effect at the proper transactional level */ int nest_level = GetCurrentTransactionNestLevel(); - /* t_tuples_inserted is nontransactional, so just advance it */ - pgstat_info->t_counts.t_tuples_inserted++; - - /* We have to log the transactional effect at the proper level */ if (pgstat_info->trans == NULL || pgstat_info->trans->nest_level != nest_level) add_tabstat_xact_level(pgstat_info, nest_level); @@ -1583,22 +1581,18 @@ pgstat_count_heap_update(Relation rel, bool hot) if (pgstat_track_counts && pgstat_info != NULL) { + /* We have to log the effect at the proper transactional level */ int nest_level = GetCurrentTransactionNestLevel(); - /* t_tuples_updated is nontransactional, so just advance it */ - pgstat_info->t_counts.t_tuples_updated++; - /* ditto for the hot_update counter */ - if (hot) - pgstat_info->t_counts.t_tuples_hot_updated++; - - /* We have to log the transactional effect at the proper level */ if (pgstat_info->trans == NULL || pgstat_info->trans->nest_level != nest_level) add_tabstat_xact_level(pgstat_info, nest_level); - /* An UPDATE both inserts a new tuple and deletes the old */ - pgstat_info->trans->tuples_inserted++; - pgstat_info->trans->tuples_deleted++; + pgstat_info->trans->tuples_updated++; + + /* t_tuples_hot_updated is nontransactional, so just advance it */ + if (hot) + pgstat_info->t_counts.t_tuples_hot_updated++; } } @@ -1612,12 +1606,9 @@ pgstat_count_heap_delete(Relation rel) if (pgstat_track_counts && pgstat_info != NULL) { + /* We have to log the effect at the proper transactional level */ int nest_level = GetCurrentTransactionNestLevel(); - /* t_tuples_deleted is nontransactional, so just advance it */ - pgstat_info->t_counts.t_tuples_deleted++; - - /* We have to log the transactional effect at the proper level */ if (pgstat_info->trans == NULL || pgstat_info->trans->nest_level != nest_level) add_tabstat_xact_level(pgstat_info, nest_level); @@ -1630,7 +1621,7 @@ pgstat_count_heap_delete(Relation rel) * pgstat_update_heap_dead_tuples - update dead-tuples count * * The semantics of this are that we are reporting the nontransactional - * recovery of "delta" dead tuples; so t_new_dead_tuples decreases + * recovery of "delta" dead tuples; so t_delta_dead_tuples decreases * rather than increasing, and the change goes straight into the per-table * counter, not into transactional state. */ @@ -1640,7 +1631,7 @@ pgstat_update_heap_dead_tuples(Relation rel, int delta) PgStat_TableStatus *pgstat_info = rel->pgstat_info; if (pgstat_track_counts && pgstat_info != NULL) - pgstat_info->t_counts.t_new_dead_tuples -= delta; + pgstat_info->t_counts.t_delta_dead_tuples -= delta; } @@ -1684,16 +1675,29 @@ AtEOXact_PgStat(bool isCommit) Assert(trans->upper == NULL); tabstat = trans->parent; Assert(tabstat->trans == trans); + /* count attempted actions regardless of commit/abort */ + tabstat->t_counts.t_tuples_inserted += trans->tuples_inserted; + tabstat->t_counts.t_tuples_updated += trans->tuples_updated; + tabstat->t_counts.t_tuples_deleted += trans->tuples_deleted; if (isCommit) { - tabstat->t_counts.t_new_live_tuples += + /* insert adds a live tuple, delete removes one */ + tabstat->t_counts.t_delta_live_tuples += trans->tuples_inserted - trans->tuples_deleted; - tabstat->t_counts.t_new_dead_tuples += trans->tuples_deleted; + /* update and delete each create a dead tuple */ + tabstat->t_counts.t_delta_dead_tuples += + trans->tuples_updated + trans->tuples_deleted; + /* insert, update, delete each count as one change event */ + tabstat->t_counts.t_changed_tuples += + trans->tuples_inserted + trans->tuples_updated + + trans->tuples_deleted; } else { /* inserted tuples are dead, deleted tuples are unaffected */ - tabstat->t_counts.t_new_dead_tuples += trans->tuples_inserted; + tabstat->t_counts.t_delta_dead_tuples += + trans->tuples_inserted + trans->tuples_updated; + /* an aborted xact generates no changed_tuple events */ } tabstat->trans = NULL; } @@ -1742,6 +1746,7 @@ AtEOSubXact_PgStat(bool isCommit, int nestDepth) if (trans->upper && trans->upper->nest_level == nestDepth - 1) { trans->upper->tuples_inserted += trans->tuples_inserted; + trans->upper->tuples_updated += trans->tuples_updated; trans->upper->tuples_deleted += trans->tuples_deleted; tabstat->trans = trans->upper; pfree(trans); @@ -1767,10 +1772,17 @@ AtEOSubXact_PgStat(bool isCommit, int nestDepth) else { /* - * On abort, inserted tuples are dead (and can be bounced out - * to the top-level tabstat), deleted tuples are unaffected + * On abort, update top-level tabstat counts, then forget + * the subtransaction */ - tabstat->t_counts.t_new_dead_tuples += trans->tuples_inserted; + + /* count attempted actions regardless of commit/abort */ + tabstat->t_counts.t_tuples_inserted += trans->tuples_inserted; + tabstat->t_counts.t_tuples_updated += trans->tuples_updated; + tabstat->t_counts.t_tuples_deleted += trans->tuples_deleted; + /* inserted tuples are dead, deleted tuples are unaffected */ + tabstat->t_counts.t_delta_dead_tuples += + trans->tuples_inserted + trans->tuples_updated; tabstat->trans = trans->upper; pfree(trans); } @@ -1810,6 +1822,7 @@ AtPrepare_PgStat(void) Assert(tabstat->trans == trans); record.tuples_inserted = trans->tuples_inserted; + record.tuples_updated = trans->tuples_updated; record.tuples_deleted = trans->tuples_deleted; record.t_id = tabstat->t_id; record.t_shared = tabstat->t_shared; @@ -1874,9 +1887,17 @@ pgstat_twophase_postcommit(TransactionId xid, uint16 info, /* Find or create a tabstat entry for the rel */ pgstat_info = get_tabstat_entry(rec->t_id, rec->t_shared); - pgstat_info->t_counts.t_new_live_tuples += + /* Same math as in AtEOXact_PgStat, commit case */ + pgstat_info->t_counts.t_tuples_inserted += rec->tuples_inserted; + pgstat_info->t_counts.t_tuples_updated += rec->tuples_updated; + pgstat_info->t_counts.t_tuples_deleted += rec->tuples_deleted; + pgstat_info->t_counts.t_delta_live_tuples += rec->tuples_inserted - rec->tuples_deleted; - pgstat_info->t_counts.t_new_dead_tuples += rec->tuples_deleted; + pgstat_info->t_counts.t_delta_dead_tuples += + rec->tuples_updated + rec->tuples_deleted; + pgstat_info->t_counts.t_changed_tuples += + rec->tuples_inserted + rec->tuples_updated + + rec->tuples_deleted; } /* @@ -1895,8 +1916,12 @@ pgstat_twophase_postabort(TransactionId xid, uint16 info, /* Find or create a tabstat entry for the rel */ pgstat_info = get_tabstat_entry(rec->t_id, rec->t_shared); - /* inserted tuples are dead, deleted tuples are no-ops */ - pgstat_info->t_counts.t_new_dead_tuples += rec->tuples_inserted; + /* Same math as in AtEOXact_PgStat, abort case */ + pgstat_info->t_counts.t_tuples_inserted += rec->tuples_inserted; + pgstat_info->t_counts.t_tuples_updated += rec->tuples_updated; + pgstat_info->t_counts.t_tuples_deleted += rec->tuples_deleted; + pgstat_info->t_counts.t_delta_dead_tuples += + rec->tuples_inserted + rec->tuples_updated; } @@ -3045,7 +3070,7 @@ pgstat_get_tab_entry(PgStat_StatDBEntry *dbentry, Oid tableoid, bool create) result->tuples_hot_updated = 0; result->n_live_tuples = 0; result->n_dead_tuples = 0; - result->last_anl_tuples = 0; + result->changes_since_analyze = 0; result->blocks_fetched = 0; result->blocks_hit = 0; @@ -3634,7 +3659,6 @@ pgstat_recv_inquiry(PgStat_MsgInquiry *msg, int len) static void pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len) { - PgStat_TableEntry *tabmsg = &(msg->m_entry[0]); PgStat_StatDBEntry *dbentry; PgStat_StatTabEntry *tabentry; int i; @@ -3653,8 +3677,10 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len) */ for (i = 0; i < msg->m_nentries; i++) { + PgStat_TableEntry *tabmsg = &(msg->m_entry[i]); + tabentry = (PgStat_StatTabEntry *) hash_search(dbentry->tables, - (void *) &(tabmsg[i].t_id), + (void *) &(tabmsg->t_id), HASH_ENTER, &found); if (!found) @@ -3663,18 +3689,18 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len) * If it's a new table entry, initialize counters to the values we * just got. */ - tabentry->numscans = tabmsg[i].t_counts.t_numscans; - tabentry->tuples_returned = tabmsg[i].t_counts.t_tuples_returned; - tabentry->tuples_fetched = tabmsg[i].t_counts.t_tuples_fetched; - tabentry->tuples_inserted = tabmsg[i].t_counts.t_tuples_inserted; - tabentry->tuples_updated = tabmsg[i].t_counts.t_tuples_updated; - tabentry->tuples_deleted = tabmsg[i].t_counts.t_tuples_deleted; - tabentry->tuples_hot_updated = tabmsg[i].t_counts.t_tuples_hot_updated; - tabentry->n_live_tuples = tabmsg[i].t_counts.t_new_live_tuples; - tabentry->n_dead_tuples = tabmsg[i].t_counts.t_new_dead_tuples; - tabentry->last_anl_tuples = 0; - tabentry->blocks_fetched = tabmsg[i].t_counts.t_blocks_fetched; - tabentry->blocks_hit = tabmsg[i].t_counts.t_blocks_hit; + tabentry->numscans = tabmsg->t_counts.t_numscans; + tabentry->tuples_returned = tabmsg->t_counts.t_tuples_returned; + tabentry->tuples_fetched = tabmsg->t_counts.t_tuples_fetched; + tabentry->tuples_inserted = tabmsg->t_counts.t_tuples_inserted; + tabentry->tuples_updated = tabmsg->t_counts.t_tuples_updated; + tabentry->tuples_deleted = tabmsg->t_counts.t_tuples_deleted; + tabentry->tuples_hot_updated = tabmsg->t_counts.t_tuples_hot_updated; + tabentry->n_live_tuples = tabmsg->t_counts.t_delta_live_tuples; + tabentry->n_dead_tuples = tabmsg->t_counts.t_delta_dead_tuples; + tabentry->changes_since_analyze = tabmsg->t_counts.t_changed_tuples; + tabentry->blocks_fetched = tabmsg->t_counts.t_blocks_fetched; + tabentry->blocks_hit = tabmsg->t_counts.t_blocks_hit; tabentry->vacuum_timestamp = 0; tabentry->autovac_vacuum_timestamp = 0; @@ -3686,20 +3712,21 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len) /* * Otherwise add the values to the existing entry. */ - tabentry->numscans += tabmsg[i].t_counts.t_numscans; - tabentry->tuples_returned += tabmsg[i].t_counts.t_tuples_returned; - tabentry->tuples_fetched += tabmsg[i].t_counts.t_tuples_fetched; - tabentry->tuples_inserted += tabmsg[i].t_counts.t_tuples_inserted; - tabentry->tuples_updated += tabmsg[i].t_counts.t_tuples_updated; - tabentry->tuples_deleted += tabmsg[i].t_counts.t_tuples_deleted; - tabentry->tuples_hot_updated += tabmsg[i].t_counts.t_tuples_hot_updated; - tabentry->n_live_tuples += tabmsg[i].t_counts.t_new_live_tuples; - tabentry->n_dead_tuples += tabmsg[i].t_counts.t_new_dead_tuples; - tabentry->blocks_fetched += tabmsg[i].t_counts.t_blocks_fetched; - tabentry->blocks_hit += tabmsg[i].t_counts.t_blocks_hit; + tabentry->numscans += tabmsg->t_counts.t_numscans; + tabentry->tuples_returned += tabmsg->t_counts.t_tuples_returned; + tabentry->tuples_fetched += tabmsg->t_counts.t_tuples_fetched; + tabentry->tuples_inserted += tabmsg->t_counts.t_tuples_inserted; + tabentry->tuples_updated += tabmsg->t_counts.t_tuples_updated; + tabentry->tuples_deleted += tabmsg->t_counts.t_tuples_deleted; + tabentry->tuples_hot_updated += tabmsg->t_counts.t_tuples_hot_updated; + tabentry->n_live_tuples += tabmsg->t_counts.t_delta_live_tuples; + tabentry->n_dead_tuples += tabmsg->t_counts.t_delta_dead_tuples; + tabentry->changes_since_analyze += tabmsg->t_counts.t_changed_tuples; + tabentry->blocks_fetched += tabmsg->t_counts.t_blocks_fetched; + tabentry->blocks_hit += tabmsg->t_counts.t_blocks_hit; } - /* Clamp n_live_tuples in case of negative new_live_tuples */ + /* Clamp n_live_tuples in case of negative delta_live_tuples */ tabentry->n_live_tuples = Max(tabentry->n_live_tuples, 0); /* Likewise for n_dead_tuples */ tabentry->n_dead_tuples = Max(tabentry->n_dead_tuples, 0); @@ -3707,13 +3734,13 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len) /* * Add per-table stats to the per-database entry, too. */ - dbentry->n_tuples_returned += tabmsg[i].t_counts.t_tuples_returned; - dbentry->n_tuples_fetched += tabmsg[i].t_counts.t_tuples_fetched; - dbentry->n_tuples_inserted += tabmsg[i].t_counts.t_tuples_inserted; - dbentry->n_tuples_updated += tabmsg[i].t_counts.t_tuples_updated; - dbentry->n_tuples_deleted += tabmsg[i].t_counts.t_tuples_deleted; - dbentry->n_blocks_fetched += tabmsg[i].t_counts.t_blocks_fetched; - dbentry->n_blocks_hit += tabmsg[i].t_counts.t_blocks_hit; + dbentry->n_tuples_returned += tabmsg->t_counts.t_tuples_returned; + dbentry->n_tuples_fetched += tabmsg->t_counts.t_tuples_fetched; + dbentry->n_tuples_inserted += tabmsg->t_counts.t_tuples_inserted; + dbentry->n_tuples_updated += tabmsg->t_counts.t_tuples_updated; + dbentry->n_tuples_deleted += tabmsg->t_counts.t_tuples_deleted; + dbentry->n_blocks_fetched += tabmsg->t_counts.t_blocks_fetched; + dbentry->n_blocks_hit += tabmsg->t_counts.t_blocks_hit; } } @@ -3879,36 +3906,15 @@ pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len) tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true); - if (msg->m_autovacuum) - tabentry->autovac_vacuum_timestamp = msg->m_vacuumtime; - else - tabentry->vacuum_timestamp = msg->m_vacuumtime; - if (msg->m_scanned_all) + if (msg->m_adopt_counts) tabentry->n_live_tuples = msg->m_tuples; /* Resetting dead_tuples to 0 is an approximation ... */ tabentry->n_dead_tuples = 0; - if (msg->m_analyze) - { - if (msg->m_scanned_all) - tabentry->last_anl_tuples = msg->m_tuples; - else - { - /* last_anl_tuples must never exceed n_live_tuples+n_dead_tuples */ - tabentry->last_anl_tuples = Min(tabentry->last_anl_tuples, - tabentry->n_live_tuples); - } - if (msg->m_autovacuum) - tabentry->autovac_analyze_timestamp = msg->m_vacuumtime; - else - tabentry->analyze_timestamp = msg->m_vacuumtime; - } + if (msg->m_autovacuum) + tabentry->autovac_vacuum_timestamp = msg->m_vacuumtime; else - { - /* last_anl_tuples must never exceed n_live_tuples+n_dead_tuples */ - tabentry->last_anl_tuples = Min(tabentry->last_anl_tuples, - tabentry->n_live_tuples); - } + tabentry->vacuum_timestamp = msg->m_vacuumtime; } /* ---------- @@ -3930,13 +3936,22 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len) 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_dead_tuples = msg->m_dead_tuples; + } + + /* + * We reset changes_since_analyze to zero, forgetting any changes that + * occurred while the ANALYZE was in progress. + */ + tabentry->changes_since_analyze = 0; + if (msg->m_autovacuum) tabentry->autovac_analyze_timestamp = msg->m_analyzetime; else tabentry->analyze_timestamp = msg->m_analyzetime; - tabentry->n_live_tuples = msg->m_live_tuples; - tabentry->n_dead_tuples = msg->m_dead_tuples; - tabentry->last_anl_tuples = msg->m_live_tuples + msg->m_dead_tuples; } diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 7c4efb9f3bd..c68693a3298 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -5,7 +5,7 @@ * * Copyright (c) 2001-2009, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.84 2009/11/28 23:38:08 tgl Exp $ + * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.85 2009/12/30 20:32:14 tgl Exp $ * ---------- */ #ifndef PGSTAT_H @@ -68,9 +68,9 @@ typedef int64 PgStat_Counter; * fetched by heap_fetch under the control of simple indexscans for this index. * * tuples_inserted/updated/deleted/hot_updated count attempted actions, - * regardless of whether the transaction committed. new_live_tuples and - * new_dead_tuples are properly adjusted depending on commit or abort. - * Note that new_live_tuples and new_dead_tuples can be negative! + * regardless of whether the transaction committed. delta_live_tuples, + * delta_dead_tuples, and changed_tuples are set depending on commit or abort. + * Note that delta_live_tuples and delta_dead_tuples can be negative! * ---------- */ typedef struct PgStat_TableCounts @@ -85,8 +85,9 @@ typedef struct PgStat_TableCounts PgStat_Counter t_tuples_deleted; PgStat_Counter t_tuples_hot_updated; - PgStat_Counter t_new_live_tuples; - PgStat_Counter t_new_dead_tuples; + PgStat_Counter t_delta_live_tuples; + PgStat_Counter t_delta_dead_tuples; + PgStat_Counter t_changed_tuples; PgStat_Counter t_blocks_fetched; PgStat_Counter t_blocks_hit; @@ -102,14 +103,14 @@ typedef struct PgStat_TableCounts /* ---------- * PgStat_TableStatus Per-table status within a backend * - * Most of the event counters are nontransactional, ie, we count events + * Many of the event counters are nontransactional, ie, we count events * in committed and aborted transactions alike. For these, we just count - * directly in the PgStat_TableStatus. However, new_live_tuples and - * new_dead_tuples must be derived from tuple insertion and deletion counts + * directly in the PgStat_TableStatus. However, delta_live_tuples, + * delta_dead_tuples, and changed_tuples must be derived from event counts * with awareness of whether the transaction or subtransaction committed or * aborted. Hence, we also keep a stack of per-(sub)transaction status * records for every table modified in the current transaction. At commit - * or abort, we propagate tuples_inserted and tuples_deleted up to the + * or abort, we propagate tuples_inserted/updated/deleted up to the * parent subtransaction level, or out to the parent PgStat_TableStatus, * as appropriate. * ---------- @@ -129,6 +130,7 @@ typedef struct PgStat_TableStatus typedef struct PgStat_TableXactStatus { PgStat_Counter tuples_inserted; /* tuples inserted in (sub)xact */ + PgStat_Counter tuples_updated; /* tuples updated in (sub)xact */ PgStat_Counter tuples_deleted; /* tuples deleted in (sub)xact */ int nest_level; /* subtransaction nest level */ /* links to other structs for same relation: */ @@ -274,7 +276,7 @@ typedef struct PgStat_MsgAutovacStart /* ---------- * PgStat_MsgVacuum Sent by the backend or autovacuum daemon - * after VACUUM or VACUUM ANALYZE + * after VACUUM * ---------- */ typedef struct PgStat_MsgVacuum @@ -282,9 +284,8 @@ typedef struct PgStat_MsgVacuum PgStat_MsgHdr m_hdr; Oid m_databaseid; Oid m_tableoid; - bool m_analyze; + bool m_adopt_counts; bool m_autovacuum; - bool m_scanned_all; TimestampTz m_vacuumtime; PgStat_Counter m_tuples; } PgStat_MsgVacuum; @@ -300,6 +301,7 @@ typedef struct PgStat_MsgAnalyze PgStat_MsgHdr m_hdr; Oid m_databaseid; Oid m_tableoid; + bool m_adopt_counts; bool m_autovacuum; TimestampTz m_analyzetime; PgStat_Counter m_live_tuples; @@ -478,7 +480,7 @@ typedef struct PgStat_StatTabEntry PgStat_Counter n_live_tuples; PgStat_Counter n_dead_tuples; - PgStat_Counter last_anl_tuples; + PgStat_Counter changes_since_analyze; PgStat_Counter blocks_fetched; PgStat_Counter blocks_hit; @@ -635,11 +637,10 @@ extern void pgstat_clear_snapshot(void); extern void pgstat_reset_counters(void); extern void pgstat_report_autovac(Oid dboid); -extern void pgstat_report_vacuum(Oid tableoid, bool shared, bool scanned_all, - bool analyze, PgStat_Counter tuples); -extern void pgstat_report_analyze(Relation rel, - PgStat_Counter livetuples, - PgStat_Counter deadtuples); +extern void pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts, + PgStat_Counter tuples); +extern void pgstat_report_analyze(Relation rel, bool adopt_counts, + PgStat_Counter livetuples, PgStat_Counter deadtuples); extern void pgstat_initialize(void); extern void pgstat_bestart(void); |