]> granicus.if.org Git - postgresql/commitdiff
Have autovacuum report its activities to the stat collector.
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 19 May 2006 15:15:37 +0000 (15:15 +0000)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 19 May 2006 15:15:37 +0000 (15:15 +0000)
src/backend/postmaster/autovacuum.c
src/backend/postmaster/pgstat.c
src/backend/postmaster/postmaster.c
src/backend/utils/adt/pgstatfuncs.c

index a19e504b0efc98dac707ac8d440c59917e81d9eb..820f44586653cf7f9425b6d0a08aa7e52ef4df73 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.18 2006/05/03 22:45:26 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.19 2006/05/19 15:15:37 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -45,6 +45,8 @@
 #include "utils/fmgroids.h"
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
+#include "utils/lsyscache.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/syscache.h"
 
@@ -109,6 +111,8 @@ static void test_rel_for_autovac(Oid relid, PgStat_StatTabEntry *tabentry,
                                         List **toast_table_ids);
 static void autovacuum_do_vac_analyze(List *relids, bool dovacuum,
                                                  bool doanalyze, bool freeze);
+static void autovac_report_activity(VacuumStmt *vacstmt,
+                                               List *relids);
 
 
 /*
@@ -911,12 +915,75 @@ autovacuum_do_vac_analyze(List *relids, bool dovacuum, bool doanalyze,
        vacstmt->relation = NULL;       /* all tables, or not used if relids != NIL */
        vacstmt->va_cols = NIL;
 
+       /* Let pgstat know what we're doing */
+       autovac_report_activity(vacstmt, relids);
+
        vacuum(vacstmt, relids);
 
        pfree(vacstmt);
        MemoryContextSwitchTo(old_cxt);
 }
 
+/*
+ * autovac_report_activity
+ *             Report to pgstat what autovacuum is doing
+ *
+ * We send a SQL string corresponding to what the user would see if the
+ * equivalent command was to be issued manually.
+ *
+ * Note we assume that we are going to report the next command as soon as we're
+ * done with the current one, and exiting right after the last one, so we don't
+ * bother to report "<IDLE>" or some such.
+ */
+#define MAX_AUTOVAC_ACTIV_LEN (NAMEDATALEN * 2 + 32)
+static void
+autovac_report_activity(VacuumStmt *vacstmt, List *relids)
+{
+       char            activity[MAX_AUTOVAC_ACTIV_LEN];
+
+       /*
+        * This case is not currently exercised by the autovac code.  Fill it in
+        * if needed.
+        */
+       if (list_length(relids) > 1)
+               elog(WARNING, "vacuuming >1 rel unsupported");
+
+       /* Report the command and possible options */
+       if (vacstmt->vacuum)
+               snprintf(activity, MAX_AUTOVAC_ACTIV_LEN,
+                                          "VACUUM%s%s%s",
+                                          vacstmt->full ? " FULL" : "",
+                                          vacstmt->freeze ? " FREEZE" : "",
+                                          vacstmt->analyze ? " ANALYZE" : "");
+       else if (vacstmt->analyze)
+               snprintf(activity, MAX_AUTOVAC_ACTIV_LEN,
+                                          "ANALYZE");
+
+       /* Report the qualified name of the first relation, if any */
+       if (list_length(relids) > 0)
+       {
+               Oid                     relid = linitial_oid(relids);
+               Relation        rel;
+
+               rel = RelationIdGetRelation(relid);
+               if (rel == NULL)
+                       elog(WARNING, "cache lookup failed for relation %u", relid);
+               else
+               {
+                       char   *nspname = get_namespace_name(RelationGetNamespace(rel));
+                       int             len = strlen(activity);
+
+                       snprintf(activity + len, MAX_AUTOVAC_ACTIV_LEN - len,
+                                        " %s.%s", nspname, RelationGetRelationName(rel));
+
+                       pfree(nspname);
+                       RelationClose(rel);
+               }
+       }
+
+       pgstat_report_activity(activity);
+}
+
 /*
  * AutoVacuumingActive
  *             Check GUC vars and report whether the autovacuum process should be
index c40b90b5993ad745795793e0eaf8acfe060adcc8..c10850a7c1f4399f680032fd677d18e9c93ed21d 100644 (file)
@@ -13,7 +13,7 @@
  *
  *     Copyright (c) 2001-2006, PostgreSQL Global Development Group
  *
- *     $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.124 2006/04/27 00:06:58 momjian Exp $
+ *     $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.125 2006/05/19 15:15:37 alvherre Exp $
  * ----------
  */
 #include "postgres.h"
