summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorFujii Masao2026-05-14 03:30:34 +0000
committerFujii Masao2026-05-14 03:30:34 +0000
commit61f8a85a577fd0ea0bf924a88064187bed31eb48 (patch)
treee108e2de7ae21374f6032bb1175e3d323bc6979b /src/bin
parent0c025ab347dc37c93620ad3d040227d9ac0e32b2 (diff)
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
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/pgbench/pgbench.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 69b12a919a4..0b2bb9340b5 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -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);
}
/*