|
|
|
@ -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_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_autovacuum)
|
|
|
|
|
tabentry->autovac_vacuum_timestamp = msg->m_vacuumtime;
|
|
|
|
|
else
|
|
|
|
|
tabentry->vacuum_timestamp = msg->m_vacuumtime;
|
|
|
|
|
if (msg->m_scanned_all)
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------
|
|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|