Re: display hot standby state in psql prompt - Mailing list pgsql-hackers

From Jim Jones
Subject Re: display hot standby state in psql prompt
Date
Msg-id 7324243e-0ae6-4873-8111-d221ade63f88@uni-muenster.de
Whole thread Raw
In response to Re: display hot standby state in psql prompt  (Nathan Bossart <nathandbossart@gmail.com>)
List pgsql-hackers

On 28/10/2025 17:42, Nathan Bossart wrote:
> IIUC the problem is that we use GUC_ACTION_SET for those even though they
> are reset at transaction end by the routines in xact.c.  Something like the
> following seems to be enough to get it working as expected in some basic
> tests, but there are probably other things to consider.  Keep in mind that
> previous proposals to mark transaction_read_only as GUC_REPORT have been
> rejected, too.
> 
> diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
> index a82286cc98a..d0bbb5aff19 100644
> --- a/src/backend/utils/misc/guc.c
> +++ b/src/backend/utils/misc/guc.c
> @@ -3349,6 +3349,12 @@ set_config_with_handle(const char *name, config_handle *handle,
>      bool        prohibitValueChange = false;
>      bool        makeDefault;
> 
> +    if (action == GUC_ACTION_SET &&
> +        (strcmp(name, "transaction_isolation") == 0 ||
> +         strcmp(name, "transaction_read_only") == 0 ||
> +         strcmp(name, "transaction_deferrable") == 0))
> +        action = GUC_ACTION_LOCAL;
> +
>      if (elevel == 0)
>      {
>          if (source == PGC_S_DEFAULT || source == PGC_S_FILE)

Thanks! It does solve the current problem (don't mind the debug messages):

postgres=# \set PROMPT1 '[%i] # '
DEBUG: hs='off' ro='off' tr='off'

[read/write] # BEGIN;
BEGIN
DEBUG: hs='off' ro='off' tr='off'

[read/write] # SET transaction_read_only TO on;
SET
DEBUG: hs='off' ro='off' tr='on'

[read-only] # END;
COMMIT
DEBUG: hs='off' ro='off' tr='off'

But in other cases it now fails, because the parameter status of
transaction_read_only isn't being updated:

postgres=# \set PROMPT1 '[%i] # '
DEBUG: hs='on' ro='off' tr='on'

[read-only] # SELECT pg_promote();
 pg_promote
------------
 t
(1 row)

DEBUG: hs='off' ro='off' tr='on'

[read-only] # SHOW transaction_read_only;
 transaction_read_only
-----------------------
 off
(1 row)

DEBUG: hs='off' ro='off' tr='on'


I played a bit with the following hack, which solves the
transaction_read_only issue ...


diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index a82286cc98..5c7748fbba 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2551,9 +2551,19 @@ ReportChangedGUCOptions(void)
         * transition from false to true.
         */
        if (in_hot_standby_guc && !RecoveryInProgress())
+       {
                SetConfigOption("in_hot_standby", "false",
                                                PGC_INTERNAL,
PGC_S_OVERRIDE);

+               /*
+                * Similarly, when exiting hot standby,
transaction_read_only may need
+                * to be reported. During hot standby, writes were
blocked regardless
+                * of the transaction_read_only setting, so report the
actual state now.
+                */
+               SetConfigOption("transaction_read_only","off",
+                                               PGC_INTERNAL,
PGC_S_OVERRIDE);
+       }
+
        /* Transmit new values of interesting variables */
        slist_foreach_modify(iter, &guc_report_list)
        {
@@ -3349,6 +3359,12 @@ set_config_with_handle(const char *name,
config_handle *handle,
        bool            prohibitValueChange = false;
        bool            makeDefault;

+       if (action == GUC_ACTION_SET &&
+               (strcmp(name, "transaction_isolation") == 0 ||
+                strcmp(name, "transaction_read_only") == 0 ||
+                strcmp(name, "transaction_deferrable") == 0))
+               action = GUC_ACTION_LOCAL;
+
        if (elevel == 0)
        {
                if (source == PGC_S_DEFAULT || source == PGC_S_FILE)


== tests ==

postgres=# \set PROMPT1 '[%i] # '
DEBUG: hs='on' ro='off' tr='on'

[read-only] # SELECT pg_promote();
 pg_promote
------------
 t
(1 row)

DEBUG: hs='off' ro='off' tr='off'

[read/write] # BEGIN;
BEGIN
DEBUG: hs='off' ro='off' tr='off'

[read/write] # SET TRANSACTION READ ONLY;
SET
DEBUG: hs='off' ro='off' tr='on'

[read-only] # END;
COMMIT
DEBUG: hs='off' ro='off' tr='off'

[read/write] # SET default_transaction_read_only TO on;
SET
DEBUG: hs='off' ro='on' tr='off'

[read-only] # SET default_transaction_read_only TO off;
SET
DEBUG: hs='off' ro='off' tr='off'
[read/write] #

... but I'm still not sure of its impact. I guess I need to go back to
the drawing board on this one.

Thanks!

Best, Jim








pgsql-hackers by date:

Previous
From: Michael Paquier
Date:
Subject: Re: Remove specific _\n code in TAP for Windows
Next
From: Michael Paquier
Date:
Subject: Re: Bug in pg_stat_statements