Re: libpq debug log

From: Kyotaro Horiguchi <horikyota(dot)ntt(at)gmail(dot)com>
To: alvherre(at)alvh(dot)no-ip(dot)org
Cc: iwata(dot)aya(at)fujitsu(dot)com, tsunakawa(dot)takay(at)fujitsu(dot)com, tgl(at)sss(dot)pgh(dot)pa(dot)us, k(dot)jamison(at)fujitsu(dot)com, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: libpq debug log
Date: 2021-03-11 01:20:23
Message-ID: 20210311.102023.1662848057196261831.horikyota.ntt@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

At Wed, 10 Mar 2021 10:31:27 -0300, "'alvherre(at)alvh(dot)no-ip(dot)org'" <alvherre(at)alvh(dot)no-ip(dot)org> wrote in
> On 2021-Mar-10, iwata(dot)aya(at)fujitsu(dot)com wrote:
>
> > Hi all,
> >
> > Following all reviewer's advice, I have created a new patch.
> >
> > In this patch, I add only two tracing entry points; I call pqTraceOutputMsg(PGconn conn, int msgCursor, PGCommSource commsource) in pqParseInput3 () and pqPutMsgEnd () to output log.
> > The argument contains message first byte offset called msgCursor because it is simpler to specify the buffer pointer in the caller.
> >
> > In pqTraceOutputMsg(), the content common to all protocol messages (first timestamp, < or >, first 1 byte, and length) are output first and after that each protocol message contents is output. I referred to pqParseInput3 () , fe-exec.c and documentation page for that part.
> >
> > This fix almost eliminates if(conn->Pfdebug) that was built into the code for other features.
>
> This certainly looks much better! Thanks for getting it done so
> quickly.
>
> I didn't review the code super closely. I do see a compiler warning:

+1 for the thanks for the quick work. I have some random comments
after a quick look on it.

The individual per-type-output functions are designed to fit to the
corresponding pqGet*() functions. On the other hand, now that we read
the message bytes knowing the exact format in advance as you did in
pqTraceOutputMsg(). So the complexity exist in the functions can be
eliminated by separating them into more type specific output
functions. For example, pqTraceOutputInt() is far simplified by
spliting it into pqTraceOutputInt16() and -32().

The output functions copy message bytes into local variable but the
same effect can be obtained by just casing via typed pointer type.

uint32 tmp4;
..
memcpy(&tmp4, buf + *cursor, 4);
result = (int) pg_ntoh32(tmp4);

can be written as

result = pg_ntoh32(* (uint32 *) (buf + *cursor));

I think we can get rid of copying in the output functions for String
and Bytes in different ways.

Now that we can manage our own reading pointer within
pqTraceOutputMsg(), the per-type-output functions can work only on the
reading pointer instead of buffer pointer and cursor, and length.
*I*'d want to make the output functions move the reading pointer by
themseves. pqTradeOutputMsg can be as simplified as the follows doing
this. End-of-message pointer may be useful to check read-overrunning
on the message buffer.

switch (id) {
case 'R':
pqTraceOutputInt32(&p, endptr, conn->Pfdebug);
fputc('\n', conn->Pfdebug);
break;
case 'K':
pqTraceOutputInt32(&p, endptr, conn->Pfdebug));
pqTraceOutputInt32(&p, endptr, conn->Pfdebug));
...

+ char *prefix = commsource == MSGDIR_FROM_BACKEND ? "<" : ">";
+ int LogEnd = commsource == MSGDIR_FROM_BACKEND ? conn->inCursor : conn->outMsgEnd;
+ char *logBuffer = commsource == MSGDIR_FROM_BACKEND ? conn->inBuffer
..
+ if (commsource == MSGDIR_FROM_BACKEND)
+ id = logBuffer[LogCursor++];

Repeated usage of the ternaly operator on the same condition makes
code hard-to-read. It is simpler to consolidate them into one if-else
statement.

+ result = (int) pg_ntoh32(result32);
+ if (result == NEGOTIATE_SSL_CODE)

Maybe I'm missing something, but the above doesn't seem working. I
didn't see such message when making a SSL connection.

+ /* Protocol 2.0 does not support tracing. */
+ if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
+ return;

We can write that message out into tracing file.

+void
+PQtraceSetFlags(PGconn *conn, int flags)
+{
+ if (conn == NULL)
+ return;
+ /* Protocol 2.0 is not supported. */
+ if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
+ return;
+ /* If PQtrace() failed, do nothing. */
+ if (conn->Pfdebug == NULL)
+ return;
+ conn->traceFlags = flags;

Pfdebug is always NULL for V2 protocol there, so it can be an
assertion?

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Thomas Munro 2021-03-11 01:20:38 Re: fdatasync performance problem with large number of DB files
Previous Message Peter Geoghegan 2021-03-11 01:11:58 Re: Removing vacuum_cleanup_index_scale_factor