Introduce a new GUC_REPORT setting "in_hot_standby".
authorTom Lane <[email protected]>
Tue, 5 Jan 2021 21:18:01 +0000 (16:18 -0500)
committerTom Lane <[email protected]>
Tue, 5 Jan 2021 21:18:05 +0000 (16:18 -0500)
Aside from being queriable via SHOW, this value is sent to the client
immediately at session startup, and again later on if the server gets
promoted to primary during the session.  The immediate report will be
used in an upcoming  to avoid an extra round trip when trying to
connect to a primary server.

Haribabu Kommi, Greg Nancarrow, Tom Lane; reviewed at various times
by Laurenz Albe, Takayuki Tsunakawa, Peter Smith.

Discussion: https://postgr.es/m/CAF3+xM+8-ztOkaV9gHiJ3wfgENTq97QcjXQt+rbFQ6F7oNzt9A@mail.gmail.com

doc/src/sgml/config.sgml
doc/src/sgml/high-availability.sgml
doc/src/sgml/libpq.sgml
doc/src/sgml/protocol.sgml
src/backend/utils/misc/check_guc
src/backend/utils/misc/guc.c

index 67de4150b8e48b9759c07b3111a5a7a80201ffc6..2a90d011db53b996c94fd033300b541469690a83 100644 (file)
@@ -9600,13 +9600,14 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
     <title>Preset Options</title>
 
     <para>
-     The following <quote>parameters</quote> are read-only, and are determined
-     when <productname>PostgreSQL</productname> is compiled or when it is
-     installed. As such, they have been excluded from the sample
+     The following <quote>parameters</quote> are read-only.
+     As such, they have been excluded from the sample
      <filename>postgresql.conf</filename> file.  These options report
      various aspects of <productname>PostgreSQL</productname> behavior
      that might be of interest to certain applications, particularly
      administrative front-ends.
+     Most of them are determined when <productname>PostgreSQL</productname>
+     is compiled or when it is installed.
     </para>
 
     <variablelist>
@@ -9651,10 +9652,11 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
       </term>
       <listitem>
        <para>
-        On Unix systems this parameter reports the permissions of the data
-        directory defined by (<xref linkend="guc-data-directory"/>) at startup.
+        On Unix systems this parameter reports the permissions the data
+        directory (defined by <xref linkend="guc-data-directory"/>)
+        had at server startup.
         (On Microsoft Windows this parameter will always display
-        <literal>0700</literal>). See
+        <literal>0700</literal>.) See
         <xref linkend="app-initdb-allow-group-access"/> for more information.
        </para>
       </listitem>
@@ -9695,6 +9697,23 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-in-hot-standby" xreflabel="in_hot_standby">
+      <term><varname>in_hot_standby</varname> (<type>boolean</type>)
+      <indexterm>
+       <primary><varname>in_hot_standby</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Reports whether the server is currently in hot standby mode.  When
+        this is <literal>on</literal>, all transactions are forced to be
+        read-only.  Within a session, this can change only if the server is
+        promoted to be primary.  See <xref linkend="hot-standby"/> for more
+        information.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-lc-collate" xreflabel="lc_collate">
       <term><varname>lc_collate</varname> (<type>string</type>)
       <indexterm>
index 19d7bd2b28faa3c30cb8ba204e58ff1178a5b97e..04f75020e44cbf0142cd1e808f3c8ba71db76c52 100644 (file)
@@ -1859,8 +1859,11 @@ if (!triggered)
    </para>
 
    <para>
-    Users will be able to tell whether their session is read-only by
-    issuing <command>SHOW transaction_read_only</command>.  In addition, a set of
+    Users can determine whether hot standby is currently active for their
+    session by issuing <command>SHOW in_hot_standby</command>.
+    (In server versions before 14, the <varname>in_hot_standby</varname>
+    parameter did not exist; a workable substitute method for older servers
+    is <command>SHOW transaction_read_only</command>.)  In addition, a set of
     functions (<xref linkend="functions-recovery-info-table"/>) allow users to
     access information about the standby server. These allow you to write
     programs that are aware of the current state of the database. These
index a5db58d46806cef8f7df21026b278996aa4f9ce4..2bb3bf77e432d5cf5add5ed8d37e8ea5674587d0 100644 (file)
@@ -2150,6 +2150,7 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName);
        <varname>server_encoding</varname>,
        <varname>client_encoding</varname>,
        <varname>application_name</varname>,
+       <varname>in_hot_standby</varname>,
        <varname>is_superuser</varname>,
        <varname>session_authorization</varname>,
        <varname>DateStyle</varname>,
@@ -2162,7 +2163,10 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName);
        <varname>standard_conforming_strings</varname> was not reported by releases
        before 8.1;
        <varname>IntervalStyle</varname> was not reported by releases before 8.4;
-       <varname>application_name</varname> was not reported by releases before 9.0.)
+       <varname>application_name</varname> was not reported by releases before
+       9.0;
+       <varname>in_hot_standby</varname> was not reported by releases before
+       14.)
        Note that
        <varname>server_version</varname>,
        <varname>server_encoding</varname> and
index 98b42bb2692310f4b0c553363579301908827741..24f7b21ecbd45cf761a19ac0b21b805893fefbe6 100644 (file)
@@ -1278,6 +1278,7 @@ SELCT 1/0;<!-- this typo is intentional -->
     <varname>server_encoding</varname>,
     <varname>client_encoding</varname>,
     <varname>application_name</varname>,
+    <varname>in_hot_standby</varname>,
     <varname>is_superuser</varname>,
     <varname>session_authorization</varname>,
     <varname>DateStyle</varname>,
@@ -1290,7 +1291,10 @@ SELCT 1/0;<!-- this typo is intentional -->
     <varname>standard_conforming_strings</varname> was not reported by releases
     before 8.1;
     <varname>IntervalStyle</varname> was not reported by releases before 8.4;
-    <varname>application_name</varname> was not reported by releases before 9.0.)
+    <varname>application_name</varname> was not reported by releases before
+    9.0;
+    <varname>in_hot_standby</varname> was not reported by releases before
+    14.)
     Note that
     <varname>server_version</varname>,
     <varname>server_encoding</varname> and
index 416a0875b6c938ebd06f655e6987304e35f80459..b171ef0e4ff3f8376b47adc6f1d7ee61e510438d 100755 (executable)
@@ -16,7 +16,7 @@
 ## if an option is valid but shows up in only one file (guc.c but not
 ## postgresql.conf.sample), it should be listed here so that it
 ## can be ignored
-INTENTIONALLY_NOT_INCLUDED="debug_deadlocks \
+INTENTIONALLY_NOT_INCLUDED="debug_deadlocks in_hot_standby \
 is_superuser lc_collate lc_ctype lc_messages lc_monetary lc_numeric lc_time \
 pre_auth_delay role seed server_encoding server_version server_version_num \
 session_authorization trace_lock_oidmin trace_lock_table trace_locks trace_lwlocks \
index 2779da8a6936bf76456d7b244bd9defc716aa6c1..383b7d0d710c2edc3571c74136ea24fdb88266a8 100644 (file)
@@ -209,6 +209,7 @@ static bool check_cluster_name(char **newval, void **extra, GucSource source);
 static const char *show_unix_socket_permissions(void);
 static const char *show_log_file_mode(void);
 static const char *show_data_directory_mode(void);
+static const char *show_in_hot_standby(void);
 static bool check_backtrace_functions(char **newval, void **extra, GucSource source);
 static void assign_backtrace_functions(const char *newval, void *extra);
 static bool check_recovery_target_timeline(char **newval, void **extra, GucSource source);
@@ -610,6 +611,7 @@ static int  wal_block_size;
 static bool data_checksums;
 static bool integer_datetimes;
 static bool assert_enabled;
+static bool in_hot_standby;
 static char *recovery_target_timeline_string;
 static char *recovery_target_string;
 static char *recovery_target_xid_string;
@@ -1844,6 +1846,17 @@ static struct config_bool ConfigureNamesBool[] =
        NULL, NULL, NULL
    },
 
+   {
+       {"in_hot_standby", PGC_INTERNAL, PRESET_OPTIONS,
+           gettext_noop("Shows whether hot standby is currently active."),
+           NULL,
+           GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
+       },
+       &in_hot_standby,
+       false,
+       NULL, NULL, show_in_hot_standby
+   },
+
    {
        {"allow_system_table_mods", PGC_SUSET, DEVELOPER_OPTIONS,
            gettext_noop("Allows modifications of the structure of system tables."),
@@ -6248,6 +6261,14 @@ BeginReportingGUCOptions(void)
 
    reporting_enabled = true;
 
+   /*
+    * Hack for in_hot_standby: initialize with the value we're about to send.
+    * (This could be out of date by the time we actually send it, in which
+    * case the next ReportChangedGUCOptions call will send a duplicate
+    * report.)
+    */
+   in_hot_standby = RecoveryInProgress();
+
    /* Transmit initial values of interesting variables */
    for (i = 0; i < num_guc_variables; i++)
    {
@@ -6280,6 +6301,23 @@ ReportChangedGUCOptions(void)
    if (!reporting_enabled)
        return;
 
+   /*
+    * Since in_hot_standby isn't actually changed by normal GUC actions, we
+    * need a hack to check whether a new value needs to be reported to the
+    * client.  For speed, we rely on the assumption that it can never
+    * transition from false to true.
+    */
+   if (in_hot_standby && !RecoveryInProgress())
+   {
+       struct config_generic *record;
+
+       record = find_option("in_hot_standby", false, ERROR);
+       Assert(record != NULL);
+       record->status |= GUC_NEEDS_REPORT;
+       report_needed = true;
+       in_hot_standby = false;
+   }
+
    /* Quick exit if no values have been changed */
    if (!report_needed)
        return;
@@ -11773,6 +11811,18 @@ show_data_directory_mode(void)
    return buf;
 }
 
+static const char *
+show_in_hot_standby(void)
+{
+   /*
+    * We display the actual state based on shared memory, so that this GUC
+    * reports up-to-date state if examined intra-query.  The underlying
+    * variable in_hot_standby changes only when we transmit a new value to
+    * the client.
+    */
+   return RecoveryInProgress() ? "on" : "off";
+}
+
 /*
  * We split the input string, where commas separate function names
  * and certain whitespace chars are ignored, into a \0-separated (and