Two small bugs in guc.c
I investigated the report at [1]/messages/by-id/CAK30z9T9gaF_isNquccZxi7agXCSjPjMsFXiifmkfu4VpZguxw@mail.gmail.com about pg_file_settings not reporting
invalid values of "log_connections". It turns out it's broken for
PGC_BACKEND and PGC_SU_BACKEND parameters, but not other ones.
The cause is a bit of premature optimization in this logic:
* If a PGC_BACKEND or PGC_SU_BACKEND parameter is changed in
* the config file, we want to accept the new value in the
* postmaster (whence it will propagate to
* subsequently-started backends), but ignore it in existing
* backends. ...
Upon detecting that case, set_config_option just returns -1 immediately
without bothering to validate the value. It should check for invalid
input before returning -1, which we can mechanize with a one-line fix:
- return -1;
+ changeVal = false;
While studying this, I also noted that the bit to prevent changes in
parallel workers seems seriously broken:
if (IsInParallelMode() && changeVal && action != GUC_ACTION_SAVE)
ereport(elevel,
(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
errmsg("cannot set parameters during a parallel operation")));
This is evidently assuming that ereport() won't return, which seems
like a very dubious assumption given the various values that elevel
can have. Maybe it's accidentally true -- I don't recall any
reports of trouble here -- but it sure looks fragile.
Hence, proposed patch attached.
regards, tom lane
[1]: /messages/by-id/CAK30z9T9gaF_isNquccZxi7agXCSjPjMsFXiifmkfu4VpZguxw@mail.gmail.com
Attachments:
v1-fix-set_config_option-logic-bugs.patchtext/x-diff; charset=us-ascii; name=v1-fix-set_config_option-logic-bugs.patchDownload
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 959a1c76bf..4126b90ad7 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -3412,9 +3412,12 @@ set_config_with_handle(const char *name, config_handle *handle,
* Other changes might need to affect other workers, so forbid them.
*/
if (IsInParallelMode() && changeVal && action != GUC_ACTION_SAVE)
+ {
ereport(elevel,
(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
errmsg("cannot set parameters during a parallel operation")));
+ return -1;
+ }
/* if handle is specified, no need to look up option */
if (!handle)
@@ -3513,7 +3516,9 @@ set_config_with_handle(const char *name, config_handle *handle,
* postmaster (whence it will propagate to
* subsequently-started backends), but ignore it in existing
* backends. This is a tad klugy, but necessary because we
- * don't re-read the config file during backend start.
+ * don't re-read the config file during backend start. Handle
+ * this by clearing changeVal but continuing, since we do want
+ * to report incorrect values.
*
* In EXEC_BACKEND builds, this works differently: we load all
* non-default settings from the CONFIG_EXEC_PARAMS file
@@ -3526,7 +3531,7 @@ set_config_with_handle(const char *name, config_handle *handle,
* applies.
*/
if (IsUnderPostmaster && !is_reload)
- return -1;
+ changeVal = false;
}
else if (context != PGC_POSTMASTER &&
context != PGC_BACKEND &&
On Tue Dec 26, 2023 at 1:02 PM CST, Tom Lane wrote:
I investigated the report at [1] about pg_file_settings not reporting
invalid values of "log_connections". It turns out it's broken for
PGC_BACKEND and PGC_SU_BACKEND parameters, but not other ones.
The cause is a bit of premature optimization in this logic:* If a PGC_BACKEND or PGC_SU_BACKEND parameter is changed in
* the config file, we want to accept the new value in the
* postmaster (whence it will propagate to
* subsequently-started backends), but ignore it in existing
* backends. ...Upon detecting that case, set_config_option just returns -1 immediately
without bothering to validate the value. It should check for invalid
input before returning -1, which we can mechanize with a one-line fix:- return -1; + changeVal = false;While studying this, I also noted that the bit to prevent changes in
parallel workers seems seriously broken:if (IsInParallelMode() && changeVal && action != GUC_ACTION_SAVE)
ereport(elevel,
(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
errmsg("cannot set parameters during a parallel operation")));This is evidently assuming that ereport() won't return, which seems
like a very dubious assumption given the various values that elevel
can have. Maybe it's accidentally true -- I don't recall any
reports of trouble here -- but it sure looks fragile.Hence, proposed patch attached.
Looks good to me.
--
Tristan Partin
Neon (https://neon.tech)