mirror of
https://github.com/postgres/postgres.git
synced 2026-05-28 04:35:45 -04:00
pgbench: fix verbose error message corruption with multiple threads
When pgbench runs with multiple threads and verbose error reporting is enabled (--verbose-errors), multiple clients can build verbose error messages concurrently. Previously, a function-local static PQExpBuffer was used for these messages, causing the buffer to be shared across threads. This was not thread-safe and could result in corrupted or incorrect log output. Fix this by using a local PQExpBufferData instead of a static buffer. This keeps verbose error messages correct during concurrent execution. Backpatch to v15, where this issue was introduced. Author: Fujii Masao <masao.fujii@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Alex Guo <guo.alex.hengchen@gmail.com> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Discussion: https://postgr.es/m/CAHGQGwER1AjGXpkKB9t9820NBhMQ_Ghv7=HsKeodUr3=SZsF4g@mail.gmail.com Backpatch-through: 15
This commit is contained in:
parent
0c025ab347
commit
61f8a85a57
1 changed files with 13 additions and 14 deletions
|
|
@ -3630,22 +3630,19 @@ getTransactionStatus(PGconn *con)
|
|||
static void
|
||||
printVerboseErrorMessages(CState *st, pg_time_usec_t *now, bool is_retry)
|
||||
{
|
||||
static PQExpBuffer buf = NULL;
|
||||
PQExpBufferData buf;
|
||||
|
||||
if (buf == NULL)
|
||||
buf = createPQExpBuffer();
|
||||
else
|
||||
resetPQExpBuffer(buf);
|
||||
initPQExpBuffer(&buf);
|
||||
|
||||
printfPQExpBuffer(buf, "client %d ", st->id);
|
||||
appendPQExpBufferStr(buf, (is_retry ?
|
||||
"repeats the transaction after the error" :
|
||||
"ends the failed transaction"));
|
||||
appendPQExpBuffer(buf, " (try %u", st->tries);
|
||||
printfPQExpBuffer(&buf, "client %d ", st->id);
|
||||
appendPQExpBufferStr(&buf, (is_retry ?
|
||||
"repeats the transaction after the error" :
|
||||
"ends the failed transaction"));
|
||||
appendPQExpBuffer(&buf, " (try %u", st->tries);
|
||||
|
||||
/* Print max_tries if it is not unlimited. */
|
||||
if (max_tries)
|
||||
appendPQExpBuffer(buf, "/%u", max_tries);
|
||||
appendPQExpBuffer(&buf, "/%u", max_tries);
|
||||
|
||||
/*
|
||||
* If the latency limit is used, print a percentage of the current
|
||||
|
|
@ -3654,12 +3651,14 @@ printVerboseErrorMessages(CState *st, pg_time_usec_t *now, bool is_retry)
|
|||
if (latency_limit)
|
||||
{
|
||||
pg_time_now_lazy(now);
|
||||
appendPQExpBuffer(buf, ", %.3f%% of the maximum time of tries was used",
|
||||
appendPQExpBuffer(&buf, ", %.3f%% of the maximum time of tries was used",
|
||||
(100.0 * (*now - st->txn_scheduled) / latency_limit));
|
||||
}
|
||||
appendPQExpBufferStr(buf, ")\n");
|
||||
appendPQExpBufferStr(&buf, ")\n");
|
||||
|
||||
pg_log_info("%s", buf->data);
|
||||
pg_log_info("%s", buf.data);
|
||||
|
||||
termPQExpBuffer(&buf);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue