]> granicus.if.org Git - postgresql/blobdiff - src/backend/postmaster/pgstat.c
Fix VACUUM so that it always updates pg_class.reltuples/relpages.
[postgresql] / src / backend / postmaster / pgstat.c
index 301568f6df335270a834bee1347748cac5e3bbeb..1d80c311d879d9cf9009621860cda3ab19c6dea9 100644 (file)
@@ -1246,8 +1246,7 @@ pgstat_report_autovac(Oid dboid)
  * ---------
  */
 void
-pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts,
-                                        PgStat_Counter tuples)
+pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter tuples)
 {
        PgStat_MsgVacuum msg;
 
@@ -1257,7 +1256,6 @@ pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts,
        pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_VACUUM);
        msg.m_databaseid = shared ? InvalidOid : MyDatabaseId;
        msg.m_tableoid = tableoid;
-       msg.m_adopt_counts = adopt_counts;
        msg.m_autovacuum = IsAutoVacuumWorkerProcess();
        msg.m_vacuumtime = GetCurrentTimestamp();
        msg.m_tuples = tuples;
@@ -1271,7 +1269,7 @@ pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts,
  * --------
  */
 void
-pgstat_report_analyze(Relation rel, bool adopt_counts,
+pgstat_report_analyze(Relation rel,
                                          PgStat_Counter livetuples, PgStat_Counter deadtuples)
 {
        PgStat_MsgAnalyze msg;
@@ -1308,7 +1306,6 @@ pgstat_report_analyze(Relation rel, bool adopt_counts,
        pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ANALYZE);
        msg.m_databaseid = rel->rd_rel->relisshared ? InvalidOid : MyDatabaseId;
        msg.m_tableoid = RelationGetRelid(rel);
-       msg.m_adopt_counts = adopt_counts;
        msg.m_autovacuum = IsAutoVacuumWorkerProcess();
        msg.m_analyzetime = GetCurrentTimestamp();
        msg.m_live_tuples = livetuples;
@@ -1319,7 +1316,7 @@ pgstat_report_analyze(Relation rel, bool adopt_counts,
 /* --------
  * pgstat_report_recovery_conflict() -
  *
- *  Tell the collector about a Hot Standby recovery conflict.
+ *     Tell the collector about a Hot Standby recovery conflict.
  * --------
  */
 void
@@ -2223,6 +2220,7 @@ pgstat_fetch_global(void)
 
 static PgBackendStatus *BackendStatusArray = NULL;
 static PgBackendStatus *MyBEEntry = NULL;
+static char *BackendClientHostnameBuffer = NULL;
 static char *BackendAppnameBuffer = NULL;
 static char *BackendActivityBuffer = NULL;
 
@@ -2240,11 +2238,13 @@ BackendStatusShmemSize(void)
                                        mul_size(NAMEDATALEN, MaxBackends));
        size = add_size(size,
                                        mul_size(pgstat_track_activity_query_size, MaxBackends));
+       size = add_size(size,
+                                       mul_size(NAMEDATALEN, MaxBackends));
        return size;
 }
 
 /*
- * Initialize the shared status array and activity/appname string buffers
+ * Initialize the shared status array and several string buffers
  * during postmaster startup.
  */
 void
@@ -2286,6 +2286,24 @@ CreateSharedBackendStatus(void)
                }
        }
 
+       /* Create or attach to the shared client hostname buffer */
+       size = mul_size(NAMEDATALEN, MaxBackends);
+       BackendClientHostnameBuffer = (char *)
+               ShmemInitStruct("Backend Client Host Name Buffer", size, &found);
+
+       if (!found)
+       {
+               MemSet(BackendClientHostnameBuffer, 0, size);
+
+               /* Initialize st_clienthostname pointers. */
+               buffer = BackendClientHostnameBuffer;
+               for (i = 0; i < MaxBackends; i++)
+               {
+                       BackendStatusArray[i].st_clienthostname = buffer;
+                       buffer += NAMEDATALEN;
+               }
+       }
+
        /* Create or attach to the shared activity buffer */
        size = mul_size(pgstat_track_activity_query_size, MaxBackends);
        BackendActivityBuffer = (char *)
@@ -2386,16 +2404,21 @@ pgstat_bestart(void)
        beentry->st_databaseid = MyDatabaseId;
        beentry->st_userid = userid;
        beentry->st_clientaddr = clientaddr;
+       beentry->st_clienthostname[0] = '\0';
        beentry->st_waiting = false;
        beentry->st_appname[0] = '\0';
        beentry->st_activity[0] = '\0';
        /* Also make sure the last byte in each string area is always 0 */
+       beentry->st_clienthostname[NAMEDATALEN - 1] = '\0';
        beentry->st_appname[NAMEDATALEN - 1] = '\0';
        beentry->st_activity[pgstat_track_activity_query_size - 1] = '\0';
 
        beentry->st_changecount++;
        Assert((beentry->st_changecount & 1) == 0);
 
+       if (MyProcPort && MyProcPort->remote_hostname)
+               strlcpy(beentry->st_clienthostname, MyProcPort->remote_hostname, NAMEDATALEN);
+
        /* Update app name to current GUC setting */
        if (application_name)
                pgstat_report_appname(application_name);
@@ -3160,6 +3183,8 @@ pgstat_get_db_entry(Oid databaseid, bool create)
                result->n_conflict_bufferpin = 0;
                result->n_conflict_startup_deadlock = 0;
 
+               result->stat_reset_timestamp = GetCurrentTimestamp();
+
                memset(&hash_ctl, 0, sizeof(hash_ctl));
                hash_ctl.keysize = sizeof(Oid);
                hash_ctl.entrysize = sizeof(PgStat_StatTabEntry);
@@ -3217,14 +3242,13 @@ pgstat_get_tab_entry(PgStat_StatDBEntry *dbentry, Oid tableoid, bool create)
                result->changes_since_analyze = 0;
                result->blocks_fetched = 0;
                result->blocks_hit = 0;
-
                result->vacuum_timestamp = 0;
-               result->autovac_vacuum_timestamp = 0;
-               result->analyze_timestamp = 0;
-               result->autovac_analyze_timestamp = 0;
                result->vacuum_count = 0;
+               result->autovac_vacuum_timestamp = 0;
                result->autovac_vacuum_count = 0;
+               result->analyze_timestamp = 0;
                result->analyze_count = 0;
+               result->autovac_analyze_timestamp = 0;
                result->autovac_analyze_count = 0;
        }
 
@@ -3439,6 +3463,12 @@ pgstat_read_statsfile(Oid onlydb, bool permanent)
         */
        memset(&globalStats, 0, sizeof(globalStats));
 
+       /*
+        * Set the current timestamp (will be kept only in case we can't load an
+        * existing statsfile.
+        */
+       globalStats.stat_reset_timestamp = GetCurrentTimestamp();
+
        /*
         * Try to open the status file. If it doesn't exist, the backends simply
         * return zero for anything and the collector simply starts from scratch
@@ -3894,9 +3924,13 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len)
                        tabentry->blocks_hit = tabmsg->t_counts.t_blocks_hit;
 
                        tabentry->vacuum_timestamp = 0;
+                       tabentry->vacuum_count = 0;
                        tabentry->autovac_vacuum_timestamp = 0;
+                       tabentry->autovac_vacuum_count = 0;
                        tabentry->analyze_timestamp = 0;
+                       tabentry->analyze_count = 0;
                        tabentry->autovac_analyze_timestamp = 0;
+                       tabentry->autovac_analyze_count = 0;
                }
                else
                {
@@ -4038,7 +4072,7 @@ pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len)
        dbentry->functions = NULL;
 
        /*
-        * Reset database-level stats too.  This should match the initialization
+        * Reset database-level stats too.      This should match the initialization
         * code in pgstat_get_db_entry().
         */
        dbentry->n_xact_commit = 0;
@@ -4052,6 +4086,8 @@ pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len)
        dbentry->n_tuples_deleted = 0;
        dbentry->last_autovac_time = 0;
 
+       dbentry->stat_reset_timestamp = GetCurrentTimestamp();
+
        memset(&hash_ctl, 0, sizeof(hash_ctl));
        hash_ctl.keysize = sizeof(Oid);
        hash_ctl.entrysize = sizeof(PgStat_StatTabEntry);
@@ -4083,6 +4119,7 @@ pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len)
        {
                /* Reset the global background writer statistics for the cluster. */
                memset(&globalStats, 0, sizeof(globalStats));
+               globalStats.stat_reset_timestamp = GetCurrentTimestamp();
        }
 
        /*
@@ -4107,12 +4144,16 @@ pgstat_recv_resetsinglecounter(PgStat_MsgResetsinglecounter *msg, int len)
        if (!dbentry)
                return;
 
+       /* Set the reset timestamp for the whole database */
+       dbentry->stat_reset_timestamp = GetCurrentTimestamp();
 
        /* Remove object if it exists, ignore it if not */
        if (msg->m_resettype == RESET_TABLE)
-               (void) hash_search(dbentry->tables, (void *) &(msg->m_objectid), HASH_REMOVE, NULL);
+               (void) hash_search(dbentry->tables, (void *) &(msg->m_objectid),
+                                                  HASH_REMOVE, NULL);
        else if (msg->m_resettype == RESET_FUNCTION)
-               (void) hash_search(dbentry->functions, (void *) &(msg->m_objectid), HASH_REMOVE, NULL);
+               (void) hash_search(dbentry->functions, (void *) &(msg->m_objectid),
+                                                  HASH_REMOVE, NULL);
 }
 
 /* ----------
@@ -4153,8 +4194,7 @@ 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;
+       tabentry->n_live_tuples = msg->m_tuples;
        /* Resetting dead_tuples to 0 is an approximation ... */
        tabentry->n_dead_tuples = 0;
 
@@ -4189,11 +4229,8 @@ 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;
-       }
+       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
@@ -4236,22 +4273,23 @@ pgstat_recv_bgwriter(PgStat_MsgBgWriter *msg, int len)
 /* ----------
  * pgstat_recv_recoveryconflict() -
  *
- *  Process as RECOVERYCONFLICT message.
+ *     Process as RECOVERYCONFLICT message.
  * ----------
  */
 static void
 pgstat_recv_recoveryconflict(PgStat_MsgRecoveryConflict *msg, int len)
 {
        PgStat_StatDBEntry *dbentry;
+
        dbentry = pgstat_get_db_entry(msg->m_databaseid, true);
 
        switch (msg->m_reason)
        {
                case PROCSIG_RECOVERY_CONFLICT_DATABASE:
+
                        /*
-                        * Since we drop the information about the database as soon
-                        * as it replicates, there is no point in counting these
-                        * conflicts.
+                        * Since we drop the information about the database as soon as it
+                        * replicates, there is no point in counting these conflicts.
                         */
                        break;
                case PROCSIG_RECOVERY_CONFLICT_TABLESPACE: