From: | Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com> |
---|---|
To: | Melanie Plageman <melanieplageman(at)gmail(dot)com> |
Cc: | Andres Freund <andres(at)anarazel(dot)de>, Fujii Masao <masao(dot)fujii(at)oss(dot)nttdata(dot)com>, Guillaume Lelarge <guillaume(at)lelarge(dot)info>, Pg Hackers <pgsql-hackers(at)postgresql(dot)org>, Daniel Gustafsson <daniel(at)yesql(dot)se>, andrey(dot)chudnovskiy(at)microsoft(dot)com, Jelte Fennema-Nio <postgres(at)jeltef(dot)nl>, Jacob Champion <jacob(dot)champion(at)enterprisedb(dot)com> |
Subject: | Re: Log connection establishment timings |
Date: | 2025-03-06 14:56:16 |
Message-ID: | Z8m3kNLsxQUlfSB8@ip-10-97-1-34.eu-west-3.compute.internal |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi,
On Wed, Mar 05, 2025 at 06:40:10PM -0500, Melanie Plageman wrote:
> On Wed, Mar 5, 2025 at 10:46 AM Melanie Plageman
> <melanieplageman(at)gmail(dot)com> wrote:
> >
> > As such, I wonder if my PGC_SET idea is not worth the effort and I
> > should revise the earlier patch version which specified the stages but
> > allow for on, off, true, yes, 1 for backwards compatibility and not
> > include disconnections (so we don't remove the log_disconnections GUC
> > this release).
>
> Okay! Attached v10 does this.
Great, thanks for it!
> It turns log_connections into a string
> but supports all the common values of the current log_connections
> boolean.
>
> So, you can specify
> log_connections = authorized,authenticated
Yeah, when used like psql -d "options=-clog_connections=authorized,authenticated"
but needs to be log_connections = 'authorized,authenticated' in the postgresql.conf
file. That makes fully sense.
> But, this is the first version of the patch where I am happy with the
> interface and with the code. It isn't a breaking change (since on,
> off, true, false, etc still work), so I think it is still okay to
> target 18.
A few comments about 0001:
=== 1
we have this:
+ /* For backwards compatability, we accept these tokens by themselves */
+ static const struct config_enum_entry compat_options[] = {
+ {"off", 0},
+ {"false", 0},
+ {"no", 0},
+ {"0", 0},
+ {"on", LOG_CONNECTION_ON},
+ {"true", LOG_CONNECTION_ON},
+ {"yes", LOG_CONNECTION_ON},
+ {"1", LOG_CONNECTION_ON},
+ };
and
+typedef enum LogConnectionOption
+{
+ LOG_CONNECTION_RECEIVED = (1 << 0),
+ LOG_CONNECTION_AUTHENTICATED = (1 << 1),
+ LOG_CONNECTION_AUTHORIZED = (1 << 2),
+ LOG_CONNECTION_ON =
+ LOG_CONNECTION_RECEIVED |
+ LOG_CONNECTION_AUTHENTICATED |
+ LOG_CONNECTION_AUTHORIZED,
+ LOG_CONNECTION_ALL =
+ LOG_CONNECTION_ON,
+} LogConnectionOption;
what do you think about also doing?
static const struct config_enum_entry compat_options[] = {
- {"off", 0},
- {"false", 0},
- {"no", 0},
- {"0", 0},
+ {"off", LOG_CONNECTION_OFF},
+ {"false", LOG_CONNECTION_OFF},
+ {"no", LOG_CONNECTION_OFF},
+ {"0", LOG_CONNECTION_OFF},
and
typedef enum LogConnectionOption
{
+ LOG_CONNECTION_OFF = 0,
LOG_CONNECTION_RECEIVED = (1 << 0),
and
/* If an empty string was passed, we're done. */
if (list_length(elemlist) == 0)
return LOG_CONNECTION_OFF;
=== 2
- if (Log_connections && status == STATUS_OK &&
+ if (log_connections & LOG_CONNECTION_AUTHENTICATED &&
+ status == STATUS_OK &&
Worth to add extra parentheses around (log_connections & LOG_CONNECTION_AUTHENTICATED)?
Not necessary as bitwise AND has higher precedence than logical AND but I think
it makes the code more readable.
=== 3
+ /* If an empty string was passed, we're done. */
+ if (list_length(elemlist) == 0)
+ return 0;
+
+ /*
+ * Now check for the backwards compatability options. They must always be
+ * specified on their own, so we error out if the first option is a
+ * backwards compatability option and other options are also specified.
+ */
+ item = linitial(elemlist);
+
+ for (size_t i = 0; i < lengthof(compat_options); i++)
+ {
+ struct config_enum_entry option = compat_options[i];
+
+ if (pg_strcasecmp(item, option.name) != 0)
+ continue;
+
+ if (list_length(elemlist) > 1)
+ {
what about storing the list_length(elemlist) at the start to avoid the multiple
list_length(elemlist) calls?
=== 4
+ /* If an empty string was passed, we're done. */
s/done./done/? (Looking at the one line comments around)
=== 5
+ /* Now check the stage-specific options. */
s/options./options/? (Looking at the one line comments around)
=== 6
+ /* For backwards compatability, we accept these tokens by themselves */
Typo: compatability/compatibility
, seen multiple times:
$ git grep compatability
doc/src/sgml/config.sgml: For the purposes of backwards compatability, <literal>on</literal>,
src/backend/tcop/backend_startup.c: /* For backwards compatability, we accept these tokens by themselves */
src/backend/tcop/backend_startup.c: * Now check for the backwards compatability options. They must always be
src/backend/tcop/backend_startup.c: * backwards compatability option and other options are also specified.
src/include/tcop/backend_startup.h: * ON is backwards compatability alias for the connection events that were
=== 7
+ /* Time for cleanup and allocating `extra` if we succeeded */
+ pfree(rawstring);
+ list_free(elemlist);
+
+ /* We didn't succeed */
+ if (flags == -1)
+ return false;
I feel the first comment is confusing, maybe the "allocating `extra` if we succeeded"
should be put after the "if (flags == -1)" part?
The logic in 0001 looks good to me, also I did a few tests and that looks ok
seen from here.
> In 0002, because we take the timings for all wal sender and client
> connection backends, now the new log message emitted in 0002 is more
> like a stage, so I've named that option "ready_for_query". As such, I
> wonder if I should change the output message to reflect that. What do
> you think?
>
hmm, I'm tempted to vote for "timings". I understand your point but "timings"
more directly communicates that this option enables timing measurements,
whereas "ready_for_query" describes just one particular state.
I think I could vote for "ready_for_query" should the GUC be log_connection_stages
(and not log_connections).
I also think that we can keep "reported_first_ready_for_query", "send_ready_for_query"
in the code though (even if the GUC option is changed to "timings").
A few comments about 0002:
==== 8
+ if (IsConnectionBackend(child_type))
IsConnectionBackend is fine by me.
=== 9
+ /* Calculate fork duration since we have start and end times. */
s/times./times/? (Looking at the one line comments around)
=== 10
+ /* Will be used to calculate total connection setup duration. */
s/duration./duration/? (Looking at the one line comments around)
=== 11
+ /* How long it took the backend to be forked. */
s/forked./forked/? (Looking at the one line comments around)
=== 12
+ if (!reported_first_ready_for_query &&
+ log_connections & LOG_CONNECTION_READY_FOR_QUERY &&
+ IsConnectionBackend(MyBackendType))
same as comment === 2 above.
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
From | Date | Subject | |
---|---|---|---|
Next Message | Sami Imseih | 2025-03-06 15:04:35 | Re: track generic and custom plans in pg_stat_statements |
Previous Message | Bykov Ivan | 2025-03-06 14:51:23 | RE: Query ID Calculation Fix for DISTINCT / ORDER BY and LIMIT / OFFSET |