v3-0001-Convert-wait_event_info-to-64-bits-expose-lower-3.patch
text/x-patch
Filename: v3-0001-Convert-wait_event_info-to-64-bits-expose-lower-3.patch
Type: text/x-patch
Part: 1
From 342c2d5037620763ac20f571a3af3d4d06516b82 Mon Sep 17 00:00:00 2001
From: Jakub Wartak <jakub.wartak@enterprisedb.com>
Date: Wed, 12 Nov 2025 12:14:16 +0100
Subject: [PATCH v3 1/2] Convert wait_event_info to 64-bits, expose lower
32-bit as new wait_event_arg
Provide also some very basic wait_event_arg demos.
---
contrib/dblink/dblink.c | 2 +-
contrib/postgres_fdw/connection.c | 6 +-
src/backend/access/transam/xlogarchive.c | 2 +-
src/backend/catalog/system_views.sql | 1 +
src/backend/replication/syncrep.c | 48 ++++++-
src/backend/replication/walsender.c | 10 +-
src/backend/storage/aio/aio_io.c | 6 +-
src/backend/storage/file/fd.c | 18 +--
src/backend/storage/ipc/barrier.c | 2 +-
src/backend/storage/ipc/latch.c | 4 +-
src/backend/storage/ipc/standby.c | 6 +-
src/backend/storage/ipc/waiteventset.c | 2 +-
src/backend/storage/lmgr/condition_variable.c | 4 +-
src/backend/storage/lmgr/lwlock.c | 5 +-
src/backend/storage/lmgr/proc.c | 7 +-
src/backend/storage/lmgr/s_lock.c | 2 +-
src/backend/storage/smgr/md.c | 3 +-
src/backend/utils/activity/backend_status.c | 3 +-
.../activity/generate-wait_event_types.pl | 12 +-
src/backend/utils/activity/wait_event.c | 88 ++++++++-----
src/backend/utils/adt/misc.c | 3 +-
src/backend/utils/adt/pgstatfuncs.c | 124 ++++++++++--------
src/backend/utils/adt/waitfuncs.c | 4 +-
src/include/access/xlogarchive.h | 2 +-
src/include/catalog/pg_proc.dat | 6 +-
src/include/libpq/libpq-be-fe-helpers.h | 20 +--
src/include/storage/barrier.h | 2 +-
src/include/storage/condition_variable.h | 4 +-
src/include/storage/fd.h | 22 ++--
src/include/storage/latch.h | 4 +-
src/include/storage/lwlock.h | 2 +-
src/include/storage/proc.h | 4 +-
src/include/storage/waiteventset.h | 2 +-
src/include/utils/wait_classes.h | 20 +--
src/include/utils/wait_event.h | 43 +++---
.../injection_points/injection_points.c | 2 +-
src/test/modules/test_shm_mq/setup.c | 2 +-
src/test/modules/worker_spi/worker_spi.c | 2 +-
src/test/regress/expected/rules.out | 9 +-
39 files changed, 301 insertions(+), 207 deletions(-)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 8bf8fc8ea2f..aa4ae8ec480 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -144,7 +144,7 @@ static HTAB *remoteConnHash = NULL;
/* custom wait event values, retrieved from shared memory */
static uint32 dblink_we_connect = 0;
-static uint32 dblink_we_get_conn = 0;
+static uint64 dblink_we_get_conn = 0;
static uint32 dblink_we_get_result = 0;
/*
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 953c2e0ab82..49e80029465 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -86,9 +86,9 @@ static unsigned int prep_stmt_number = 0;
static bool xact_got_connection = false;
/* custom wait event values, retrieved from shared memory */
-static uint32 pgfdw_we_cleanup_result = 0;
-static uint32 pgfdw_we_connect = 0;
-static uint32 pgfdw_we_get_result = 0;
+static uint64 pgfdw_we_cleanup_result = 0;
+static uint64 pgfdw_we_connect = 0;
+static uint64 pgfdw_we_get_result = 0;
/*
* Milliseconds to wait to cancel an in-progress query or execute a cleanup
diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c
index 1ef1713c91a..59547e1e3da 100644
--- a/src/backend/access/transam/xlogarchive.c
+++ b/src/backend/access/transam/xlogarchive.c
@@ -293,7 +293,7 @@ not_available:
*/
void
ExecuteRecoveryCommand(const char *command, const char *commandName,
- bool failOnSignal, uint32 wait_event_info)
+ bool failOnSignal, uint64 wait_event_info)
{
char *xlogRecoveryCmd;
char lastRestartPointFname[MAXPGPATH];
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 086c4c8fb6f..b8bd711f0e3 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -915,6 +915,7 @@ CREATE VIEW pg_stat_activity AS
S.state_change,
S.wait_event_type,
S.wait_event,
+ S.wait_event_arg,
S.state,
S.backend_xid,
S.backend_xmin,
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index a0c79958fd5..c624bb919b6 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -78,6 +78,7 @@
#include "common/int.h"
#include "miscadmin.h"
#include "pgstat.h"
+#include "portability/instr_time.h"
#include "replication/syncrep.h"
#include "replication/walsender.h"
#include "replication/walsender_private.h"
@@ -270,7 +271,8 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
*/
for (;;)
{
- int rc;
+ int rc, i;
+ uint32_t wait_event_arg_pid;
/* Must reset the latch before testing state. */
ResetLatch(MyLatch);
@@ -328,8 +330,48 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
* Wait on latch. Any condition that should wake us up will set the
* latch, so no need for timeout.
*/
- rc = WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1,
- WAIT_EVENT_SYNC_REP);
+
+
+ /*
+ * XXX/DEMO syncrep get pid of LSN, performance impact of spinlocking here is unknown
+ */
+ for (i = 0; i < max_wal_senders; i++)
+ {
+ WalSnd *walsnd = &WalSndCtl->walsnds[i];
+ XLogRecPtr wallsn;
+ pid_t walpid;
+
+ /* potentially we could NOT take those spinlocks to not loose performance? */
+ SpinLockAcquire(&walsnd->mutex);
+ walpid = walsnd->pid;
+ switch (mode)
+ {
+ case SYNC_REP_WAIT_WRITE:
+ wallsn = walsnd->write;
+ break;
+ case SYNC_REP_WAIT_FLUSH:
+ wallsn = walsnd->flush;
+ break;
+ case SYNC_REP_WAIT_APPLY:
+ wallsn = walsnd->apply;
+ break;
+ default:
+ wallsn = InvalidXLogRecPtr;
+ }
+ SpinLockRelease(&walsnd->mutex);
+ if (walpid == 0)
+ continue;
+
+ //elog(LOG, "walpid %d analysis, our LSN=%X/%08X walsndLSN=%X/%08X", walpid, LSN_FORMAT_ARGS(lsn), LSN_FORMAT_ARGS(wallsn));
+
+ if(wallsn <= lsn) {
+ elog(LOG, "walpid %d selected", walpid);
+ wait_event_arg_pid = walpid;
+ break;
+ }
+ }
+ rc = WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_TIMEOUT, 100,
+ WAIT_EVENT_SYNC_REP | wait_event_arg_pid);
/*
* If the postmaster dies, we'll probably never get an acknowledgment,
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index fc8f8559073..76c9e0273c5 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -282,7 +282,7 @@ static void WalSndKeepalive(bool requestReply, XLogRecPtr writePtr);
static void WalSndKeepaliveIfNecessary(void);
static void WalSndCheckTimeOut(void);
static long WalSndComputeSleeptime(TimestampTz now);
-static void WalSndWait(uint32 socket_events, long timeout, uint32 wait_event);
+static void WalSndWait(uint32 socket_events, long timeout, uint64 wait_event);
static void WalSndPrepareWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, bool last_write);
static void WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, bool last_write);
static void WalSndUpdateProgress(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid,
@@ -1754,7 +1754,7 @@ PhysicalWakeupLogicalWalSnd(void)
* wait_event; otherwise, wait_event is set to 0.
*/
static bool
-NeedToWaitForStandbys(XLogRecPtr flushed_lsn, uint32 *wait_event)
+NeedToWaitForStandbys(XLogRecPtr flushed_lsn, uint64 *wait_event)
{
int elevel = got_STOPPING ? ERROR : WARNING;
bool failover_slot;
@@ -1787,7 +1787,7 @@ NeedToWaitForStandbys(XLogRecPtr flushed_lsn, uint32 *wait_event)
*/
static bool
NeedToWaitForWal(XLogRecPtr target_lsn, XLogRecPtr flushed_lsn,
- uint32 *wait_event)
+ uint64 *wait_event)
{
/* Check if we need to wait for WALs to be flushed to disk */
if (target_lsn > flushed_lsn)
@@ -1817,7 +1817,7 @@ static XLogRecPtr
WalSndWaitForWal(XLogRecPtr loc)
{
int wakeEvents;
- uint32 wait_event = 0;
+ uint64 wait_event = 0;
static XLogRecPtr RecentFlushPtr = InvalidXLogRecPtr;
TimestampTz last_flush = 0;
@@ -3811,7 +3811,7 @@ WalSndWakeup(bool physical, bool logical)
* on postmaster death.
*/
static void
-WalSndWait(uint32 socket_events, long timeout, uint32 wait_event)
+WalSndWait(uint32 socket_events, long timeout, uint64 wait_event)
{
WaitEvent event;
diff --git a/src/backend/storage/aio/aio_io.c b/src/backend/storage/aio/aio_io.c
index 7d11d40284a..4efd76e7671 100644
--- a/src/backend/storage/aio/aio_io.c
+++ b/src/backend/storage/aio/aio_io.c
@@ -124,14 +124,16 @@ pgaio_io_perform_synchronously(PgAioHandle *ioh)
switch ((PgAioOp) ioh->op)
{
case PGAIO_OP_READV:
- pgstat_report_wait_start(WAIT_EVENT_DATA_FILE_READ);
+ /* FIXME DEMO just use fd for short demo, as i dont know how to get relationId from here */
+ pgstat_report_wait_start(WAIT_EVENT_DATA_FILE_READ | ioh->op_data.read.fd);
result = pg_preadv(ioh->op_data.read.fd, iov,
ioh->op_data.read.iov_length,
ioh->op_data.read.offset);
pgstat_report_wait_end();
break;
case PGAIO_OP_WRITEV:
- pgstat_report_wait_start(WAIT_EVENT_DATA_FILE_WRITE);
+ /* FIXME DEMO just use fd for short demo, as i dont know how to get relationId from here */
+ pgstat_report_wait_start(WAIT_EVENT_DATA_FILE_WRITE | ioh->op_data.write.fd);
result = pg_pwritev(ioh->op_data.write.fd, iov,
ioh->op_data.write.iov_length,
ioh->op_data.write.offset);
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index e9eaaf9c829..c549832e39d 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -2077,7 +2077,7 @@ FileClose(File file)
* this.
*/
int
-FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
+FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info)
{
Assert(FileIsValid(file));
@@ -2133,7 +2133,7 @@ retry:
}
void
-FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint32 wait_event_info)
+FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint64 wait_event_info)
{
int returnCode;
@@ -2160,7 +2160,7 @@ FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint32 wait_event_info)
ssize_t
FileReadV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
ssize_t returnCode;
Vfd *vfdP;
@@ -2217,7 +2217,7 @@ retry:
int
FileStartReadV(PgAioHandle *ioh, File file,
int iovcnt, pgoff_t offset,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
int returnCode;
Vfd *vfdP;
@@ -2242,7 +2242,7 @@ FileStartReadV(PgAioHandle *ioh, File file,
ssize_t
FileWriteV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
ssize_t returnCode;
Vfd *vfdP;
@@ -2346,7 +2346,7 @@ retry:
}
int
-FileSync(File file, uint32 wait_event_info)
+FileSync(File file, uint64 wait_event_info)
{
int returnCode;
@@ -2373,7 +2373,7 @@ FileSync(File file, uint32 wait_event_info)
* appropriate error.
*/
int
-FileZero(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
+FileZero(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info)
{
int returnCode;
ssize_t written;
@@ -2418,7 +2418,7 @@ FileZero(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
* appropriate error.
*/
int
-FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
+FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info)
{
#ifdef HAVE_POSIX_FALLOCATE
int returnCode;
@@ -2475,7 +2475,7 @@ FileSize(File file)
}
int
-FileTruncate(File file, pgoff_t offset, uint32 wait_event_info)
+FileTruncate(File file, pgoff_t offset, uint64 wait_event_info)
{
int returnCode;
diff --git a/src/backend/storage/ipc/barrier.c b/src/backend/storage/ipc/barrier.c
index cb99c5f06b0..27bfadbf2e4 100644
--- a/src/backend/storage/ipc/barrier.c
+++ b/src/backend/storage/ipc/barrier.c
@@ -122,7 +122,7 @@ BarrierInit(Barrier *barrier, int participants)
* phase of work that must be done serially while other participants wait.
*/
bool
-BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info)
+BarrierArriveAndWait(Barrier *barrier, uint64 wait_event_info)
{
bool release = false;
bool elected;
diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c
index beadeb5e46a..92902a2c7b6 100644
--- a/src/backend/storage/ipc/latch.c
+++ b/src/backend/storage/ipc/latch.c
@@ -170,7 +170,7 @@ DisownLatch(Latch *latch)
*/
int
WaitLatch(Latch *latch, int wakeEvents, long timeout,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
WaitEvent event;
@@ -221,7 +221,7 @@ WaitLatch(Latch *latch, int wakeEvents, long timeout,
*/
int
WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock,
- long timeout, uint32 wait_event_info)
+ long timeout, uint64 wait_event_info)
{
int ret = 0;
int rc;
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 4222bdab078..65b3ed9cbd4 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -72,7 +72,7 @@ static volatile sig_atomic_t got_standby_lock_timeout = false;
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
ProcSignalReason reason,
- uint32 wait_event_info,
+ uint64 wait_event_info,
bool report_waiting);
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason);
static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts);
@@ -231,7 +231,7 @@ static int standbyWait_us = STANDBY_INITIAL_WAIT_US;
* more then we return true, if we can wait some more return false.
*/
static bool
-WaitExceedsMaxStandbyDelay(uint32 wait_event_info)
+WaitExceedsMaxStandbyDelay(uint64 wait_event_info)
{
TimestampTz ltime;
@@ -358,7 +358,7 @@ LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start,
*/
static void
ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
- ProcSignalReason reason, uint32 wait_event_info,
+ ProcSignalReason reason, uint64 wait_event_info,
bool report_waiting)
{
TimestampTz waitStart = 0;
diff --git a/src/backend/storage/ipc/waiteventset.c b/src/backend/storage/ipc/waiteventset.c
index 465cee40ccc..57770a4e08e 100644
--- a/src/backend/storage/ipc/waiteventset.c
+++ b/src/backend/storage/ipc/waiteventset.c
@@ -1037,7 +1037,7 @@ WaitEventAdjustWin32(WaitEventSet *set, WaitEvent *event)
int
WaitEventSetWait(WaitEventSet *set, long timeout,
WaitEvent *occurred_events, int nevents,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
int returned_events = 0;
instr_time start_time;
diff --git a/src/backend/storage/lmgr/condition_variable.c b/src/backend/storage/lmgr/condition_variable.c
index 59abc080ed2..2713d9536c0 100644
--- a/src/backend/storage/lmgr/condition_variable.c
+++ b/src/backend/storage/lmgr/condition_variable.c
@@ -95,7 +95,7 @@ ConditionVariablePrepareToSleep(ConditionVariable *cv)
* wait_event_type and wait_event columns while waiting.
*/
void
-ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
+ConditionVariableSleep(ConditionVariable *cv, uint64 wait_event_info)
{
(void) ConditionVariableTimedSleep(cv, -1 /* no timeout */ ,
wait_event_info);
@@ -112,7 +112,7 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
*/
bool
ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
long cur_timeout = -1;
instr_time start_time;
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 255cfa8fa95..e703d6ae807 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -718,7 +718,7 @@ LWLockInitialize(LWLock *lock, int tranche_id)
static inline void
LWLockReportWaitStart(LWLock *lock)
{
- pgstat_report_wait_start(PG_WAIT_LWLOCK | lock->tranche);
+ pgstat_report_wait_start(PG_WAIT_LWLOCK | ((uint64_t) lock->tranche << 32));
}
/*
@@ -770,8 +770,9 @@ GetLWTrancheName(uint16 trancheId)
* Return an identifier for an LWLock based on the wait class and event.
*/
const char *
-GetLWLockIdentifier(uint32 classId, uint16 eventId)
+GetLWLockIdentifier(uint64 classId, uint16 eventId)
{
+ // FIXME
Assert(classId == PG_WAIT_LWLOCK);
/* The event IDs are just tranche numbers. */
return GetLWTrancheName(eventId);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 1504fafe6d8..83bb46d9afa 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -523,7 +523,7 @@ InitProcess(void)
Assert(dlist_is_empty(&MyProc->lockGroupMembers));
/* Initialize wait event information. */
- MyProc->wait_event_info = 0;
+ pg_atomic_init_u64(&MyProc->wait_event_info, 0);
/* Initialize fields for group transaction status update. */
MyProc->clogGroupMember = false;
@@ -1460,8 +1460,9 @@ ProcSleep(LOCALLOCK *locallock)
}
else
{
+ /* FIXME/review later */
(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
- PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
+ PG_WAIT_LOCK | ((uint64_t) locallock->tag.lock.locktag_type << 32) | locallock->tag.lock.locktag_field2);
ResetLatch(MyLatch);
/* check for deadlocks first, as that's probably log-worthy */
if (got_deadlock_timeout)
@@ -1981,7 +1982,7 @@ GetLockHoldersAndWaiters(LOCALLOCK *locallock, StringInfo lock_holders_sbuf,
* wait again if not.
*/
void
-ProcWaitForSignal(uint32 wait_event_info)
+ProcWaitForSignal(uint64 wait_event_info)
{
(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
wait_event_info);
diff --git a/src/backend/storage/lmgr/s_lock.c b/src/backend/storage/lmgr/s_lock.c
index d26e192f4bc..fe113b2b92d 100644
--- a/src/backend/storage/lmgr/s_lock.c
+++ b/src/backend/storage/lmgr/s_lock.c
@@ -66,7 +66,7 @@
* s_lock_test.
*/
static uint32 local_my_wait_event_info;
-uint32 *my_wait_event_info = &local_my_wait_event_info;
+uint64 *my_wait_event_info = &local_my_wait_event_info;
#endif
static int spins_per_delay = DEFAULT_SPINS_PER_DELAY;
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index e3f335a8340..a56d73ec2e4 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -890,7 +890,8 @@ mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
reln->smgr_rlocator.locator.relNumber,
reln->smgr_rlocator.backend);
nbytes = FileReadV(v->mdfd_vfd, iov, iovcnt, seekpos,
- WAIT_EVENT_DATA_FILE_READ);
+ WAIT_EVENT_DATA_FILE_READ | (uint32_t) v->mdfd_vfd);
+ //WAIT_EVENT_DATA_FILE_READ | (uint32_t) reln->smgr_rlocator.locator.relNumber);
TRACE_POSTGRESQL_SMGR_MD_READ_DONE(forknum, blocknum,
reln->smgr_rlocator.locator.spcOid,
reln->smgr_rlocator.locator.dbOid,
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index a290cc4c975..2e3b5642dc9 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -20,6 +20,7 @@
#include "storage/proc.h" /* for MyProc */
#include "storage/procarray.h"
#include "utils/ascii.h"
+#include "utils/dsa.h"
#include "utils/guc.h" /* for application_name */
#include "utils/memutils.h"
@@ -601,7 +602,7 @@ pgstat_report_activity(BackendState state, const char *cmd_str)
beentry->st_xact_start_timestamp = 0;
beentry->st_query_id = INT64CONST(0);
beentry->st_plan_id = INT64CONST(0);
- proc->wait_event_info = 0;
+ pg_atomic_write_u64(&proc->wait_event_info, 0);
PGSTAT_END_WRITE_ACTIVITY(beentry);
}
return;
diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index 5db13419f25..ec48b2a8098 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -192,6 +192,7 @@ if ($gen_code)
my $lastlc = lc $last;
my $firstpass = 1;
my $pg_wait_class;
+ my $counter;
printf $c
"static const char *\npgstat_get_wait_$lastlc($waitclass w)\n{\n";
@@ -200,17 +201,24 @@ if ($gen_code)
foreach my $wev (@{ $hashwe{$waitclass} })
{
+ $pg_wait_class = "PG_WAIT_" . $lastuc;
if ($firstpass)
{
printf $h "typedef enum\n{\n";
- $pg_wait_class = "PG_WAIT_" . $lastuc;
printf $h "\t%s = %s", $wev->[0], $pg_wait_class;
$continue = ",\n";
+ $counter = 1;
}
else
{
- printf $h "%s\t%s", $continue, $wev->[0];
+ # Instead of simple emission of enum type like:
+ # WAIT_EVENT_DATA_FILE_READ
+ # we emit for enum proper value like:
+ # WAIT_EVENT_DATA_FILE_READ = PG_WAIT_IO + (21ULL << 32)
+ # because C doesnt allow for defining custom jumps
+ printf $h "%s\t%s = %s + (%dULL << 32)", $continue, $wev->[0], $pg_wait_class, $counter;
$continue = ",\n";
+ $counter++;
}
$firstpass = 0;
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index d9b8f34a355..8c0ce90442c 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -22,6 +22,7 @@
*/
#include "postgres.h"
+#include "port/atomics.h"
#include "storage/lmgr.h" /* for GetLockNameFromTagType */
#include "storage/lwlock.h" /* for GetLWLockIdentifier */
#include "storage/spin.h"
@@ -36,11 +37,14 @@ static const char *pgstat_get_wait_timeout(WaitEventTimeout w);
static const char *pgstat_get_wait_io(WaitEventIO w);
-static uint32 local_my_wait_event_info;
-uint32 *my_wait_event_info = &local_my_wait_event_info;
+static volatile pg_atomic_uint64 local_my_wait_event_info;
+volatile pg_atomic_uint64 *my_wait_event_info = &local_my_wait_event_info;
-#define WAIT_EVENT_CLASS_MASK 0xFF000000
-#define WAIT_EVENT_ID_MASK 0x0000FFFF
+#define WAIT_EVENT_CLASS_MASK 0xFF00000000000000
+#define WAIT_EVENT_ID_MASK 0x0000FFFF00000000
+#define WAIT_EVENT_ARG_MASK 0x00000000FFFFFFFF
+/* just upper 24bits for decoding wait_event into name */
+#define WAIT_EVENT_CLASSID_MASK (WAIT_EVENT_CLASS_MASK | WAIT_EVENT_ID_MASK)
/*
* Hash tables for storing custom wait event ids and their names in
@@ -69,14 +73,14 @@ static HTAB *WaitEventCustomHashByName; /* find infos from names */
/* hash table entries */
typedef struct WaitEventCustomEntryByInfo
{
- uint32 wait_event_info; /* hash key */
+ uint64 wait_event_info; /* hash key */
char wait_event_name[NAMEDATALEN]; /* custom wait event name */
} WaitEventCustomEntryByInfo;
typedef struct WaitEventCustomEntryByName
{
char wait_event_name[NAMEDATALEN]; /* hash key */
- uint32 wait_event_info;
+ uint64 wait_event_info;
} WaitEventCustomEntryByName;
@@ -93,8 +97,8 @@ static WaitEventCustomCounterData *WaitEventCustomCounter;
/* first event ID of custom wait events */
#define WAIT_EVENT_CUSTOM_INITIAL_ID 1
-static uint32 WaitEventCustomNew(uint32 classId, const char *wait_event_name);
-static const char *GetWaitEventCustomIdentifier(uint32 wait_event_info);
+static uint64 WaitEventCustomNew(uint64 classId, const char *wait_event_name);
+static const char *GetWaitEventCustomIdentifier(uint64 wait_event_info);
/*
* Return the space for dynamic shared hash tables and dynamic allocation counter.
@@ -133,7 +137,7 @@ WaitEventCustomShmemInit(void)
}
/* initialize or attach the hash tables to store custom wait events */
- info.keysize = sizeof(uint32);
+ info.keysize = sizeof(uint64);
info.entrysize = sizeof(WaitEventCustomEntryByInfo);
WaitEventCustomHashByInfo =
ShmemInitHash("WaitEventCustom hash by wait event information",
@@ -158,27 +162,31 @@ WaitEventCustomShmemInit(void)
*
* If the wait event name is already defined, this does not allocate a new
* entry; it returns the wait event information associated to the name.
+ *
+ * XXX: maybe we should return safe u64 struct here so that extension
+ * writers will get clear error message about need to change the type
*/
-uint32
+uint64
WaitEventExtensionNew(const char *wait_event_name)
{
return WaitEventCustomNew(PG_WAIT_EXTENSION, wait_event_name);
}
-uint32
+uint64
WaitEventInjectionPointNew(const char *wait_event_name)
{
return WaitEventCustomNew(PG_WAIT_INJECTIONPOINT, wait_event_name);
+
}
-static uint32
-WaitEventCustomNew(uint32 classId, const char *wait_event_name)
+static uint64
+WaitEventCustomNew(uint64 classId, const char *wait_event_name)
{
uint16 eventId;
bool found;
WaitEventCustomEntryByName *entry_by_name;
WaitEventCustomEntryByInfo *entry_by_info;
- uint32 wait_event_info;
+ uint64 wait_event_info;
/* Check the limit of the length of the event name */
if (strlen(wait_event_name) >= NAMEDATALEN)
@@ -197,7 +205,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
LWLockRelease(WaitEventCustomLock);
if (found)
{
- uint32 oldClassId;
+ uint64 oldClassId;
oldClassId = entry_by_name->wait_event_info & WAIT_EVENT_CLASS_MASK;
if (oldClassId != classId)
@@ -206,7 +214,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
errmsg("wait event \"%s\" already exists in type \"%s\"",
wait_event_name,
pgstat_get_wait_event_type(entry_by_name->wait_event_info))));
- return entry_by_name->wait_event_info;
+ return entry_by_name->wait_event_info | classId;
}
/*
@@ -221,7 +229,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
HASH_FIND, &found);
if (found)
{
- uint32 oldClassId;
+ uint64 oldClassId;
LWLockRelease(WaitEventCustomLock);
oldClassId = entry_by_name->wait_event_info & WAIT_EVENT_CLASS_MASK;
@@ -231,7 +239,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
errmsg("wait event \"%s\" already exists in type \"%s\"",
wait_event_name,
pgstat_get_wait_event_type(entry_by_name->wait_event_info))));
- return entry_by_name->wait_event_info;
+ return entry_by_name->wait_event_info | classId;
}
/* Allocate a new event Id */
@@ -250,7 +258,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
SpinLockRelease(&WaitEventCustomCounter->mutex);
/* Register the new wait event */
- wait_event_info = classId | eventId;
+ wait_event_info = classId | (uint64) eventId;
entry_by_info = (WaitEventCustomEntryByInfo *)
hash_search(WaitEventCustomHashByInfo, &wait_event_info,
HASH_ENTER, &found);
@@ -273,7 +281,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
* Return the name of a custom wait event information.
*/
static const char *
-GetWaitEventCustomIdentifier(uint32 wait_event_info)
+GetWaitEventCustomIdentifier(uint64 wait_event_info)
{
bool found;
WaitEventCustomEntryByInfo *entry;
@@ -291,7 +299,7 @@ GetWaitEventCustomIdentifier(uint32 wait_event_info)
if (!entry)
elog(ERROR,
- "could not find custom name for wait event information %u",
+ "could not find custom name for wait event information %" PRIu64,
wait_event_info);
return entry->wait_event_name;
@@ -303,7 +311,7 @@ GetWaitEventCustomIdentifier(uint32 wait_event_info)
* a palloc'd array, with the number of elements saved in *nwaitevents.
*/
char **
-GetWaitEventCustomNames(uint32 classId, int *nwaitevents)
+GetWaitEventCustomNames(uint64 classId, int *nwaitevents)
{
char **waiteventnames;
WaitEventCustomEntryByName *hentry;
@@ -346,7 +354,7 @@ GetWaitEventCustomNames(uint32 classId, int *nwaitevents)
* into shared memory.
*/
void
-pgstat_set_wait_event_storage(uint32 *wait_event_info)
+pgstat_set_wait_event_storage(volatile pg_atomic_uint64 *wait_event_info)
{
my_wait_event_info = wait_event_info;
}
@@ -370,9 +378,9 @@ pgstat_reset_wait_event_storage(void)
* waiting on.
*/
const char *
-pgstat_get_wait_event_type(uint32 wait_event_info)
+pgstat_get_wait_event_type(uint64 wait_event_info)
{
- uint32 classId;
+ uint64 classId;
const char *event_type;
/* report process as not waiting. */
@@ -428,9 +436,9 @@ pgstat_get_wait_event_type(uint32 wait_event_info)
* waiting on.
*/
const char *
-pgstat_get_wait_event(uint32 wait_event_info)
+pgstat_get_wait_event(uint64 wait_event_info)
{
- uint32 classId;
+ uint64 classId;
uint16 eventId;
const char *event_name;
@@ -439,7 +447,7 @@ pgstat_get_wait_event(uint32 wait_event_info)
return NULL;
classId = wait_event_info & WAIT_EVENT_CLASS_MASK;
- eventId = wait_event_info & WAIT_EVENT_ID_MASK;
+ eventId = (uint16) ((wait_event_info & WAIT_EVENT_ID_MASK) >> 32);
switch (classId)
{
@@ -453,44 +461,49 @@ pgstat_get_wait_event(uint32 wait_event_info)
case PG_WAIT_INJECTIONPOINT:
event_name = GetWaitEventCustomIdentifier(wait_event_info);
break;
+ /* for the below ones we need to mask lower 32-bits */
case PG_WAIT_BUFFERPIN:
{
- WaitEventBufferPin w = (WaitEventBufferPin) wait_event_info;
+ WaitEventBufferPin w = (WaitEventBufferPin) wait_event_info & WAIT_EVENT_CLASSID_MASK;
+
event_name = pgstat_get_wait_bufferpin(w);
break;
}
case PG_WAIT_ACTIVITY:
{
- WaitEventActivity w = (WaitEventActivity) wait_event_info;
+ WaitEventActivity w = (WaitEventActivity) wait_event_info & WAIT_EVENT_CLASSID_MASK;
+
event_name = pgstat_get_wait_activity(w);
break;
}
case PG_WAIT_CLIENT:
{
- WaitEventClient w = (WaitEventClient) wait_event_info;
+ WaitEventClient w = (WaitEventClient) wait_event_info & WAIT_EVENT_CLASSID_MASK;
+
event_name = pgstat_get_wait_client(w);
break;
}
case PG_WAIT_IPC:
{
- WaitEventIPC w = (WaitEventIPC) wait_event_info;
+ WaitEventIPC w = (WaitEventIPC) wait_event_info & WAIT_EVENT_CLASSID_MASK;
+
event_name = pgstat_get_wait_ipc(w);
break;
}
case PG_WAIT_TIMEOUT:
{
- WaitEventTimeout w = (WaitEventTimeout) wait_event_info;
+ WaitEventTimeout w = (WaitEventTimeout) wait_event_info & WAIT_EVENT_CLASSID_MASK;
event_name = pgstat_get_wait_timeout(w);
break;
}
case PG_WAIT_IO:
{
- WaitEventIO w = (WaitEventIO) wait_event_info;
+ WaitEventIO w = (WaitEventIO) wait_event_info & WAIT_EVENT_CLASSID_MASK;
event_name = pgstat_get_wait_io(w);
break;
@@ -503,4 +516,11 @@ pgstat_get_wait_event(uint32 wait_event_info)
return event_name;
}
+uint32
+pgstat_get_wait_event_arg(uint64 wait_event_info)
+{
+ uint32 arg = wait_event_info & WAIT_EVENT_ARG_MASK;
+ return arg;
+}
+
#include "pgstat_wait_event.c"
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index a365c432d34..7b28e775f5b 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -374,10 +374,11 @@ pg_sleep(PG_FUNCTION_ARGS)
else
break;
+ /* FIXME DEMO: we just save number of seconds into wait_event_arg */
(void) WaitLatch(MyLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
delay_ms,
- WAIT_EVENT_PG_SLEEP);
+ WAIT_EVENT_PG_SLEEP | (uint32_t) secs/USECS_PER_SEC);
ResetLatch(MyLatch);
}
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 7e2ed69138a..24dbb195fae 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -30,9 +30,11 @@
#include "storage/procarray.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/dsa.h"
#include "utils/timestamp.h"
-#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
+//#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
+#define UINT64_ACCESS_ONCE(var) ((uint64)(*((volatile uint64 *)&(var))))
#define HAS_PGSTAT_PERMISSIONS(role) (has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS) || has_privs_of_role(GetUserId(), role))
@@ -351,7 +353,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
Datum
pg_stat_get_activity(PG_FUNCTION_ARGS)
{
-#define PG_STAT_GET_ACTIVITY_COLS 31
+#define PG_STAT_GET_ACTIVITY_COLS 32
int num_backends = pgstat_fetch_stat_numbackends();
int curr_backend;
int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
@@ -370,6 +372,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
PGPROC *proc;
const char *wait_event_type = NULL;
const char *wait_event = NULL;
+ uint32 wait_event_arg = 0;
/* Get the next one in the list */
local_beentry = pgstat_get_local_beentry_by_index(curr_backend);
@@ -398,14 +401,14 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
nulls[3] = true;
if (TransactionIdIsValid(local_beentry->backend_xid))
- values[15] = TransactionIdGetDatum(local_beentry->backend_xid);
+ values[16] = TransactionIdGetDatum(local_beentry->backend_xid);
else
- nulls[15] = true;
+ nulls[16] = true;
if (TransactionIdIsValid(local_beentry->backend_xmin))
- values[16] = TransactionIdGetDatum(local_beentry->backend_xmin);
+ values[17] = TransactionIdGetDatum(local_beentry->backend_xmin);
else
- nulls[16] = true;
+ nulls[17] = true;
/* Values only available to role member or pg_read_all_stats */
if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -445,7 +448,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
pfree(clipped_activity);
/* leader_pid */
- nulls[29] = true;
+ nulls[30] = true;
proc = BackendPidGetProc(beentry->st_procpid);
@@ -466,12 +469,13 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
*/
if (proc != NULL)
{
- uint32 raw_wait_event;
+ uint64 raw_wait_event;
PGPROC *leader;
- raw_wait_event = UINT32_ACCESS_ONCE(proc->wait_event_info);
+ raw_wait_event = UINT64_ACCESS_ONCE(proc->wait_event_info);
wait_event_type = pgstat_get_wait_event_type(raw_wait_event);
wait_event = pgstat_get_wait_event(raw_wait_event);
+ wait_event_arg = pgstat_get_wait_event_arg(raw_wait_event);
leader = proc->lockGroupLeader;
@@ -482,8 +486,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
*/
if (leader && leader->pid != beentry->st_procpid)
{
- values[29] = Int32GetDatum(leader->pid);
- nulls[29] = false;
+ values[30] = Int32GetDatum(leader->pid);
+ nulls[30] = false;
}
else if (beentry->st_backendType == B_BG_WORKER)
{
@@ -491,8 +495,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
if (leader_pid != InvalidPid)
{
- values[29] = Int32GetDatum(leader_pid);
- nulls[29] = false;
+ values[30] = Int32GetDatum(leader_pid);
+ nulls[30] = false;
}
}
}
@@ -507,6 +511,11 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
else
nulls[7] = true;
+ if (wait_event_arg)
+ values[8] = UInt32GetDatum(wait_event_arg);
+ else
+ nulls[8] = true;
+
/*
* Don't expose transaction time for walsenders; it confuses
* monitoring, particularly because we don't keep the time up-to-
@@ -514,32 +523,32 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
*/
if (beentry->st_xact_start_timestamp != 0 &&
beentry->st_backendType != B_WAL_SENDER)
- values[8] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
+ values[9] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
else
- nulls[8] = true;
+ nulls[9] = true;
if (beentry->st_activity_start_timestamp != 0)
- values[9] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
+ values[10] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
else
- nulls[9] = true;
+ nulls[10] = true;
if (beentry->st_proc_start_timestamp != 0)
- values[10] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
+ values[11] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
else
- nulls[10] = true;
+ nulls[11] = true;
if (beentry->st_state_start_timestamp != 0)
- values[11] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
+ values[12] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
else
- nulls[11] = true;
+ nulls[12] = true;
/* A zeroed client addr means we don't know */
if (pg_memory_is_all_zeros(&beentry->st_clientaddr,
sizeof(beentry->st_clientaddr)))
{
- nulls[12] = true;
nulls[13] = true;
nulls[14] = true;
+ nulls[15] = true;
}
else
{
@@ -560,20 +569,20 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
if (ret == 0)
{
clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
- values[12] = DirectFunctionCall1(inet_in,
+ values[13] = DirectFunctionCall1(inet_in,
CStringGetDatum(remote_host));
if (beentry->st_clienthostname &&
beentry->st_clienthostname[0])
- values[13] = CStringGetTextDatum(beentry->st_clienthostname);
+ values[14] = CStringGetTextDatum(beentry->st_clienthostname);
else
- nulls[13] = true;
- values[14] = Int32GetDatum(atoi(remote_port));
+ nulls[14] = true;
+ values[15] = Int32GetDatum(atoi(remote_port));
}
else
{
- nulls[12] = true;
nulls[13] = true;
nulls[14] = true;
+ nulls[15] = true;
}
}
else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
@@ -584,16 +593,16 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
* connections we have no permissions to view, or with
* errors.
*/
- nulls[12] = true;
nulls[13] = true;
- values[14] = Int32GetDatum(-1);
+ nulls[14] = true;
+ values[15] = Int32GetDatum(-1);
}
else
{
/* Unknown address type, should never happen */
- nulls[12] = true;
nulls[13] = true;
nulls[14] = true;
+ nulls[15] = true;
}
}
/* Add backend type */
@@ -603,68 +612,68 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
bgw_type = GetBackgroundWorkerTypeByPid(beentry->st_procpid);
if (bgw_type)
- values[17] = CStringGetTextDatum(bgw_type);
+ values[18] = CStringGetTextDatum(bgw_type);
else
- nulls[17] = true;
+ nulls[18] = true;
}
else
- values[17] =
+ values[18] =
CStringGetTextDatum(GetBackendTypeDesc(beentry->st_backendType));
/* SSL information */
if (beentry->st_ssl)
{
- values[18] = BoolGetDatum(true); /* ssl */
- values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
- values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
- values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
+ values[19] = BoolGetDatum(true); /* ssl */
+ values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
+ values[21] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
+ values[22] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
if (beentry->st_sslstatus->ssl_client_dn[0])
- values[22] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn);
+ values[23] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn);
else
- nulls[22] = true;
+ nulls[23] = true;
if (beentry->st_sslstatus->ssl_client_serial[0])
- values[23] = DirectFunctionCall3(numeric_in,
+ values[24] = DirectFunctionCall3(numeric_in,
CStringGetDatum(beentry->st_sslstatus->ssl_client_serial),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));
else
- nulls[23] = true;
+ nulls[24] = true;
if (beentry->st_sslstatus->ssl_issuer_dn[0])
- values[24] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn);
+ values[25] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn);
else
- nulls[24] = true;
+ nulls[25] = true;
}
else
{
- values[18] = BoolGetDatum(false); /* ssl */
- nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = true;
+ values[19] = BoolGetDatum(false); /* ssl */
+ nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = nulls[25] = true;
}
/* GSSAPI information */
if (beentry->st_gss)
{
- values[25] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */
- values[26] = CStringGetTextDatum(beentry->st_gssstatus->gss_princ);
- values[27] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */
- values[28] = BoolGetDatum(beentry->st_gssstatus->gss_delegation); /* GSS credentials
+ values[26] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */
+ values[27] = CStringGetTextDatum(beentry->st_gssstatus->gss_princ);
+ values[28] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */
+ values[29] = BoolGetDatum(beentry->st_gssstatus->gss_delegation); /* GSS credentials
* delegated */
}
else
{
- values[25] = BoolGetDatum(false); /* gss_auth */
- nulls[26] = true; /* No GSS principal */
- values[27] = BoolGetDatum(false); /* GSS Encryption not in
+ values[26] = BoolGetDatum(false); /* gss_auth */
+ nulls[27] = true; /* No GSS principal */
+ values[28] = BoolGetDatum(false); /* GSS Encryption not in
* use */
- values[28] = BoolGetDatum(false); /* GSS credentials not
+ values[29] = BoolGetDatum(false); /* GSS credentials not
* delegated */
}
if (beentry->st_query_id == INT64CONST(0))
- nulls[30] = true;
+ nulls[31] = true;
else
- values[30] = Int64GetDatum(beentry->st_query_id);
+ values[31] = Int64GetDatum(beentry->st_query_id);
}
else
{
@@ -694,6 +703,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
nulls[28] = true;
nulls[29] = true;
nulls[30] = true;
+ nulls[31] = true;
}
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
@@ -825,7 +835,7 @@ pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
wait_event_type = "<insufficient privilege>";
else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
- wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);
+ wait_event_type = pgstat_get_wait_event_type(pg_atomic_read_u64((&proc->wait_event_info)));
if (!wait_event_type)
PG_RETURN_NULL();
@@ -846,7 +856,7 @@ pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
wait_event = "<insufficient privilege>";
else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
- wait_event = pgstat_get_wait_event(proc->wait_event_info);
+ wait_event = pgstat_get_wait_event(pg_atomic_read_u64((&proc->wait_event_info)));
if (!wait_event)
PG_RETURN_NULL();
diff --git a/src/backend/utils/adt/waitfuncs.c b/src/backend/utils/adt/waitfuncs.c
index f01cad72a0f..346844f22d4 100644
--- a/src/backend/utils/adt/waitfuncs.c
+++ b/src/backend/utils/adt/waitfuncs.c
@@ -20,8 +20,6 @@
#include "utils/fmgrprotos.h"
#include "utils/wait_event.h"
-#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
-
/*
* pg_isolation_test_session_is_blocked - support function for isolationtester
@@ -56,7 +54,7 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS)
if (proc == NULL)
PG_RETURN_BOOL(false); /* session gone: definitely unblocked */
wait_event_type =
- pgstat_get_wait_event_type(UINT32_ACCESS_ONCE(proc->wait_event_info));
+ pgstat_get_wait_event_type(pg_atomic_read_u64(&proc->wait_event_info));
if (wait_event_type && strcmp("InjectionPoint", wait_event_type) == 0)
PG_RETURN_BOOL(true);
diff --git a/src/include/access/xlogarchive.h b/src/include/access/xlogarchive.h
index 6ed47e99f12..110ae2b1680 100644
--- a/src/include/access/xlogarchive.h
+++ b/src/include/access/xlogarchive.h
@@ -21,7 +21,7 @@ extern bool RestoreArchivedFile(char *path, const char *xlogfname,
const char *recovername, off_t expectedSize,
bool cleanupEnabled);
extern void ExecuteRecoveryCommand(const char *command, const char *commandName,
- bool failOnSignal, uint32 wait_event_info);
+ bool failOnSignal, uint64 wait_event_info);
extern void KeepFileRestoredFromArchive(const char *path, const char *xlogfname);
extern void XLogArchiveNotify(const char *xlog);
extern void XLogArchiveNotifySeg(XLogSegNo segno, TimeLineID tli);
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 66af2d96d67..f15cb2587c5 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5653,9 +5653,9 @@
proname => 'pg_stat_get_activity', prorows => '100', proisstrict => 'f',
proretset => 't', provolatile => 's', proparallel => 'r',
prorettype => 'record', proargtypes => 'int4',
- proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,text,bool,text,text,int4,text,numeric,text,bool,text,bool,bool,int4,int8}',
- proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
- proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc,gss_delegation,leader_pid,query_id}',
+ proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,int4,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,text,bool,text,text,int4,text,numeric,text,bool,text,bool,bool,int4,int8}',
+ proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
+ proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,wait_event_arg,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc,gss_delegation,leader_pid,query_id}',
prosrc => 'pg_stat_get_activity' },
{ oid => '6318', descr => 'describe wait events',
proname => 'pg_get_wait_events', procost => '10', prorows => '250',
diff --git a/src/include/libpq/libpq-be-fe-helpers.h b/src/include/libpq/libpq-be-fe-helpers.h
index 1c4a342090c..5adf391935a 100644
--- a/src/include/libpq/libpq-be-fe-helpers.h
+++ b/src/include/libpq/libpq-be-fe-helpers.h
@@ -39,9 +39,9 @@
static inline void libpqsrv_connect_prepare(void);
-static inline void libpqsrv_connect_internal(PGconn *conn, uint32 wait_event_info);
-static inline PGresult *libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info);
-static inline PGresult *libpqsrv_get_result(PGconn *conn, uint32 wait_event_info);
+static inline void libpqsrv_connect_internal(PGconn *conn, uint64 wait_event_info);
+static inline PGresult *libpqsrv_get_result_last(PGconn *conn, uint64 wait_event_info);
+static inline PGresult *libpqsrv_get_result(PGconn *conn, uint64 wait_event_info);
/*
@@ -53,7 +53,7 @@ static inline PGresult *libpqsrv_get_result(PGconn *conn, uint32 wait_event_info
* check if connection establishment succeeded.
*/
static inline PGconn *
-libpqsrv_connect(const char *conninfo, uint32 wait_event_info)
+libpqsrv_connect(const char *conninfo, uint64 wait_event_info)
{
PGconn *conn = NULL;
@@ -74,7 +74,7 @@ static inline PGconn *
libpqsrv_connect_params(const char *const *keywords,
const char *const *values,
int expand_dbname,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
PGconn *conn = NULL;
@@ -147,7 +147,7 @@ libpqsrv_connect_prepare(void)
* Helper function for all connection establishment functions.
*/
static inline void
-libpqsrv_connect_internal(PGconn *conn, uint32 wait_event_info)
+libpqsrv_connect_internal(PGconn *conn, uint64 wait_event_info)
{
/*
* With conn == NULL libpqsrv_disconnect() wouldn't release the FD. So do
@@ -243,7 +243,7 @@ libpqsrv_connect_internal(PGconn *conn, uint32 wait_event_info)
* notably, PQexec() would silently discard any prior query results.
*/
static inline PGresult *
-libpqsrv_exec(PGconn *conn, const char *query, uint32 wait_event_info)
+libpqsrv_exec(PGconn *conn, const char *query, uint64 wait_event_info)
{
if (!PQsendQuery(conn, query))
return NULL;
@@ -264,7 +264,7 @@ libpqsrv_exec_params(PGconn *conn,
const int *paramLengths,
const int *paramFormats,
int resultFormat,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
if (!PQsendQueryParams(conn, command, nParams, paramTypes, paramValues,
paramLengths, paramFormats, resultFormat))
@@ -277,7 +277,7 @@ libpqsrv_exec_params(PGconn *conn,
* terminal state. Return the last non-NULL result or the terminal state.
*/
static inline PGresult *
-libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info)
+libpqsrv_get_result_last(PGconn *conn, uint64 wait_event_info)
{
PGresult *lastResult = NULL;
@@ -310,7 +310,7 @@ libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info)
* Perform the equivalent of PQgetResult(), but watch for interrupts.
*/
static inline PGresult *
-libpqsrv_get_result(PGconn *conn, uint32 wait_event_info)
+libpqsrv_get_result(PGconn *conn, uint64 wait_event_info)
{
/*
* Collect data until PQgetResult is ready to get the result without
diff --git a/src/include/storage/barrier.h b/src/include/storage/barrier.h
index 4d8a95f4a4a..5bce133f22c 100644
--- a/src/include/storage/barrier.h
+++ b/src/include/storage/barrier.h
@@ -35,7 +35,7 @@ typedef struct Barrier
} Barrier;
extern void BarrierInit(Barrier *barrier, int participants);
-extern bool BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info);
+extern bool BarrierArriveAndWait(Barrier *barrier, uint64 wait_event_info);
extern bool BarrierArriveAndDetach(Barrier *barrier);
extern bool BarrierArriveAndDetachExceptLast(Barrier *barrier);
extern int BarrierAttach(Barrier *barrier);
diff --git a/src/include/storage/condition_variable.h b/src/include/storage/condition_variable.h
index 526c4ee1051..2137538b246 100644
--- a/src/include/storage/condition_variable.h
+++ b/src/include/storage/condition_variable.h
@@ -53,9 +53,9 @@ extern void ConditionVariableInit(ConditionVariable *cv);
* be called to ensure that the process is no longer in the wait list for
* the condition variable.
*/
-extern void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info);
+extern void ConditionVariableSleep(ConditionVariable *cv, uint64 wait_event_info);
extern bool ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
- uint32 wait_event_info);
+ uint64 wait_event_info);
extern bool ConditionVariableCancelSleep(void);
/*
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index a1bdefec4a5..07158748fe3 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -107,17 +107,17 @@ extern File PathNameOpenFile(const char *fileName, int fileFlags);
extern File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode);
extern File OpenTemporaryFile(bool interXact);
extern void FileClose(File file);
-extern int FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
-extern ssize_t FileReadV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint32 wait_event_info);
-extern ssize_t FileWriteV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint32 wait_event_info);
-extern int FileStartReadV(struct PgAioHandle *ioh, File file, int iovcnt, pgoff_t offset, uint32 wait_event_info);
-extern int FileSync(File file, uint32 wait_event_info);
-extern int FileZero(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
-extern int FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
+extern int FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info);
+extern ssize_t FileReadV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint64 wait_event_info);
+extern ssize_t FileWriteV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint64 wait_event_info);
+extern int FileStartReadV(struct PgAioHandle *ioh, File file, int iovcnt, pgoff_t offset, uint64 wait_event_info);
+extern int FileSync(File file, uint64 wait_event_info);
+extern int FileZero(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info);
+extern int FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info);
extern pgoff_t FileSize(File file);
-extern int FileTruncate(File file, pgoff_t offset, uint32 wait_event_info);
-extern void FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint32 wait_event_info);
+extern int FileTruncate(File file, pgoff_t offset, uint64 wait_event_info);
+extern void FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint64 wait_event_info);
extern char *FilePathName(File file);
extern int FileGetRawDesc(File file);
extern int FileGetRawFlags(File file);
@@ -196,7 +196,7 @@ extern int data_sync_elevel(int elevel);
static inline ssize_t
FileRead(File file, void *buffer, size_t amount, pgoff_t offset,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
struct iovec iov = {
.iov_base = buffer,
@@ -208,7 +208,7 @@ FileRead(File file, void *buffer, size_t amount, pgoff_t offset,
static inline ssize_t
FileWrite(File file, const void *buffer, size_t amount, pgoff_t offset,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
struct iovec iov = {
.iov_base = unconstify(void *, buffer),
diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h
index e41dc70785a..ddce0036519 100644
--- a/src/include/storage/latch.h
+++ b/src/include/storage/latch.h
@@ -132,9 +132,9 @@ extern void SetLatch(Latch *latch);
extern void ResetLatch(Latch *latch);
extern int WaitLatch(Latch *latch, int wakeEvents, long timeout,
- uint32 wait_event_info);
+ uint64 wait_event_info);
extern int WaitLatchOrSocket(Latch *latch, int wakeEvents,
- pgsocket sock, long timeout, uint32 wait_event_info);
+ pgsocket sock, long timeout, uint64 wait_event_info);
extern void InitializeLatchWaitSet(void);
#endif /* LATCH_H */
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 8e0d0d233b4..54e72cd8860 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -142,7 +142,7 @@ extern Size LWLockShmemSize(void);
extern void CreateLWLocks(void);
extern void InitLWLockAccess(void);
-extern const char *GetLWLockIdentifier(uint32 classId, uint16 eventId);
+extern const char *GetLWLockIdentifier(uint64 classId, uint16 eventId);
/*
* Extensions (or core code) can obtain an LWLocks by calling
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index c6f5ebceefd..9c2258000e9 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -299,7 +299,7 @@ struct PGPROC
*/
TransactionId procArrayGroupMemberXid;
- uint32 wait_event_info; /* proc's wait information */
+ volatile pg_atomic_uint64 wait_event_info; /* proc's wait information */
/* Support for group transaction status update. */
bool clogGroupMember; /* true, if member of clog group */
@@ -512,7 +512,7 @@ extern void GetLockHoldersAndWaiters(LOCALLOCK *locallock,
StringInfo lock_waiters_sbuf,
int *lockHoldersNum);
-extern void ProcWaitForSignal(uint32 wait_event_info);
+extern void ProcWaitForSignal(uint64 wait_event_info);
extern void ProcSendSignal(ProcNumber procNumber);
extern PGPROC *AuxiliaryPidGetProc(int pid);
diff --git a/src/include/storage/waiteventset.h b/src/include/storage/waiteventset.h
index dd514d52991..40eb121d4cd 100644
--- a/src/include/storage/waiteventset.h
+++ b/src/include/storage/waiteventset.h
@@ -86,7 +86,7 @@ extern void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events,
struct Latch *latch);
extern int WaitEventSetWait(WaitEventSet *set, long timeout,
WaitEvent *occurred_events, int nevents,
- uint32 wait_event_info);
+ uint64 wait_event_info);
extern int GetNumRegisteredWaitEvents(WaitEventSet *set);
extern bool WaitEventSetCanReportClosed(void);
diff --git a/src/include/utils/wait_classes.h b/src/include/utils/wait_classes.h
index 51ee68397d5..36355a55b0c 100644
--- a/src/include/utils/wait_classes.h
+++ b/src/include/utils/wait_classes.h
@@ -15,15 +15,15 @@
* Wait Classes
* ----------
*/
-#define PG_WAIT_LWLOCK 0x01000000U
-#define PG_WAIT_LOCK 0x03000000U
-#define PG_WAIT_BUFFERPIN 0x04000000U
-#define PG_WAIT_ACTIVITY 0x05000000U
-#define PG_WAIT_CLIENT 0x06000000U
-#define PG_WAIT_EXTENSION 0x07000000U
-#define PG_WAIT_IPC 0x08000000U
-#define PG_WAIT_TIMEOUT 0x09000000U
-#define PG_WAIT_IO 0x0A000000U
-#define PG_WAIT_INJECTIONPOINT 0x0B000000U
+#define PG_WAIT_LWLOCK 0x0100000000000000ULL
+#define PG_WAIT_LOCK 0x0300000000000000ULL
+#define PG_WAIT_BUFFERPIN 0x0400000000000000ULL
+#define PG_WAIT_ACTIVITY 0x0500000000000000ULL
+#define PG_WAIT_CLIENT 0x0600000000000000ULL
+#define PG_WAIT_EXTENSION 0x0700000000000000ULL
+#define PG_WAIT_IPC 0x0800000000000000ULL
+#define PG_WAIT_TIMEOUT 0x0900000000000000ULL
+#define PG_WAIT_IO 0x0A00000000000000ULL
+#define PG_WAIT_INJECTIONPOINT 0x0B00000000000000ULL
#endif /* WAIT_CLASSES_H */
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index f5815b4994a..fadd1b93740 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -12,15 +12,17 @@
/* enums for wait events */
#include "utils/wait_event_types.h"
+#include "port/atomics.h"
-extern const char *pgstat_get_wait_event(uint32 wait_event_info);
-extern const char *pgstat_get_wait_event_type(uint32 wait_event_info);
-static inline void pgstat_report_wait_start(uint32 wait_event_info);
+extern const char *pgstat_get_wait_event(uint64 wait_event_info);
+extern const char *pgstat_get_wait_event_type(uint64 wait_event_info);
+extern uint32 pgstat_get_wait_event_arg(uint64 wait_event_info);
+static inline void pgstat_report_wait_start(uint64 wait_event_info);
static inline void pgstat_report_wait_end(void);
-extern void pgstat_set_wait_event_storage(uint32 *wait_event_info);
+extern void pgstat_set_wait_event_storage(volatile pg_atomic_uint64 *wait_event_info);
extern void pgstat_reset_wait_event_storage(void);
-extern PGDLLIMPORT uint32 *my_wait_event_info;
+extern PGDLLIMPORT volatile pg_atomic_uint64 *my_wait_event_info;
/*
@@ -39,23 +41,27 @@ extern PGDLLIMPORT uint32 *my_wait_event_info;
*
* The ID retrieved can be used with pgstat_report_wait_start() or equivalent.
*/
-extern uint32 WaitEventExtensionNew(const char *wait_event_name);
-extern uint32 WaitEventInjectionPointNew(const char *wait_event_name);
+extern uint64 WaitEventExtensionNew(const char *wait_event_name);
+extern uint64 WaitEventInjectionPointNew(const char *wait_event_name);
extern void WaitEventCustomShmemInit(void);
extern Size WaitEventCustomShmemSize(void);
-extern char **GetWaitEventCustomNames(uint32 classId, int *nwaitevents);
+extern char **GetWaitEventCustomNames(uint64 classId, int *nwaitevents);
/* ----------
* pgstat_report_wait_start() -
*
* Called from places where server process needs to wait. This is called
* to report wait event information. The wait information is stored
- * as 4-bytes where first byte represents the wait event class (type of
- * wait, for different types of wait, refer WaitClass) and the next
- * 3-bytes represent the actual wait event. Currently 2-bytes are used
- * for wait event which is sufficient for current usage, 1-byte is
- * reserved for future usage.
+ * as 8-bytes where:
+ * - first byte represents the wait event class (type of wait, for different
+ * types of wait, refer WaitClass)
+ * - the next 3-bytes represent the actual wait event. Out of which:
+ * -- currently 2-bytes are used for wait event which is sufficient for
+ * current usage,
+ * -- 1-byte is reserved for future usage.
+ * - the remaining 4-bytes are used to store additional per wait-event
+ * details
*
* Historically we used to make this reporting conditional on
* pgstat_track_activities, but the check for that seems to add more cost
@@ -66,13 +72,14 @@ extern char **GetWaitEventCustomNames(uint32 classId, int *nwaitevents);
* ----------
*/
static inline void
-pgstat_report_wait_start(uint32 wait_event_info)
+pgstat_report_wait_start(uint64 wait_event_info)
{
/*
- * Since this is a four-byte field which is always read and written as
- * four-bytes, updates are atomic.
+ * Since this is a eight-byte field which is always read and written as
+ * eight-bytes, updates should be on most platforms atomic.
*/
- *(volatile uint32 *) my_wait_event_info = wait_event_info;
+ pg_atomic_write_u64(my_wait_event_info, wait_event_info);
+ elog(DEBUG1, "setting my_wait_event_info = 0x%lX (%ld)", wait_event_info, wait_event_info);
}
/* ----------
@@ -85,7 +92,7 @@ static inline void
pgstat_report_wait_end(void)
{
/* see pgstat_report_wait_start() */
- *(volatile uint32 *) my_wait_event_info = 0;
+ *(volatile uint64 *) my_wait_event_info = 0;
}
diff --git a/src/test/modules/injection_points/injection_points.c b/src/test/modules/injection_points/injection_points.c
index b7c1c58ea56..3cf4e2a8c45 100644
--- a/src/test/modules/injection_points/injection_points.c
+++ b/src/test/modules/injection_points/injection_points.c
@@ -284,7 +284,7 @@ injection_wait(const char *name, const void *private_data, void *arg)
{
uint32 old_wait_counts = 0;
int index = -1;
- uint32 injection_wait_event = 0;
+ uint64 injection_wait_event = 0;
InjectionPointCondition *condition = (InjectionPointCondition *) private_data;
if (inj_state == NULL)
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 2a20ffb1273..81c0a0d9a72 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -40,7 +40,7 @@ static void wait_for_workers_to_become_ready(worker_state *wstate,
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
-static uint32 we_bgworker_startup = 0;
+static uint64 we_bgworker_startup = 0;
/*
* Set up a dynamic shared memory segment and zero or more background workers
diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c
index bea8339f464..fc9909ecb14 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -53,7 +53,7 @@ static char *worker_spi_database = NULL;
static char *worker_spi_role = NULL;
/* value cached, fetched from shared memory */
-static uint32 worker_spi_wait_event_main = 0;
+static uint64 worker_spi_wait_event_main = 0;
typedef struct worktable
{
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 94e45dd4d57..2a24a042d04 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1790,13 +1790,14 @@ pg_stat_activity| SELECT s.datid,
s.state_change,
s.wait_event_type,
s.wait_event,
+ s.wait_event_arg,
s.state,
s.backend_xid,
s.backend_xmin,
s.query_id,
s.query,
s.backend_type
- FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
+ FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, wait_event_arg, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
LEFT JOIN pg_database d ON ((s.datid = d.oid)))
LEFT JOIN pg_authid u ON ((s.usesysid = u.oid)));
pg_stat_all_indexes| SELECT c.oid AS relid,
@@ -1926,7 +1927,7 @@ pg_stat_gssapi| SELECT pid,
gss_princ AS principal,
gss_enc AS encrypted,
gss_delegation AS credentials_delegated
- FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
+ FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, wait_event_arg, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
WHERE (client_port IS NOT NULL);
pg_stat_io| SELECT backend_type,
object,
@@ -2139,7 +2140,7 @@ pg_stat_replication| SELECT s.pid,
w.sync_priority,
w.sync_state,
w.reply_time
- FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
+ FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, wait_event_arg, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
JOIN pg_stat_get_wal_senders() w(pid, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, write_lag, flush_lag, replay_lag, sync_priority, sync_state, reply_time) ON ((s.pid = w.pid)))
LEFT JOIN pg_authid u ON ((s.usesysid = u.oid)));
pg_stat_replication_slots| SELECT s.slot_name,
@@ -2176,7 +2177,7 @@ pg_stat_ssl| SELECT pid,
ssl_client_dn AS client_dn,
ssl_client_serial AS client_serial,
ssl_issuer_dn AS issuer_dn
- FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
+ FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, wait_event_arg, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
WHERE (client_port IS NOT NULL);
pg_stat_subscription| SELECT su.oid AS subid,
su.subname,
--
2.43.0