@@ -700,17 +700,17 @@ pgstat_bestart(void)
 
        /*
         * We may not have a MyProcPort (eg, if this is the autovacuum process).
-        * For the moment, punt and don't send BESTART --- would be better to work
-        * out a clean way of handling "unknown clientaddr".
+        * Send an all-zeroes client address, which is dealt with specially in
+        * pg_stat_get_backend_client_addr and pg_stat_get_backend_client_port.
         */
+       pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_BESTART);
+       msg.m_databaseid = MyDatabaseId;
+       msg.m_userid = GetSessionUserId();
        if (MyProcPort)
-       {
-               pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_BESTART);
-               msg.m_databaseid = MyDatabaseId;
-               msg.m_userid = GetSessionUserId();
                memcpy(&msg.m_clientaddr, &MyProcPort->raddr, sizeof(msg.m_clientaddr));
-               pgstat_send(&msg, sizeof(msg));
-       }
+       else
+               MemSet(&msg.m_clientaddr, 0, sizeof(msg.m_clientaddr));
+       pgstat_send(&msg, sizeof(msg));
 
        /*
         * Set up a process-exit hook to ensure we flush the last batch of
index 71923ec084b45b67fd34d19b4ddc3b8ee8fe7f46..2ee450945fd3e428fafdef8a0396a3d6226d9548 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.483 2006/03/18 22:09:58 neilc Exp $
+ *       $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.484 2006/05/19 15:15:37 alvherre Exp $
  *
  * NOTES
  *
@@ -2182,6 +2182,9 @@ reaper(SIGNAL_ARGS)
                {
                        AutoVacPID = 0;
                        autovac_stopped();
+                       /* Tell the collector about process termination */
+                       pgstat_beterm(pid);
+
                        if (exitstatus != 0)
                                HandleChildCrash(pid, exitstatus,
                                                                 _("autovacuum process"));
index 90344385ca4a4702b60cdb1ea9716a89bc7a7e6f..362aa1d08ef7a12440170a8162ae9bef54c36e04 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.27 2006/03/05 15:58:43 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.28 2006/05/19 15:15:37 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -389,6 +389,7 @@ Datum
 pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
 {
        PgStat_StatBeEntry *beentry;
+       SockAddr        zero_clientaddr;
        int32           beid;
        char            remote_host[NI_MAXHOST];
        int                     ret;
@@ -405,6 +406,12 @@ pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
        if (!superuser() && beentry->userid != GetUserId())
                PG_RETURN_NULL();
 
+       /* A zeroed client addr means we don't know */
+       memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
+       if (memcmp(&(beentry->clientaddr), &zero_clientaddr,
+                          sizeof(zero_clientaddr) == 0))
+               PG_RETURN_NULL();
+
        switch (beentry->clientaddr.addr.ss_family)
        {
                case AF_INET:
@@ -432,6 +439,7 @@ Datum
 pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
 {
        PgStat_StatBeEntry *beentry;
+       SockAddr        zero_clientaddr;
        int32           beid;
        char            remote_port[NI_MAXSERV];
        int                     ret;
@@ -448,6 +456,12 @@ pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
        if (!superuser() && beentry->userid != GetUserId())
                PG_RETURN_NULL();
 
+       /* A zeroed client addr means we don't know */
+       memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
+       if (memcmp(&(beentry->clientaddr), &zero_clientaddr,
+                          sizeof(zero_clientaddr) == 0))
+               PG_RETURN_NULL();
+
        switch (beentry->clientaddr.addr.ss_family)
        {
                case AF_INET: