Re: [UPDATED] A GUC variable to replace PGBE_ACTIVITY_SIZE - Mailing list pgsql-patches

From Thomas Lee
Subject Re: [UPDATED] A GUC variable to replace PGBE_ACTIVITY_SIZE
Date
Msg-id 486101C0.9090006@vector-seven.com
Whole thread Raw
In response to Re: A GUC variable to replace PGBE_ACTIVITY_SIZE  ("Heikki Linnakangas" <heikki@enterprisedb.com>)
Responses Re: [UPDATED] A GUC variable to replace PGBE_ACTIVITY_SIZE  ("Heikki Linnakangas" <heikki@enterprisedb.com>)
List pgsql-patches
An updated patch for the track_activity_query_size GUC variable.

Made sure it's a context diff this time around, as per the wiki
documentation.

Cheers,
T
*** a/doc/src/sgml/config.sgml
--- b/doc/src/sgml/config.sgml
***************
*** 3331,3336 **** COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
--- 3331,3349 ----
        </listitem>
       </varlistentry>

+      <varlistentry id="guc-track-active-query-size" xreflabel="track_active_query_size">
+       <term><varname>track_active_query_size</varname> (<type>integer</type>)</term>
+       <indexterm>
+        <primary><varname>track_active_query_size</> configuration parameter</primary>
+       </indexterm>
+       <listitem>
+        Specifies the maximum number of characters used to track the currently
+        executing command for each active session. This parameter has a value
+        of 1024 by default.
+        Only superusers can change this setting.
+       </listitem>
+      </varlistentry>
+
       <varlistentry id="guc-track-counts" xreflabel="track_counts">
        <term><varname>track_counts</varname> (<type>boolean</type>)</term>
        <indexterm>
*** a/src/backend/postmaster/pgstat.c
--- b/src/backend/postmaster/pgstat.c
***************
*** 101,106 ****
--- 101,107 ----
  bool        pgstat_track_activities = false;
  bool        pgstat_track_counts = false;
  int            pgstat_track_functions = TRACK_FUNC_OFF;
+ int            pgstat_track_activity_query_size = PGBE_DEFAULT_ACTIVITY_SIZE;

  /*
   * BgWriter global statistics counters (unused in other processes).
***************
*** 2010,2015 **** pgstat_fetch_global(void)
--- 2011,2017 ----

  static PgBackendStatus *BackendStatusArray = NULL;
  static PgBackendStatus *MyBEEntry = NULL;
+ static char*            BackendActivityBuffer = NULL;


  /*
***************
*** 2025,2031 **** BackendStatusShmemSize(void)
  }

  /*
!  * Initialize the shared status array during postmaster startup.
   */
  void
  CreateSharedBackendStatus(void)
--- 2027,2052 ----
  }

  /*
!  * Ensures that every element of BackendStatusArray has a valid st_activity
!  * pointer.
!  */
! static void
! pgstat_initialize_activity_pointers(void)
! {
!     Size i;
!     PgBackendStatus* beentry = BackendStatusArray;
!     char*             buffer = BackendActivityBuffer;
!
!     for (i = 0; i < MaxBackends; i++) {
!         beentry->st_activity = buffer;
!         buffer += pgstat_track_activity_query_size;
!         beentry++;
!     }
! }
!
! /*
!  * Initialize the shared status array & activity buffer during postmaster
!  * startup.
   */
  void
  CreateSharedBackendStatus(void)
***************
*** 2044,2049 **** CreateSharedBackendStatus(void)
--- 2065,2081 ----
           */
          MemSet(BackendStatusArray, 0, size);
      }
+
+     size = mul_size(pgstat_track_activity_query_size, MaxBackends);
+     BackendActivityBuffer = (char*)
+         ShmemInitStruct("Backend Activity Buffer", size, &found);
+
+     if (!found)
+     {
+         MemSet(BackendActivityBuffer, 0, size);
+     }
+
+     pgstat_initialize_activity_pointers();
  }


***************
*** 2128,2134 **** pgstat_bestart(void)
      beentry->st_waiting = false;
      beentry->st_activity[0] = '\0';
      /* Also make sure the last byte in the string area is always 0 */
!     beentry->st_activity[PGBE_ACTIVITY_SIZE - 1] = '\0';

      beentry->st_changecount++;
      Assert((beentry->st_changecount & 1) == 0);
--- 2160,2166 ----
      beentry->st_waiting = false;
      beentry->st_activity[0] = '\0';
      /* Also make sure the last byte in the string area is always 0 */
!     beentry->st_activity[pgstat_track_activity_query_size - 1] = '\0';

      beentry->st_changecount++;
      Assert((beentry->st_changecount & 1) == 0);
***************
*** 2188,2194 **** pgstat_report_activity(const char *cmd_str)
      start_timestamp = GetCurrentStatementStartTimestamp();

      len = strlen(cmd_str);
!     len = pg_mbcliplen(cmd_str, len, PGBE_ACTIVITY_SIZE - 1);

      /*
       * Update my status entry, following the protocol of bumping
--- 2220,2226 ----
      start_timestamp = GetCurrentStatementStartTimestamp();

      len = strlen(cmd_str);
!     len = pg_mbcliplen(cmd_str, len, pgstat_track_activity_query_size - 1);

      /*
       * Update my status entry, following the protocol of bumping
***************
*** 2267,2272 **** pgstat_read_current_status(void)
--- 2299,2305 ----
      volatile PgBackendStatus *beentry;
      PgBackendStatus *localtable;
      PgBackendStatus *localentry;
+     char            *localactivity;
      int            i;

      Assert(!pgStatRunningInCollector);
***************
*** 2278,2283 **** pgstat_read_current_status(void)
--- 2311,2319 ----
      localtable = (PgBackendStatus *)
          MemoryContextAlloc(pgStatLocalContext,
                             sizeof(PgBackendStatus) * MaxBackends);
+     localactivity = (char *)
+         MemoryContextAlloc(pgStatLocalContext,
+                            pgstat_track_activity_query_size * MaxBackends);
      localNumBackends = 0;

      beentry = BackendStatusArray;
***************
*** 2296,2305 **** pgstat_read_current_status(void)
              int            save_changecount = beentry->st_changecount;

              /*
!              * XXX if PGBE_ACTIVITY_SIZE is really large, it might be best to
!              * use strcpy not memcpy for copying the activity string?
               */
              memcpy(localentry, (char *) beentry, sizeof(PgBackendStatus));

              if (save_changecount == beentry->st_changecount &&
                  (save_changecount & 1) == 0)
--- 2332,2345 ----
              int            save_changecount = beentry->st_changecount;

              /*
!              * XXX if pgstat_track_activity_query_size is really large,
!              * it might be best to use strcpy not memcpy for copying the
!              * activity string?
               */
              memcpy(localentry, (char *) beentry, sizeof(PgBackendStatus));
+             memcpy(localactivity, (char *) beentry->st_activity,
+                     pgstat_track_activity_query_size);
+             localentry->st_activity = localactivity;

              if (save_changecount == beentry->st_changecount &&
                  (save_changecount & 1) == 0)
***************
*** 2314,2322 **** pgstat_read_current_status(void)
          if (localentry->st_procpid > 0)
          {
              localentry++;
              localNumBackends++;
          }
!     }

      /* Set the pointer only after completion of a valid table */
      localBackendStatusTable = localtable;
--- 2354,2363 ----
          if (localentry->st_procpid > 0)
          {
              localentry++;
+             localactivity += pgstat_track_activity_query_size;
              localNumBackends++;
          }
!      }

      /* Set the pointer only after completion of a valid table */
      localBackendStatusTable = localtable;
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
***************
*** 1311,1316 **** static struct config_int ConfigureNamesInt[] =
--- 1311,1325 ----
      },

      {
+         {"track_activity_query_size", PGC_POSTMASTER, RESOURCES_MEM,
+             gettext_noop("Sets the maximum number of characters that will be displayed for
pg_stat_activity.current_query."),
+             NULL,
+         },
+         &pgstat_track_activity_query_size,
+         PGBE_DEFAULT_ACTIVITY_SIZE, 100, 102400, NULL, NULL
+     },
+
+     {
          {"temp_buffers", PGC_USERSET, RESOURCES_MEM,
              gettext_noop("Sets the maximum number of temporary buffers used by each session."),
              NULL,
*** a/src/backend/utils/misc/postgresql.conf.sample
--- b/src/backend/utils/misc/postgresql.conf.sample
***************
*** 364,369 ****
--- 364,370 ----
  #track_activities = on
  #track_counts = on
  #track_functions = none            # none, pl, all
+ #track_active_query_size = 1024
  #update_process_title = on


*** a/src/include/pgstat.h
--- b/src/include/pgstat.h
***************
*** 509,516 **** typedef struct PgStat_GlobalStats
   * ----------
   */

! /* Max length of st_activity string ... perhaps replace with a GUC var? */
! #define PGBE_ACTIVITY_SIZE    1024

  /* ----------
   * PgBackendStatus
--- 509,516 ----
   * ----------
   */

! /* Default length of st_activity string (see backend_activity_size GUC) */
! #define PGBE_DEFAULT_ACTIVITY_SIZE    1024

  /* ----------
   * PgBackendStatus
***************
*** 551,557 **** typedef struct PgBackendStatus
      bool        st_waiting;

      /* current command string; MUST be null-terminated */
!     char        st_activity[PGBE_ACTIVITY_SIZE];
  } PgBackendStatus;

  /*
--- 551,557 ----
      bool        st_waiting;

      /* current command string; MUST be null-terminated */
!     char       *st_activity;
  } PgBackendStatus;

  /*
***************
*** 578,583 **** typedef struct PgStat_FunctionCallUsage
--- 578,584 ----
  extern bool pgstat_track_activities;
  extern bool pgstat_track_counts;
  extern int    pgstat_track_functions;
+ extern int    pgstat_track_activity_query_size;

  /*
   * BgWriter statistics counters are updated directly by bgwriter and bufmgr

pgsql-patches by date:

Previous
From: "Heikki Linnakangas"
Date:
Subject: Re: A GUC variable to replace PGBE_ACTIVITY_SIZE
Next
From: "Pavel Stehule"
Date:
Subject: Re: variadic function support