</row>
<row>
<entry><literal>%v</literal></entry>
- <entry>Virtual transaction ID (backendID/localXID); see
+ <entry>Virtual transaction ID (procNumber/localXID); see
<xref linkend="transaction-id"/></entry>
<entry>no</entry>
</row>
access functions can be used; these are shown in <xref
linkend="monitoring-stats-backend-funcs-table"/>.
These access functions use the session's backend ID number, which is a
- small positive integer that is distinct from the backend ID of any
+ small integer (>= 0) that is distinct from the backend ID of any
concurrent session, although a session's ID can be recycled as soon as
it exits. The backend ID is used, among other things, to identify the
session's temporary schema if it has one.
arg0 contains the fork to be extended. arg1, arg2, and arg3 contain the
tablespace, database, and relation OIDs identifying the relation. arg4
is the ID of the backend which created the temporary relation for a
- local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared
+ local buffer, or <symbol>INVALID_PROC_NUMBER</symbol> (-1) for a shared
buffer. arg5 is the number of blocks the caller would like to extend
by.</entry>
</row>
arg0 contains the fork to be extended. arg1, arg2, and arg3 contain the
tablespace, database, and relation OIDs identifying the relation. arg4
is the ID of the backend which created the temporary relation for a
- local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared
+ local buffer, or <symbol>INVALID_PROC_NUMBER</symbol> (-1) for a shared
buffer. arg5 is the number of blocks the relation was extended by, this
can be less than the number in the
<literal>buffer-extend-start</literal> due to resource
arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
identifying the relation.
arg5 is the ID of the backend which created the temporary relation for a
- local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.
+ local buffer, or <symbol>INVALID_PROC_NUMBER</symbol> (-1) for a shared buffer.
</entry>
</row>
<row>
arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
identifying the relation.
arg5 is the ID of the backend which created the temporary relation for a
- local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.
+ local buffer, or <symbol>INVALID_PROC_NUMBER</symbol> (-1) for a shared buffer.
arg6 is true if the buffer was found in the pool, false if not.</entry>
</row>
<row>
arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
identifying the relation.
arg5 is the ID of the backend which created the temporary relation for a
- local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.</entry>
+ local buffer, or <symbol>INVALID_PROC_NUMBER</symbol> (-1) for a shared buffer.</entry>
</row>
<row>
<entry><literal>smgr-md-read-done</literal></entry>
arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
identifying the relation.
arg5 is the ID of the backend which created the temporary relation for a
- local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.
+ local buffer, or <symbol>INVALID_PROC_NUMBER</symbol> (-1) for a shared buffer.
arg6 is the number of bytes actually read, while arg7 is the number
requested (if these are different it indicates a short read).</entry>
</row>
arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
identifying the relation.
arg5 is the ID of the backend which created the temporary relation for a
- local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.</entry>
+ local buffer, or <symbol>INVALID_PROC_NUMBER</symbol> (-1) for a shared buffer.</entry>
</row>
<row>
<entry><literal>smgr-md-write-done</literal></entry>
arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
identifying the relation.
arg5 is the ID of the backend which created the temporary relation for a
- local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.
+ local buffer, or <symbol>INVALID_PROC_NUMBER</symbol> (-1) for a shared buffer.
arg6 is the number of bytes actually written, while arg7 is the number
requested (if these are different it indicates a short write).</entry>
</row>
which can be found in <structname>pg_class</structname>.<structfield>relfilenode</structfield>. But
for temporary relations, the file name is of the form
<literal>t<replaceable>BBB</replaceable>_<replaceable>FFF</replaceable></literal>, where <replaceable>BBB</replaceable>
-is the backend ID of the backend which created the file, and <replaceable>FFF</replaceable>
+is the process number of the backend which created the file, and <replaceable>FFF</replaceable>
is the filenode number. In either case, in addition to the main file (a/k/a
main fork), each table and index has a <firstterm>free space map</firstterm> (see <xref
linkend="storage-fsm"/>), which stores information about free space available in
Every transaction is identified by a unique
<literal>VirtualTransactionId</literal> (also called
<literal>virtualXID</literal> or <literal>vxid</literal>), which
- is comprised of a backend ID (or <literal>backendID</literal>)
+ is comprised of a backend's process number (or <literal>procNumber</literal>)
and a sequentially-assigned number local to each backend, known as
<literal>localXID</literal>. For example, the virtual transaction
- ID <literal>4/12532</literal> has a <literal>backendID</literal>
+ ID <literal>4/12532</literal> has a <literal>procNumber</literal>
of <literal>4</literal> and a <literal>localXID</literal> of
<literal>12532</literal>.
</para>
A transaction that has no XID still needs to be identified for various
purposes, notably holding locks. For this purpose we assign a "virtual
transaction ID" or VXID to each top-level transaction. VXIDs are formed from
-two fields, the backendID and a backend-local counter; this arrangement allows
-assignment of a new VXID at transaction start without any contention for
-shared memory. To ensure that a VXID isn't re-used too soon after backend
+two fields, the procNumber and a backend-local counter; this arrangement
+allows assignment of a new VXID at transaction start without any contention
+for shared memory. To ensure that a VXID isn't re-used too soon after backend
exit, we store the last local counter value into shared memory at backend
-exit, and initialize it from the previous value for the same backendID slot
-at backend start. All these counters go back to zero at shared memory
+exit, and initialize it from the previous value for the same PGPROC slot at
+backend start. All these counters go back to zero at shared memory
re-initialization, but that's OK because VXIDs never appear anywhere on-disk.
Internally, a backend needs a way to identify subtransactions whether or not
* still work, just less efficiently -- we handle this case by
* switching to a different bank lock in the loop below.
*/
- if (nextidx != INVALID_PGPROCNO &&
+ if (nextidx != INVALID_PROC_NUMBER &&
GetPGProcByNumber(nextidx)->clogGroupMemberPage != proc->clogGroupMemberPage)
{
/*
* needs an XID status update.
*/
proc->clogGroupMember = false;
- pg_atomic_write_u32(&proc->clogGroupNext, INVALID_PGPROCNO);
+ pg_atomic_write_u32(&proc->clogGroupNext, INVALID_PROC_NUMBER);
return false;
}
* If the list was not empty, the leader will update the status of our
* XID. It is impossible to have followers without a leader because the
* first process that has added itself to the list will always have
- * nextidx as INVALID_PGPROCNO.
+ * nextidx as INVALID_PROC_NUMBER.
*/
- if (nextidx != INVALID_PGPROCNO)
+ if (nextidx != INVALID_PROC_NUMBER)
{
int extraWaits = 0;
}
pgstat_report_wait_end();
- Assert(pg_atomic_read_u32(&proc->clogGroupNext) == INVALID_PGPROCNO);
+ Assert(pg_atomic_read_u32(&proc->clogGroupNext) == INVALID_PROC_NUMBER);
/* Fix semaphore count for any absorbed wakeups */
while (extraWaits-- > 0)
* group.
*/
nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
- INVALID_PGPROCNO);
+ INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
wakeidx = nextidx;
/* Walk the list and update the status of all XIDs. */
- while (nextidx != INVALID_PGPROCNO)
+ while (nextidx != INVALID_PROC_NUMBER)
{
PGPROC *nextproc = &ProcGlobal->allProcs[nextidx];
int thispageno = nextproc->clogGroupMemberPage;
* clogGroupNext to invalid while saving the semaphores to an array, then
* a single write barrier, then another pass unlocking the semaphores.)
*/
- while (wakeidx != INVALID_PGPROCNO)
+ while (wakeidx != INVALID_PROC_NUMBER)
{
PGPROC *wakeproc = &ProcGlobal->allProcs[wakeidx];
wakeidx = pg_atomic_read_u32(&wakeproc->clogGroupNext);
- pg_atomic_write_u32(&wakeproc->clogGroupNext, INVALID_PGPROCNO);
+ pg_atomic_write_u32(&wakeproc->clogGroupNext, INVALID_PROC_NUMBER);
/* ensure all previous writes are visible before follower continues. */
pg_write_barrier();
/*
* Per-backend data starts here. We have two arrays stored in the area
* immediately following the MultiXactStateData struct. Each is indexed by
- * BackendId.
+ * ProcNumber.
*
- * In both arrays, there's a slot for all normal backends (1..MaxBackends)
- * followed by a slot for max_prepared_xacts prepared transactions. Valid
- * BackendIds start from 1; element zero of each array is never used.
+ * In both arrays, there's a slot for all normal backends
+ * (0..MaxBackends-1) followed by a slot for max_prepared_xacts prepared
+ * transactions.
*
* OldestMemberMXactId[k] is the oldest MultiXactId each backend's current
* transaction(s) could possibly be a member of, or InvalidMultiXactId
} MultiXactStateData;
/*
- * Last element of OldestMemberMXactId and OldestVisibleMXactId arrays.
- * Valid elements are (1..MaxOldestSlot); element 0 is never used.
+ * Size of OldestMemberMXactId and OldestVisibleMXactId arrays.
*/
#define MaxOldestSlot (MaxBackends + max_prepared_xacts)
Assert(!TransactionIdEquals(xid1, xid2) || (status1 != status2));
/* MultiXactIdSetOldestMember() must have been called already. */
- Assert(MultiXactIdIsValid(OldestMemberMXactId[MyBackendId]));
+ Assert(MultiXactIdIsValid(OldestMemberMXactId[MyProcNumber]));
/*
* Note: unlike MultiXactIdExpand, we don't bother to check that both XIDs
Assert(TransactionIdIsValid(xid));
/* MultiXactIdSetOldestMember() must have been called already. */
- Assert(MultiXactIdIsValid(OldestMemberMXactId[MyBackendId]));
+ Assert(MultiXactIdIsValid(OldestMemberMXactId[MyProcNumber]));
debug_elog5(DEBUG2, "Expand: received multi %u, xid %u status %s",
multi, xid, mxstatus_to_string(status));
void
MultiXactIdSetOldestMember(void)
{
- if (!MultiXactIdIsValid(OldestMemberMXactId[MyBackendId]))
+ if (!MultiXactIdIsValid(OldestMemberMXactId[MyProcNumber]))
{
MultiXactId nextMXact;
if (nextMXact < FirstMultiXactId)
nextMXact = FirstMultiXactId;
- OldestMemberMXactId[MyBackendId] = nextMXact;
+ OldestMemberMXactId[MyProcNumber] = nextMXact;
LWLockRelease(MultiXactGenLock);
debug_elog4(DEBUG2, "MultiXact: setting OldestMember[%d] = %u",
- MyBackendId, nextMXact);
+ MyProcNumber, nextMXact);
}
}
static void
MultiXactIdSetOldestVisible(void)
{
- if (!MultiXactIdIsValid(OldestVisibleMXactId[MyBackendId]))
+ if (!MultiXactIdIsValid(OldestVisibleMXactId[MyProcNumber]))
{
MultiXactId oldestMXact;
int i;
if (oldestMXact < FirstMultiXactId)
oldestMXact = FirstMultiXactId;
- for (i = 1; i <= MaxOldestSlot; i++)
+ for (i = 0; i < MaxOldestSlot; i++)
{
MultiXactId thisoldest = OldestMemberMXactId[i];
oldestMXact = thisoldest;
}
- OldestVisibleMXactId[MyBackendId] = oldestMXact;
+ OldestVisibleMXactId[MyProcNumber] = oldestMXact;
LWLockRelease(MultiXactGenLock);
debug_elog4(DEBUG2, "MultiXact: setting OldestVisible[%d] = %u",
- MyBackendId, oldestMXact);
+ MyProcNumber, oldestMXact);
}
}
* multi. It cannot possibly still be running.
*/
if (isLockOnly &&
- MultiXactIdPrecedes(multi, OldestVisibleMXactId[MyBackendId]))
+ MultiXactIdPrecedes(multi, OldestVisibleMXactId[MyProcNumber]))
{
debug_elog2(DEBUG2, "GetMembers: a locker-only multi is too old");
*members = NULL;
* We assume that storing a MultiXactId is atomic and so we need not take
* MultiXactGenLock to do this.
*/
- OldestMemberMXactId[MyBackendId] = InvalidMultiXactId;
- OldestVisibleMXactId[MyBackendId] = InvalidMultiXactId;
+ OldestMemberMXactId[MyProcNumber] = InvalidMultiXactId;
+ OldestVisibleMXactId[MyProcNumber] = InvalidMultiXactId;
/*
* Discard the local MultiXactId cache. Since MXactContext was created as
void
AtPrepare_MultiXact(void)
{
- MultiXactId myOldestMember = OldestMemberMXactId[MyBackendId];
+ MultiXactId myOldestMember = OldestMemberMXactId[MyProcNumber];
if (MultiXactIdIsValid(myOldestMember))
RegisterTwoPhaseRecord(TWOPHASE_RM_MULTIXACT_ID, 0,
* Transfer our OldestMemberMXactId value to the slot reserved for the
* prepared transaction.
*/
- myOldestMember = OldestMemberMXactId[MyBackendId];
+ myOldestMember = OldestMemberMXactId[MyProcNumber];
if (MultiXactIdIsValid(myOldestMember))
{
- BackendId dummyBackendId = TwoPhaseGetDummyBackendId(xid, false);
+ ProcNumber dummyProcNumber = TwoPhaseGetDummyProcNumber(xid, false);
/*
* Even though storing MultiXactId is atomic, acquire lock to make
*/
LWLockAcquire(MultiXactGenLock, LW_EXCLUSIVE);
- OldestMemberMXactId[dummyBackendId] = myOldestMember;
- OldestMemberMXactId[MyBackendId] = InvalidMultiXactId;
+ OldestMemberMXactId[dummyProcNumber] = myOldestMember;
+ OldestMemberMXactId[MyProcNumber] = InvalidMultiXactId;
LWLockRelease(MultiXactGenLock);
}
* We assume that storing a MultiXactId is atomic and so we need not take
* MultiXactGenLock to do this.
*/
- OldestVisibleMXactId[MyBackendId] = InvalidMultiXactId;
+ OldestVisibleMXactId[MyProcNumber] = InvalidMultiXactId;
/*
* Discard the local MultiXactId cache like in AtEOXact_MultiXact.
multixact_twophase_recover(TransactionId xid, uint16 info,
void *recdata, uint32 len)
{
- BackendId dummyBackendId = TwoPhaseGetDummyBackendId(xid, false);
+ ProcNumber dummyProcNumber = TwoPhaseGetDummyProcNumber(xid, false);
MultiXactId oldestMember;
/*
Assert(len == sizeof(MultiXactId));
oldestMember = *((MultiXactId *) recdata);
- OldestMemberMXactId[dummyBackendId] = oldestMember;
+ OldestMemberMXactId[dummyProcNumber] = oldestMember;
}
/*
multixact_twophase_postcommit(TransactionId xid, uint16 info,
void *recdata, uint32 len)
{
- BackendId dummyBackendId = TwoPhaseGetDummyBackendId(xid, true);
+ ProcNumber dummyProcNumber = TwoPhaseGetDummyProcNumber(xid, true);
Assert(len == sizeof(MultiXactId));
- OldestMemberMXactId[dummyBackendId] = InvalidMultiXactId;
+ OldestMemberMXactId[dummyProcNumber] = InvalidMultiXactId;
}
/*
{
Size size;
- /* We need 2*MaxOldestSlot + 1 perBackendXactIds[] entries */
+ /* We need 2*MaxOldestSlot perBackendXactIds[] entries */
#define SHARED_MULTIXACT_STATE_SIZE \
- add_size(offsetof(MultiXactStateData, perBackendXactIds) + sizeof(MultiXactId), \
+ add_size(offsetof(MultiXactStateData, perBackendXactIds), \
mul_size(sizeof(MultiXactId) * 2, MaxOldestSlot))
size = SHARED_MULTIXACT_STATE_SIZE;
Assert(found);
/*
- * Set up array pointers. Note that perBackendXactIds[0] is wasted space
- * since we only use indexes 1..MaxOldestSlot in each array.
+ * Set up array pointers.
*/
OldestMemberMXactId = MultiXactState->perBackendXactIds;
OldestVisibleMXactId = OldestMemberMXactId + MaxOldestSlot;
nextMXact = FirstMultiXactId;
oldestMXact = nextMXact;
- for (i = 1; i <= MaxOldestSlot; i++)
+ for (i = 0; i < MaxOldestSlot; i++)
{
MultiXactId thisoldest;
bool is_superuser;
PGPROC *parallel_leader_pgproc;
pid_t parallel_leader_pid;
- BackendId parallel_leader_backend_id;
+ ProcNumber parallel_leader_proc_number;
TimestampTz xact_ts;
TimestampTz stmt_ts;
SerializableXactHandle serializable_xact_handle;
&fps->temp_toast_namespace_id);
fps->parallel_leader_pgproc = MyProc;
fps->parallel_leader_pid = MyProcPid;
- fps->parallel_leader_backend_id = MyBackendId;
+ fps->parallel_leader_proc_number = MyProcNumber;
fps->xact_ts = GetCurrentTransactionStartTimestamp();
fps->stmt_ts = GetCurrentStatementStartTimestamp();
fps->serializable_xact_handle = ShareSerializableXact();
/* Arrange to signal the leader if we exit. */
ParallelLeaderPid = fps->parallel_leader_pid;
- ParallelLeaderBackendId = fps->parallel_leader_backend_id;
+ ParallelLeaderProcNumber = fps->parallel_leader_proc_number;
before_shmem_exit(ParallelWorkerShutdown, PointerGetDatum(seg));
/*
mqh = shm_mq_attach(mq, seg, NULL);
pq_redirect_to_shm_mq(seg, mqh);
pq_set_parallel_leader(fps->parallel_leader_pid,
- fps->parallel_leader_backend_id);
+ fps->parallel_leader_proc_number);
/*
* Send a BackendKeyData message to the process that initiated parallelism
{
SendProcSignal(ParallelLeaderPid,
PROCSIG_PARALLEL_MESSAGE,
- ParallelLeaderBackendId);
+ ParallelLeaderProcNumber);
dsm_detach((dsm_segment *) DatumGetPointer(arg));
}
*
* 3. To begin COMMIT PREPARED or ROLLBACK PREPARED, check that the entry is
* valid and not locked, then mark the entry as locked by storing my current
- * backend ID into locking_backend. This prevents concurrent attempts to
+ * proc number into locking_backend. This prevents concurrent attempts to
* commit or rollback the same prepared xact.
*
* 4. On completion of COMMIT PREPARED or ROLLBACK PREPARED, remove the entry
TransactionId xid; /* The GXACT id */
Oid owner; /* ID of user that executed the xact */
- BackendId locking_backend; /* backend currently working on the xact */
+ ProcNumber locking_backend; /* backend currently working on the xact */
bool valid; /* true if PGPROC entry is in proc array */
bool ondisk; /* true if prepare state file is on disk */
bool inredo; /* true if entry was added via xlog_redo */
if (!MyLockedGxact->valid)
RemoveGXact(MyLockedGxact);
else
- MyLockedGxact->locking_backend = InvalidBackendId;
+ MyLockedGxact->locking_backend = INVALID_PROC_NUMBER;
LWLockRelease(TwoPhaseStateLock);
MyLockedGxact = NULL;
PostPrepare_Twophase(void)
{
LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
- MyLockedGxact->locking_backend = InvalidBackendId;
+ MyLockedGxact->locking_backend = INVALID_PROC_NUMBER;
LWLockRelease(TwoPhaseStateLock);
MyLockedGxact = NULL;
{
/* clone VXID, for TwoPhaseGetXidByVirtualXID() to find */
proc->vxid.lxid = MyProc->vxid.lxid;
- proc->vxid.backendId = MyBackendId;
+ proc->vxid.procNumber = MyProcNumber;
}
else
{
Assert(AmStartupProcess() || !IsPostmasterEnvironment);
/* GetLockConflicts() uses this to specify a wait on the XID */
proc->vxid.lxid = xid;
- proc->vxid.backendId = InvalidBackendId;
+ proc->vxid.procNumber = INVALID_PROC_NUMBER;
}
proc->xid = xid;
Assert(proc->xmin == InvalidTransactionId);
gxact->prepared_at = prepared_at;
gxact->xid = xid;
gxact->owner = owner;
- gxact->locking_backend = MyBackendId;
+ gxact->locking_backend = MyProcNumber;
gxact->valid = false;
gxact->inredo = false;
strcpy(gxact->gid, gid);
continue;
/* Found it, but has someone else got it locked? */
- if (gxact->locking_backend != InvalidBackendId)
+ if (gxact->locking_backend != INVALID_PROC_NUMBER)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("prepared transaction with identifier \"%s\" is busy",
errhint("Connect to the database where the transaction was prepared to finish it.")));
/* OK for me to lock it */
- gxact->locking_backend = MyBackendId;
+ gxact->locking_backend = MyProcNumber;
MyLockedGxact = gxact;
LWLockRelease(TwoPhaseStateLock);
*
* (This won't find recovered xacts.) If more than one matches, return any
* and set "have_more" to true. To witness multiple matches, a single
- * BackendId must consume 2^32 LXIDs, with no intervening database restart.
+ * proc number must consume 2^32 LXIDs, with no intervening database restart.
*/
TransactionId
TwoPhaseGetXidByVirtualXID(VirtualTransactionId vxid,
GET_VXID_FROM_PGPROC(proc_vxid, *proc);
if (VirtualTransactionIdEquals(vxid, proc_vxid))
{
- /* Startup process sets proc->backendId to InvalidBackendId. */
+ /*
+ * Startup process sets proc->vxid.procNumber to
+ * INVALID_PROC_NUMBER.
+ */
Assert(!gxact->inredo);
if (result != InvalidTransactionId)
}
/*
- * TwoPhaseGetDummyBackendId
- * Get the dummy backend ID for prepared transaction specified by XID
+ * TwoPhaseGetDummyProcNumber
+ * Get the dummy proc number for prepared transaction specified by XID
*
- * Dummy backend IDs are similar to real backend IDs of real backends.
- * They start at MaxBackends + 1, and are unique across all currently active
- * real backends and prepared transactions. If lock_held is set to true,
+ * Dummy proc numbers are similar to proc numbers of real backends. They
+ * start at MaxBackends, and are unique across all currently active real
+ * backends and prepared transactions. If lock_held is set to true,
* TwoPhaseStateLock will not be taken, so the caller had better hold it.
*/
-BackendId
-TwoPhaseGetDummyBackendId(TransactionId xid, bool lock_held)
+ProcNumber
+TwoPhaseGetDummyProcNumber(TransactionId xid, bool lock_held)
{
GlobalTransaction gxact = TwoPhaseGetGXact(xid, lock_held);
- return gxact->pgprocno + 1;
+ return gxact->pgprocno;
}
/*
gxact->prepare_end_lsn = end_lsn;
gxact->xid = hdr->xid;
gxact->owner = hdr->owner;
- gxact->locking_backend = InvalidBackendId;
+ gxact->locking_backend = INVALID_PROC_NUMBER;
gxact->valid = false;
gxact->ondisk = XLogRecPtrIsInvalid(start_lsn);
gxact->inredo = true; /* yes, added in redo */
AtStart_ResourceOwner();
/*
- * Assign a new LocalTransactionId, and combine it with the backendId to
+ * Assign a new LocalTransactionId, and combine it with the proc number to
* form a virtual transaction id.
*/
- vxid.backendId = MyBackendId;
+ vxid.procNumber = MyProcNumber;
vxid.localTransactionId = GetNextLocalTransactionId();
/*
/*
* Advertise it in the proc array. We assume assignment of
- * localTransactionId is atomic, and the backendId should be set already.
+ * localTransactionId is atomic, and the proc number should be set
+ * already.
*/
- Assert(MyProc->vxid.backendId == vxid.backendId);
+ Assert(MyProc->vxid.procNumber == vxid.procNumber);
MyProc->vxid.lxid = vxid.localTransactionId;
TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
* same relation (with some scheme to handle invalidations
* safely), but for now we'll call smgropen() every time.
*/
- reln = smgropen(block->rlocator, InvalidBackendId);
+ reln = smgropen(block->rlocator, INVALID_PROC_NUMBER);
/*
* If the relation file doesn't exist on disk, for example because
}
/* Open the relation at smgr level */
- smgr = smgropen(rlocator, InvalidBackendId);
+ smgr = smgropen(rlocator, INVALID_PROC_NUMBER);
/*
* Create the target file if it doesn't already exist. This lets us cope
* We will never be working with temp rels during recovery or while
* syncing WAL-skipped files.
*/
- rel->rd_backend = InvalidBackendId;
+ rel->rd_backend = INVALID_PROC_NUMBER;
/* It must be a permanent table here */
rel->rd_rel->relpersistence = RELPERSISTENCE_PERMANENT;
* Set up a non-pinned SMgrRelation reference, so that we don't need to
* worry about unpinning it on error.
*/
- rel->rd_smgr = smgropen(rlocator, InvalidBackendId);
+ rel->rd_smgr = smgropen(rlocator, INVALID_PROC_NUMBER);
return rel;
}
char *lastslash;
char *ipath;
- path = GetRelationPath(dboid, spcoid, relfilenumber, InvalidBackendId,
+ path = GetRelationPath(dboid, spcoid, relfilenumber, INVALID_PROC_NUMBER,
forknum);
lastslash = strrchr(path, '/');
RelFileLocatorBackend rlocator;
char *rpath;
bool collides;
- BackendId backend;
+ ProcNumber procNumber;
/*
* If we ever get here during pg_upgrade, there's something wrong; all
switch (relpersistence)
{
case RELPERSISTENCE_TEMP:
- backend = BackendIdForTempRelations();
+ procNumber = ProcNumberForTempRelations();
break;
case RELPERSISTENCE_UNLOGGED:
case RELPERSISTENCE_PERMANENT:
- backend = InvalidBackendId;
+ procNumber = INVALID_PROC_NUMBER;
break;
default:
elog(ERROR, "invalid relpersistence: %c", relpersistence);
InvalidOid : MyDatabaseId;
/*
- * The relpath will vary based on the backend ID, so we must initialize
- * that properly here to make sure that any collisions based on filename
- * are properly detected.
+ * The relpath will vary based on the backend number, so we must
+ * initialize that properly here to make sure that any collisions based on
+ * filename are properly detected.
*/
- rlocator.backend = backend;
+ rlocator.backend = procNumber;
do
{
checkTempNamespaceStatus(Oid namespaceId)
{
PGPROC *proc;
- int backendId;
+ ProcNumber procNumber;
Assert(OidIsValid(MyDatabaseId));
- backendId = GetTempNamespaceBackendId(namespaceId);
+ procNumber = GetTempNamespaceProcNumber(namespaceId);
/* No such namespace, or its name shows it's not temp? */
- if (backendId == InvalidBackendId)
+ if (procNumber == INVALID_PROC_NUMBER)
return TEMP_NAMESPACE_NOT_TEMP;
/* Is the backend alive? */
- proc = BackendIdGetProc(backendId);
+ proc = ProcNumberGetProc(procNumber);
if (proc == NULL)
return TEMP_NAMESPACE_IDLE;
}
/*
- * GetTempNamespaceBackendId - if the given namespace is a temporary-table
- * namespace (either my own, or another backend's), return the BackendId
+ * GetTempNamespaceProcNumber - if the given namespace is a temporary-table
+ * namespace (either my own, or another backend's), return the proc number
* that owns it. Temporary-toast-table namespaces are included, too.
- * If it isn't a temp namespace, return InvalidBackendId.
+ * If it isn't a temp namespace, return INVALID_PROC_NUMBER.
*/
-int
-GetTempNamespaceBackendId(Oid namespaceId)
+ProcNumber
+GetTempNamespaceProcNumber(Oid namespaceId)
{
int result;
char *nspname;
/* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
nspname = get_namespace_name(namespaceId);
if (!nspname)
- return InvalidBackendId; /* no such namespace? */
+ return INVALID_PROC_NUMBER; /* no such namespace? */
if (strncmp(nspname, "pg_temp_", 8) == 0)
result = atoi(nspname + 8);
else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
result = atoi(nspname + 14);
else
- result = InvalidBackendId;
+ result = INVALID_PROC_NUMBER;
pfree(nspname);
return result;
}
/*
* Do not allow a Hot Standby session to make temp tables. Aside from
* problems with modifying the system catalogs, there is a naming
- * conflict: pg_temp_N belongs to the session with BackendId N on the
- * primary, not to a hot standby session with the same BackendId. We
+ * conflict: pg_temp_N belongs to the session with proc number N on the
+ * primary, not to a hot standby session with the same proc number. We
* should not be able to get here anyway due to XactReadOnly checks, but
* let's just make real sure. Note that this also backstops various
* operations that allow XactReadOnly transactions to modify temp tables;
(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
errmsg("cannot create temporary tables during a parallel operation")));
- snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
+ snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyProcNumber);
namespaceId = get_namespace_oid(namespaceName, true);
if (!OidIsValid(namespaceId))
* dropping a parent table should make its toast table go away.)
*/
snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
- MyBackendId);
+ MyProcNumber);
toastspaceId = get_namespace_oid(namespaceName, true);
if (!OidIsValid(toastspaceId))
typedef struct PendingRelDelete
{
RelFileLocator rlocator; /* relation that may need to be deleted */
- BackendId backend; /* InvalidBackendId if not a temp rel */
+ ProcNumber procNumber; /* INVALID_PROC_NUMBER if not a temp rel */
bool atCommit; /* T=delete at commit; F=delete at abort */
int nestLevel; /* xact nesting level of request */
struct PendingRelDelete *next; /* linked-list link */
bool register_delete)
{
SMgrRelation srel;
- BackendId backend;
+ ProcNumber procNumber;
bool needs_wal;
Assert(!IsInParallelMode()); /* couldn't update pendingSyncHash */
switch (relpersistence)
{
case RELPERSISTENCE_TEMP:
- backend = BackendIdForTempRelations();
+ procNumber = ProcNumberForTempRelations();
needs_wal = false;
break;
case RELPERSISTENCE_UNLOGGED:
- backend = InvalidBackendId;
+ procNumber = INVALID_PROC_NUMBER;
needs_wal = false;
break;
case RELPERSISTENCE_PERMANENT:
- backend = InvalidBackendId;
+ procNumber = INVALID_PROC_NUMBER;
needs_wal = true;
break;
default:
return NULL; /* placate compiler */
}
- srel = smgropen(rlocator, backend);
+ srel = smgropen(rlocator, procNumber);
smgrcreate(srel, MAIN_FORKNUM, false);
if (needs_wal)
pending = (PendingRelDelete *)
MemoryContextAlloc(TopMemoryContext, sizeof(PendingRelDelete));
pending->rlocator = rlocator;
- pending->backend = backend;
+ pending->procNumber = procNumber;
pending->atCommit = false; /* delete if abort */
pending->nestLevel = GetCurrentTransactionNestLevel();
pending->next = pendingDeletes;
if (relpersistence == RELPERSISTENCE_PERMANENT && !XLogIsNeeded())
{
- Assert(backend == InvalidBackendId);
+ Assert(procNumber == INVALID_PROC_NUMBER);
AddPendingSync(&rlocator);
}
pending = (PendingRelDelete *)
MemoryContextAlloc(TopMemoryContext, sizeof(PendingRelDelete));
pending->rlocator = rel->rd_locator;
- pending->backend = rel->rd_backend;
+ pending->procNumber = rel->rd_backend;
pending->atCommit = true; /* delete if commit */
pending->nestLevel = GetCurrentTransactionNestLevel();
pending->next = pendingDeletes;
{
SMgrRelation srel;
- srel = smgropen(pending->rlocator, pending->backend);
+ srel = smgropen(pending->rlocator, pending->procNumber);
/* allocate the initial array, or extend it, if needed */
if (maxrels == 0)
BlockNumber total_blocks = 0;
SMgrRelation srel;
- srel = smgropen(pendingsync->rlocator, InvalidBackendId);
+ srel = smgropen(pendingsync->rlocator, INVALID_PROC_NUMBER);
/*
* We emit newpage WAL records for smaller relations.
for (pending = pendingDeletes; pending != NULL; pending = pending->next)
{
if (pending->nestLevel >= nestLevel && pending->atCommit == forCommit
- && pending->backend == InvalidBackendId)
+ && pending->procNumber == INVALID_PROC_NUMBER)
nrels++;
}
if (nrels == 0)
for (pending = pendingDeletes; pending != NULL; pending = pending->next)
{
if (pending->nestLevel >= nestLevel && pending->atCommit == forCommit
- && pending->backend == InvalidBackendId)
+ && pending->procNumber == INVALID_PROC_NUMBER)
{
*rptr = pending->rlocator;
rptr++;
xl_smgr_create *xlrec = (xl_smgr_create *) XLogRecGetData(record);
SMgrRelation reln;
- reln = smgropen(xlrec->rlocator, InvalidBackendId);
+ reln = smgropen(xlrec->rlocator, INVALID_PROC_NUMBER);
smgrcreate(reln, xlrec->forkNum, true);
}
else if (info == XLOG_SMGR_TRUNCATE)
int nforks = 0;
bool need_fsm_vacuum = false;
- reln = smgropen(xlrec->rlocator, InvalidBackendId);
+ reln = smgropen(xlrec->rlocator, INVALID_PROC_NUMBER);
/*
* Forcibly create relation if it doesn't exist (which suggests that
{
int32 pid; /* either a PID or InvalidPid */
Oid dboid; /* backend's database OID, or InvalidOid */
- BackendId nextListener; /* id of next listener, or InvalidBackendId */
+ ProcNumber nextListener; /* id of next listener, or INVALID_PROC_NUMBER */
QueuePosition pos; /* backend has read queue up to here */
} QueueBackendStatus;
* NotifyQueueTailLock, then NotifyQueueLock, and lastly SLRU bank lock.
*
* Each backend uses the backend[] array entry with index equal to its
- * BackendId (which can range from 1 to MaxBackends). We rely on this to make
- * SendProcSignal fast.
+ * ProcNumber. We rely on this to make SendProcSignal fast.
*
* The backend[] array entries for actively-listening backends are threaded
* together using firstListener and the nextListener links, so that we can
* scan them without having to iterate over inactive entries. We keep this
- * list in order by BackendId so that the scan is cache-friendly when there
+ * list in order by ProcNumber so that the scan is cache-friendly when there
* are many active entries.
*/
typedef struct AsyncQueueControl
* listening backend */
int stopPage; /* oldest unrecycled page; must be <=
* tail.page */
- BackendId firstListener; /* id of first listener, or InvalidBackendId */
+ ProcNumber firstListener; /* id of first listener, or
+ * INVALID_PROC_NUMBER */
TimestampTz lastQueueFillWarn; /* time of last queue-full msg */
QueueBackendStatus backend[FLEXIBLE_ARRAY_MEMBER];
- /* backend[0] is not used; used entries are from [1] to [MaxBackends] */
} AsyncQueueControl;
static AsyncQueueControl *asyncQueueControl;
Size size;
/* This had better match AsyncShmemInit */
- size = mul_size(MaxBackends + 1, sizeof(QueueBackendStatus));
+ size = mul_size(MaxBackends, sizeof(QueueBackendStatus));
size = add_size(size, offsetof(AsyncQueueControl, backend));
size = add_size(size, SimpleLruShmemSize(notify_buffers, 0));
/*
* Create or attach to the AsyncQueueControl structure.
- *
- * The used entries in the backend[] array run from 1 to MaxBackends; the
- * zero'th entry is unused but must be allocated.
*/
- size = mul_size(MaxBackends + 1, sizeof(QueueBackendStatus));
+ size = mul_size(MaxBackends, sizeof(QueueBackendStatus));
size = add_size(size, offsetof(AsyncQueueControl, backend));
asyncQueueControl = (AsyncQueueControl *)
SET_QUEUE_POS(QUEUE_HEAD, 0, 0);
SET_QUEUE_POS(QUEUE_TAIL, 0, 0);
QUEUE_STOP_PAGE = 0;
- QUEUE_FIRST_LISTENER = InvalidBackendId;
+ QUEUE_FIRST_LISTENER = INVALID_PROC_NUMBER;
asyncQueueControl->lastQueueFillWarn = 0;
- /* zero'th entry won't be used, but let's initialize it anyway */
- for (int i = 0; i <= MaxBackends; i++)
+ for (int i = 0; i < MaxBackends; i++)
{
QUEUE_BACKEND_PID(i) = InvalidPid;
QUEUE_BACKEND_DBOID(i) = InvalidOid;
- QUEUE_NEXT_LISTENER(i) = InvalidBackendId;
+ QUEUE_NEXT_LISTENER(i) = INVALID_PROC_NUMBER;
SET_QUEUE_POS(QUEUE_BACKEND_POS(i), 0, 0);
}
}
{
QueuePosition head;
QueuePosition max;
- BackendId prevListener;
+ ProcNumber prevListener;
/*
* Nothing to do if we are already listening to something, nor if we
LWLockAcquire(NotifyQueueLock, LW_EXCLUSIVE);
head = QUEUE_HEAD;
max = QUEUE_TAIL;
- prevListener = InvalidBackendId;
- for (BackendId i = QUEUE_FIRST_LISTENER; i > 0; i = QUEUE_NEXT_LISTENER(i))
+ prevListener = INVALID_PROC_NUMBER;
+ for (ProcNumber i = QUEUE_FIRST_LISTENER; i != INVALID_PROC_NUMBER; i = QUEUE_NEXT_LISTENER(i))
{
if (QUEUE_BACKEND_DBOID(i) == MyDatabaseId)
max = QUEUE_POS_MAX(max, QUEUE_BACKEND_POS(i));
/* Also find last listening backend before this one */
- if (i < MyBackendId)
+ if (i < MyProcNumber)
prevListener = i;
}
- QUEUE_BACKEND_POS(MyBackendId) = max;
- QUEUE_BACKEND_PID(MyBackendId) = MyProcPid;
- QUEUE_BACKEND_DBOID(MyBackendId) = MyDatabaseId;
+ QUEUE_BACKEND_POS(MyProcNumber) = max;
+ QUEUE_BACKEND_PID(MyProcNumber) = MyProcPid;
+ QUEUE_BACKEND_DBOID(MyProcNumber) = MyDatabaseId;
/* Insert backend into list of listeners at correct position */
- if (prevListener > 0)
+ if (prevListener != INVALID_PROC_NUMBER)
{
- QUEUE_NEXT_LISTENER(MyBackendId) = QUEUE_NEXT_LISTENER(prevListener);
- QUEUE_NEXT_LISTENER(prevListener) = MyBackendId;
+ QUEUE_NEXT_LISTENER(MyProcNumber) = QUEUE_NEXT_LISTENER(prevListener);
+ QUEUE_NEXT_LISTENER(prevListener) = MyProcNumber;
}
else
{
- QUEUE_NEXT_LISTENER(MyBackendId) = QUEUE_FIRST_LISTENER;
- QUEUE_FIRST_LISTENER = MyBackendId;
+ QUEUE_NEXT_LISTENER(MyProcNumber) = QUEUE_FIRST_LISTENER;
+ QUEUE_FIRST_LISTENER = MyProcNumber;
}
LWLockRelease(NotifyQueueLock);
*/
LWLockAcquire(NotifyQueueLock, LW_EXCLUSIVE);
/* Mark our entry as invalid */
- QUEUE_BACKEND_PID(MyBackendId) = InvalidPid;
- QUEUE_BACKEND_DBOID(MyBackendId) = InvalidOid;
+ QUEUE_BACKEND_PID(MyProcNumber) = InvalidPid;
+ QUEUE_BACKEND_DBOID(MyProcNumber) = InvalidOid;
/* and remove it from the list */
- if (QUEUE_FIRST_LISTENER == MyBackendId)
- QUEUE_FIRST_LISTENER = QUEUE_NEXT_LISTENER(MyBackendId);
+ if (QUEUE_FIRST_LISTENER == MyProcNumber)
+ QUEUE_FIRST_LISTENER = QUEUE_NEXT_LISTENER(MyProcNumber);
else
{
- for (BackendId i = QUEUE_FIRST_LISTENER; i > 0; i = QUEUE_NEXT_LISTENER(i))
+ for (ProcNumber i = QUEUE_FIRST_LISTENER; i != INVALID_PROC_NUMBER; i = QUEUE_NEXT_LISTENER(i))
{
- if (QUEUE_NEXT_LISTENER(i) == MyBackendId)
+ if (QUEUE_NEXT_LISTENER(i) == MyProcNumber)
{
- QUEUE_NEXT_LISTENER(i) = QUEUE_NEXT_LISTENER(MyBackendId);
+ QUEUE_NEXT_LISTENER(i) = QUEUE_NEXT_LISTENER(MyProcNumber);
break;
}
}
}
- QUEUE_NEXT_LISTENER(MyBackendId) = InvalidBackendId;
+ QUEUE_NEXT_LISTENER(MyProcNumber) = INVALID_PROC_NUMBER;
LWLockRelease(NotifyQueueLock);
/* mark ourselves as no longer listed in the global array */
QueuePosition min = QUEUE_HEAD;
int32 minPid = InvalidPid;
- for (BackendId i = QUEUE_FIRST_LISTENER; i > 0; i = QUEUE_NEXT_LISTENER(i))
+ for (ProcNumber i = QUEUE_FIRST_LISTENER; i != INVALID_PROC_NUMBER; i = QUEUE_NEXT_LISTENER(i))
{
Assert(QUEUE_BACKEND_PID(i) != InvalidPid);
min = QUEUE_POS_MIN(min, QUEUE_BACKEND_POS(i));
* behind. Waken them anyway if they're far enough behind, so that they'll
* advance their queue position pointers, allowing the global tail to advance.
*
- * Since we know the BackendId and the Pid the signaling is quite cheap.
+ * Since we know the ProcNumber and the Pid the signaling is quite cheap.
*
* This is called during CommitTransaction(), so it's important for it
* to have very low probability of failure.
SignalBackends(void)
{
int32 *pids;
- BackendId *ids;
+ ProcNumber *procnos;
int count;
/*
* preallocate the arrays? They're not that large, though.
*/
pids = (int32 *) palloc(MaxBackends * sizeof(int32));
- ids = (BackendId *) palloc(MaxBackends * sizeof(BackendId));
+ procnos = (ProcNumber *) palloc(MaxBackends * sizeof(ProcNumber));
count = 0;
LWLockAcquire(NotifyQueueLock, LW_EXCLUSIVE);
- for (BackendId i = QUEUE_FIRST_LISTENER; i > 0; i = QUEUE_NEXT_LISTENER(i))
+ for (ProcNumber i = QUEUE_FIRST_LISTENER; i != INVALID_PROC_NUMBER; i = QUEUE_NEXT_LISTENER(i))
{
int32 pid = QUEUE_BACKEND_PID(i);
QueuePosition pos;
}
/* OK, need to signal this one */
pids[count] = pid;
- ids[count] = i;
+ procnos[count] = i;
count++;
}
LWLockRelease(NotifyQueueLock);
* NotifyQueueLock; which is unlikely but certainly possible. So we
* just log a low-level debug message if it happens.
*/
- if (SendProcSignal(pid, PROCSIG_NOTIFY_INTERRUPT, ids[i]) < 0)
+ if (SendProcSignal(pid, PROCSIG_NOTIFY_INTERRUPT, procnos[i]) < 0)
elog(DEBUG3, "could not signal backend with PID %d: %m", pid);
}
pfree(pids);
- pfree(ids);
+ pfree(procnos);
}
/*
/* Fetch current state */
LWLockAcquire(NotifyQueueLock, LW_SHARED);
/* Assert checks that we have a valid state entry */
- Assert(MyProcPid == QUEUE_BACKEND_PID(MyBackendId));
- pos = QUEUE_BACKEND_POS(MyBackendId);
+ Assert(MyProcPid == QUEUE_BACKEND_PID(MyProcNumber));
+ pos = QUEUE_BACKEND_POS(MyProcNumber);
head = QUEUE_HEAD;
LWLockRelease(NotifyQueueLock);
{
/* Update shared state */
LWLockAcquire(NotifyQueueLock, LW_SHARED);
- QUEUE_BACKEND_POS(MyBackendId) = pos;
+ QUEUE_BACKEND_POS(MyProcNumber) = pos;
LWLockRelease(NotifyQueueLock);
}
PG_END_TRY();
*/
LWLockAcquire(NotifyQueueLock, LW_EXCLUSIVE);
min = QUEUE_HEAD;
- for (BackendId i = QUEUE_FIRST_LISTENER; i > 0; i = QUEUE_NEXT_LISTENER(i))
+ for (ProcNumber i = QUEUE_FIRST_LISTENER; i != INVALID_PROC_NUMBER; i = QUEUE_NEXT_LISTENER(i))
{
Assert(QUEUE_BACKEND_PID(i) != InvalidPid);
min = QUEUE_POS_MIN(min, QUEUE_BACKEND_POS(i));
rlocator.dbOid = dbid;
rlocator.relNumber = relfilenumber;
- smgr = smgropen(rlocator, InvalidBackendId);
+ smgr = smgropen(rlocator, INVALID_PROC_NUMBER);
nblocks = smgrnblocks(smgr, MAIN_FORKNUM);
smgrclose(smgr);
/* If requested, publish who we're going to wait for. */
if (progress)
{
- PGPROC *holder = BackendIdGetProc(old_snapshots[i].backendId);
+ PGPROC *holder = ProcNumberGetProc(old_snapshots[i].procNumber);
if (holder)
pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID,
{
SMgrRelation srel;
- srel = smgropen(rel->rd_locator, InvalidBackendId);
+ srel = smgropen(rel->rd_locator, INVALID_PROC_NUMBER);
smgrcreate(srel, INIT_FORKNUM, false);
log_smgrcreate(&rel->rd_locator, INIT_FORKNUM);
fill_seq_fork_with_data(rel, tuple, INIT_FORKNUM);
static shm_mq_handle *pq_mq_handle;
static bool pq_mq_busy = false;
static pid_t pq_mq_parallel_leader_pid = 0;
-static pid_t pq_mq_parallel_leader_backend_id = InvalidBackendId;
+static pid_t pq_mq_parallel_leader_proc_number = INVALID_PROC_NUMBER;
static void pq_cleanup_redirect_to_shm_mq(dsm_segment *seg, Datum arg);
static void mq_comm_reset(void);
* message data via the shm_mq.
*/
void
-pq_set_parallel_leader(pid_t pid, BackendId backend_id)
+pq_set_parallel_leader(pid_t pid, ProcNumber procNumber)
{
Assert(PqCommMethods == &PqCommMqMethods);
pq_mq_parallel_leader_pid = pid;
- pq_mq_parallel_leader_backend_id = backend_id;
+ pq_mq_parallel_leader_proc_number = procNumber;
}
static void
if (IsLogicalParallelApplyWorker())
SendProcSignal(pq_mq_parallel_leader_pid,
PROCSIG_PARALLEL_APPLY_MESSAGE,
- pq_mq_parallel_leader_backend_id);
+ pq_mq_parallel_leader_proc_number);
else
{
Assert(IsParallelWorker());
SendProcSignal(pq_mq_parallel_leader_pid,
PROCSIG_PARALLEL_MESSAGE,
- pq_mq_parallel_leader_backend_id);
+ pq_mq_parallel_leader_proc_number);
}
}
/* Shared memory area for archiver process */
typedef struct PgArchData
{
- int pgprocno; /* pgprocno of archiver process */
+ int pgprocno; /* proc number of archiver process */
/*
* Forces a directory scan in pgarch_readyXlog().
{
/* First time through, so initialize */
MemSet(PgArch, 0, PgArchShmemSize());
- PgArch->pgprocno = INVALID_PGPROCNO;
+ PgArch->pgprocno = INVALID_PROC_NUMBER;
pg_atomic_init_u32(&PgArch->force_dir_scan, 0);
}
}
on_shmem_exit(pgarch_die, 0);
/*
- * Advertise our pgprocno so that backends can use our latch to wake us up
- * while we're sleeping.
+ * Advertise our proc number so that backends can use our latch to wake us
+ * up while we're sleeping.
*/
PgArch->pgprocno = MyProcNumber;
* process' (or no process') latch. Even in that case the archiver will
* be relaunched shortly and will start archiving.
*/
- if (arch_pgprocno != INVALID_PGPROCNO)
+ if (arch_pgprocno != INVALID_PROC_NUMBER)
SetLatch(&ProcGlobal->allProcs[arch_pgprocno].procLatch);
}
static void
pgarch_die(int code, Datum arg)
{
- PgArch->pgprocno = INVALID_PGPROCNO;
+ PgArch->pgprocno = INVALID_PROC_NUMBER;
}
/*
* and so the LSN might point to the start of the next file even though
* that might happen to be in the middle of a WAL record.
*
- * summarizer_pgprocno is the pgprocno value for the summarizer process,
- * if one is running, or else INVALID_PGPROCNO.
+ * summarizer_pgprocno is the proc number of the summarizer process, if
+ * one is running, or else INVALID_PROC_NUMBER.
*
* pending_lsn is used by the summarizer to advertise the ending LSN of a
* record it has recently read. It shouldn't ever be less than
TimeLineID summarized_tli;
XLogRecPtr summarized_lsn;
bool lsn_is_exact;
- int summarizer_pgprocno;
+ ProcNumber summarizer_pgprocno;
XLogRecPtr pending_lsn;
/*
WalSummarizerCtl->summarized_tli = 0;
WalSummarizerCtl->summarized_lsn = InvalidXLogRecPtr;
WalSummarizerCtl->lsn_is_exact = false;
- WalSummarizerCtl->summarizer_pgprocno = INVALID_PGPROCNO;
+ WalSummarizerCtl->summarizer_pgprocno = INVALID_PROC_NUMBER;
WalSummarizerCtl->pending_lsn = InvalidXLogRecPtr;
ConditionVariableInit(&WalSummarizerCtl->summary_file_cv);
}
*summarized_tli = WalSummarizerCtl->summarized_tli;
*summarized_lsn = WalSummarizerCtl->summarized_lsn;
- if (summarizer_pgprocno == INVALID_PGPROCNO)
+ if (summarizer_pgprocno == INVALID_PROC_NUMBER)
{
/*
* If the summarizer has exited, the fact that it had processed
void
SetWalSummarizerLatch(void)
{
- int pgprocno;
+ ProcNumber pgprocno;
if (WalSummarizerCtl == NULL)
return;
pgprocno = WalSummarizerCtl->summarizer_pgprocno;
LWLockRelease(WALSummarizerLock);
- if (pgprocno != INVALID_PGPROCNO)
+ if (pgprocno != INVALID_PROC_NUMBER)
SetLatch(&ProcGlobal->allProcs[pgprocno].procLatch);
}
WalSummarizerShutdown(int code, Datum arg)
{
LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
- WalSummarizerCtl->summarizer_pgprocno = INVALID_PGPROCNO;
+ WalSummarizerCtl->summarizer_pgprocno = INVALID_PROC_NUMBER;
LWLockRelease(WALSummarizerLock);
}
{
SendProcSignal(MyLogicalRepWorker->leader_pid,
PROCSIG_PARALLEL_APPLY_MESSAGE,
- InvalidBackendId);
+ INVALID_PROC_NUMBER);
dsm_detach((dsm_segment *) DatumGetPointer(arg));
}
pq_redirect_to_shm_mq(seg, error_mqh);
pq_set_parallel_leader(MyLogicalRepWorker->leader_pid,
- InvalidBackendId);
+ INVALID_PROC_NUMBER);
MyLogicalRepWorker->last_send_time = MyLogicalRepWorker->last_recv_time =
MyLogicalRepWorker->reply_time = 0;
if (MyBackendType == B_STARTUP)
(void) SendProcSignal(active_pid,
PROCSIG_RECOVERY_CONFLICT_LOGICALSLOT,
- InvalidBackendId);
+ INVALID_PROC_NUMBER);
else
(void) kill(active_pid, SIGTERM);
if (pid == 0)
continue;
- SendProcSignal(pid, PROCSIG_WALSND_INIT_STOPPING, InvalidBackendId);
+ SendProcSignal(pid, PROCSIG_WALSND_INIT_STOPPING, INVALID_PROC_NUMBER);
}
}
ClearBufferTag(&buf->tag);
pg_atomic_init_u32(&buf->state, 0);
- buf->wait_backend_pgprocno = INVALID_PGPROCNO;
+ buf->wait_backend_pgprocno = INVALID_PROC_NUMBER;
buf->buf_id = i;
* permanent = false for a RELPERSISTENCE_UNLOGGED relation. This function
* cannot be used for temporary relations (and making that work might be
* difficult, unless we only want to read temporary relations for our own
- * BackendId).
+ * ProcNumber).
*/
Buffer
ReadBufferWithoutRelcache(RelFileLocator rlocator, ForkNumber forkNum,
{
bool hit;
- SMgrRelation smgr = smgropen(rlocator, InvalidBackendId);
+ SMgrRelation smgr = smgropen(rlocator, INVALID_PROC_NUMBER);
return ReadBuffer_common(smgr, permanent ? RELPERSISTENCE_PERMANENT :
RELPERSISTENCE_UNLOGGED, forkNum, blockNum,
int32 loccount;
char *path;
char *result;
- BackendId backend;
+ ProcNumber backend;
uint32 buf_state;
Assert(BufferIsValid(buffer));
{
buf = GetLocalBufferDescriptor(-buffer - 1);
loccount = LocalRefCount[-buffer - 1];
- backend = MyBackendId;
+ backend = MyProcNumber;
}
else
{
buf = GetBufferDescriptor(buffer - 1);
loccount = GetPrivateRefCount(buffer);
- backend = InvalidBackendId;
+ backend = INVALID_PROC_NUMBER;
}
/* theoretically we should lock the bufhdr here */
/* Find smgr relation for buffer */
if (reln == NULL)
- reln = smgropen(BufTagGetRelFileLocator(&buf->tag), InvalidBackendId);
+ reln = smgropen(BufTagGetRelFileLocator(&buf->tag), INVALID_PROC_NUMBER);
TRACE_POSTGRESQL_BUFFER_FLUSH_START(BufTagGetForkNum(&buf->tag),
buf->tag.blockNum,
/* If it's a local relation, it's localbuf.c's problem. */
if (RelFileLocatorBackendIsTemp(rlocator))
{
- if (rlocator.backend == MyBackendId)
+ if (rlocator.backend == MyProcNumber)
{
for (j = 0; j < nforks; j++)
DropRelationLocalBuffers(rlocator.locator, forkNum[j],
{
if (RelFileLocatorBackendIsTemp(smgr_reln[i]->smgr_rlocator))
{
- if (smgr_reln[i]->smgr_rlocator.backend == MyBackendId)
+ if (smgr_reln[i]->smgr_rlocator.backend == MyProcNumber)
DropRelationAllLocalBuffers(smgr_reln[i]->smgr_rlocator.locator);
}
else
"blockNum=%u, flags=0x%x, refcount=%u %d)",
i, buf->freeNext,
relpathbackend(BufTagGetRelFileLocator(&buf->tag),
- InvalidBackendId, BufTagGetForkNum(&buf->tag)),
+ INVALID_PROC_NUMBER, BufTagGetForkNum(&buf->tag)),
buf->tag.blockNum, buf->flags,
buf->refcount, GetPrivateRefCount(b));
}
use_wal = XLogIsNeeded() && (permanent || forkNum == INIT_FORKNUM);
/* Get number of blocks in the source relation. */
- nblocks = smgrnblocks(smgropen(srclocator, InvalidBackendId),
+ nblocks = smgrnblocks(smgropen(srclocator, INVALID_PROC_NUMBER),
forkNum);
/* Nothing to copy; just return. */
* relation before starting to copy block by block.
*/
memset(buf.data, 0, BLCKSZ);
- smgrextend(smgropen(dstlocator, InvalidBackendId), forkNum, nblocks - 1,
+ smgrextend(smgropen(dstlocator, INVALID_PROC_NUMBER), forkNum, nblocks - 1,
buf.data, true);
/* This is a bulk operation, so use buffer access strategies. */
relpersistence = permanent ?
RELPERSISTENCE_PERMANENT : RELPERSISTENCE_UNLOGGED;
- src_rel = smgropen(src_rlocator, InvalidBackendId);
- dst_rel = smgropen(dst_rlocator, InvalidBackendId);
+ src_rel = smgropen(src_rlocator, INVALID_PROC_NUMBER);
+ dst_rel = smgropen(dst_rlocator, INVALID_PROC_NUMBER);
/*
* Create and copy all forks of the relation. During create database we
if (bufHdr != NULL)
{
char *path = relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
- MyBackendId,
+ MyProcNumber,
BufTagGetForkNum(&bufHdr->tag));
errcontext("writing block %u of relation %s",
i += ahead;
/* and finally tell the kernel to write the data to storage */
- reln = smgropen(currlocator, InvalidBackendId);
+ reln = smgropen(currlocator, INVALID_PROC_NUMBER);
smgrwriteback(reln, BufTagGetForkNum(&tag), tag.blockNum, nblocks);
}
Page localpage = (char *) LocalBufHdrGetBlock(bufHdr);
/* Find smgr relation for buffer */
- oreln = smgropen(BufTagGetRelFileLocator(&bufHdr->tag), MyBackendId);
+ oreln = smgropen(BufTagGetRelFileLocator(&bufHdr->tag), MyProcNumber);
PageSetChecksumInplace(localpage, bufHdr->tag.blockNum);
elog(ERROR, "block %u of %s is still referenced (local %u)",
bufHdr->tag.blockNum,
relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
- MyBackendId,
+ MyProcNumber,
BufTagGetForkNum(&bufHdr->tag)),
LocalRefCount[i]);
elog(ERROR, "block %u of %s is still referenced (local %u)",
bufHdr->tag.blockNum,
relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
- MyBackendId,
+ MyProcNumber,
BufTagGetForkNum(&bufHdr->tag)),
LocalRefCount[i]);
/* Remove entry from hashtable */
* If the list was not empty, the leader will clear our XID. It is
* impossible to have followers without a leader because the first process
* that has added itself to the list will always have nextidx as
- * INVALID_PGPROCNO.
+ * INVALID_PROC_NUMBER.
*/
- if (nextidx != INVALID_PGPROCNO)
+ if (nextidx != INVALID_PROC_NUMBER)
{
int extraWaits = 0;
}
pgstat_report_wait_end();
- Assert(pg_atomic_read_u32(&proc->procArrayGroupNext) == INVALID_PGPROCNO);
+ Assert(pg_atomic_read_u32(&proc->procArrayGroupNext) == INVALID_PROC_NUMBER);
/* Fix semaphore count for any absorbed wakeups */
while (extraWaits-- > 0)
* to pop elements one at a time could lead to an ABA problem.
*/
nextidx = pg_atomic_exchange_u32(&procglobal->procArrayGroupFirst,
- INVALID_PGPROCNO);
+ INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
wakeidx = nextidx;
/* Walk the list and clear all XIDs. */
- while (nextidx != INVALID_PGPROCNO)
+ while (nextidx != INVALID_PROC_NUMBER)
{
PGPROC *nextproc = &allProcs[nextidx];
* up are probably much slower than the simple memory writes we did while
* holding the lock.
*/
- while (wakeidx != INVALID_PGPROCNO)
+ while (wakeidx != INVALID_PROC_NUMBER)
{
PGPROC *nextproc = &allProcs[wakeidx];
wakeidx = pg_atomic_read_u32(&nextproc->procArrayGroupNext);
- pg_atomic_write_u32(&nextproc->procArrayGroupNext, INVALID_PGPROCNO);
+ pg_atomic_write_u32(&nextproc->procArrayGroupNext, INVALID_PROC_NUMBER);
/* ensure all previous writes are visible before follower continues. */
pg_write_barrier();
/*
* Find the PGPROC entry of the source transaction. (This could use
- * GetPGProcByBackendId(), unless it's a prepared xact. But this isn't
+ * GetPGProcByNumber(), unless it's a prepared xact. But this isn't
* performance critical.)
*/
for (index = 0; index < arrayP->numProcs; index++)
continue;
/* We are only interested in the specific virtual transaction. */
- if (proc->vxid.backendId != sourcevxid->backendId)
+ if (proc->vxid.procNumber != sourcevxid->procNumber)
continue;
if (proc->vxid.lxid != sourcevxid->localTransactionId)
continue;
}
/*
- * BackendIdGetProc -- get a backend's PGPROC given its backend ID
+ * ProcNumberGetProc -- get a backend's PGPROC given its proc number
*
* The result may be out of date arbitrarily quickly, so the caller
* must be careful about how this information is used. NULL is
* returned if the backend is not active.
*/
PGPROC *
-BackendIdGetProc(int backendID)
+ProcNumberGetProc(ProcNumber procNumber)
{
PGPROC *result;
- if (backendID < 1 || backendID > ProcGlobal->allProcCount)
+ if (procNumber < 0 || procNumber >= ProcGlobal->allProcCount)
return NULL;
- result = GetPGProcByBackendId(backendID);
+ result = GetPGProcByNumber(procNumber);
if (result->pid == 0)
return NULL;
}
/*
- * BackendIdGetTransactionIds -- get a backend's transaction status
+ * ProcNumberGetTransactionIds -- get a backend's transaction status
*
* Get the xid, xmin, nsubxid and overflow status of the backend. The
* result may be out of date arbitrarily quickly, so the caller must be
* careful about how this information is used.
*/
void
-BackendIdGetTransactionIds(int backendID, TransactionId *xid,
- TransactionId *xmin, int *nsubxid, bool *overflowed)
+ProcNumberGetTransactionIds(ProcNumber procNumber, TransactionId *xid,
+ TransactionId *xmin, int *nsubxid, bool *overflowed)
{
PGPROC *proc;
*nsubxid = 0;
*overflowed = false;
- if (backendID < 1 || backendID > ProcGlobal->allProcCount)
+ if (procNumber < 0 || procNumber >= ProcGlobal->allProcCount)
return;
- proc = GetPGProcByBackendId(backendID);
+ proc = GetPGProcByNumber(procNumber);
/* Need to lock out additions/removals of backends */
LWLockAcquire(ProcArrayLock, LW_SHARED);
LWLockRelease(ProcArrayLock);
/* add the terminator */
- vxids[count].backendId = InvalidBackendId;
+ vxids[count].procNumber = INVALID_PROC_NUMBER;
vxids[count].localTransactionId = InvalidLocalTransactionId;
return vxids;
GET_VXID_FROM_PGPROC(procvxid, *proc);
- if (procvxid.backendId == vxid.backendId &&
+ if (procvxid.procNumber == vxid.procNumber &&
procvxid.localTransactionId == vxid.localTransactionId)
{
proc->recoveryConflictPending = conflictPending;
* Kill the pid if it's still here. If not, that's what we
* wanted so ignore any errors.
*/
- (void) SendProcSignal(pid, sigmode, vxid.backendId);
+ (void) SendProcSignal(pid, sigmode, vxid.procNumber);
}
break;
}
* Kill the pid if it's still here. If not, that's what we
* wanted so ignore any errors.
*/
- (void) SendProcSignal(pid, sigmode, procvxid.backendId);
+ (void) SendProcSignal(pid, sigmode, procvxid.procNumber);
}
}
}
* observe it only once.)
*
* Each process that wants to receive signals registers its process ID
- * in the ProcSignalSlots array. The array is indexed by backend ID to make
+ * in the ProcSignalSlots array. The array is indexed by ProcNumber to make
* slot allocation simple, and to avoid having to search the array when you
- * know the backend ID of the process you're signaling. (We do support
- * signaling without backend ID, but it's a bit less efficient.)
+ * know the ProcNumber of the process you're signaling. (We do support
+ * signaling without ProcNumber, but it's a bit less efficient.)
*
* The flags are actually declared as "volatile sig_atomic_t" for maximum
* portability. This should ensure that loads and stores of the flag
} ProcSignalHeader;
/*
- * We reserve a slot for each possible BackendId, plus one for each
+ * We reserve a slot for each possible ProcNumber, plus one for each
* possible auxiliary process type. (This scheme assumes there is not
* more than one of any auxiliary process type at a time.)
*/
ProcSignalSlot *slot;
uint64 barrier_generation;
- if (MyBackendId <= 0)
- elog(ERROR, "MyBackendId not set");
- if (MyBackendId > NumProcSignalSlots)
- elog(ERROR, "unexpected MyBackendId %d in ProcSignalInit (max %d)", MyBackendId, NumProcSignalSlots);
- slot = &ProcSignal->psh_slot[MyBackendId - 1];
+ if (MyProcNumber < 0)
+ elog(ERROR, "MyProcNumber not set");
+ if (MyProcNumber >= NumProcSignalSlots)
+ elog(ERROR, "unexpected MyProcNumber %d in ProcSignalInit (max %d)", MyProcNumber, NumProcSignalSlots);
+ slot = &ProcSignal->psh_slot[MyProcNumber];
/* sanity check */
if (slot->pss_pid != 0)
elog(LOG, "process %d taking over ProcSignal slot %d, but it's not empty",
- MyProcPid, MyBackendId - 1);
+ MyProcPid, MyProcNumber);
/* Clear out any leftover signal reasons */
MemSet(slot->pss_signalFlags, 0, NUM_PROCSIGNALS * sizeof(sig_atomic_t));
* won't try to access it after it's no longer ours (and perhaps even
* after we've unmapped the shared memory segment).
*/
+ Assert(MyProcSignalSlot != NULL);
MyProcSignalSlot = NULL;
/* sanity check */
* SendProcSignal
* Send a signal to a Postgres process
*
- * Providing backendId is optional, but it will speed up the operation.
+ * Providing procNumber is optional, but it will speed up the operation.
*
* On success (a signal was sent), zero is returned.
* On error, -1 is returned, and errno is set (typically to ESRCH or EPERM).
* Not to be confused with ProcSendSignal
*/
int
-SendProcSignal(pid_t pid, ProcSignalReason reason, BackendId backendId)
+SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
volatile ProcSignalSlot *slot;
- if (backendId != InvalidBackendId)
+ if (procNumber != INVALID_PROC_NUMBER)
{
- slot = &ProcSignal->psh_slot[backendId - 1];
+ slot = &ProcSignal->psh_slot[procNumber];
/*
* Note: Since there's no locking, it's possible that the target
else
{
/*
- * BackendId not provided, so search the array using pid. We search
+ * Pronumber not provided, so search the array using pid. We search
* the array back to front so as to reduce search overhead. Passing
- * InvalidBackendId means that the target is most likely an auxiliary
- * process, which will have a slot near the end of the array.
+ * INVALID_PROC_NUMBER means that the target is most likely an
+ * auxiliary process, which will have a slot near the end of the
+ * array.
*/
int i;
#include "access/transam.h"
#include "miscadmin.h"
-#include "storage/backendid.h"
#include "storage/ipc.h"
#include "storage/proc.h"
+#include "storage/procnumber.h"
#include "storage/procsignal.h"
#include "storage/shmem.h"
#include "storage/sinvaladt.h"
/*
* Next LocalTransactionId to use for each idle backend slot. We keep
- * this here because it is indexed by BackendId and it is convenient to
- * copy the value to and from local memory when MyBackendId is set. It's
+ * this here because it is indexed by ProcNumber and it is convenient to
+ * copy the value to and from local memory when MyProcNumber is set. It's
* meaningless in an active ProcState entry.
*/
LocalTransactionId nextLXID;
} SISeg;
/*
- * We reserve a slot for each possible BackendId, plus one for each
+ * We reserve a slot for each possible ProcNumber, plus one for each
* possible auxiliary process type. (This scheme assumes there is not
* more than one of any auxiliary process type at a time.)
*/
ProcState *stateP;
pid_t oldPid;
SISeg *segP = shmInvalBuffer;
- int pgprocno;
- if (MyBackendId <= 0)
- elog(ERROR, "MyBackendId not set");
- if (MyBackendId > NumProcStateSlots)
- elog(PANIC, "unexpected MyBackendId %d in SharedInvalBackendInit (max %d)",
- MyBackendId, NumProcStateSlots);
- pgprocno = MyBackendId - 1;
- stateP = &segP->procState[pgprocno];
+ if (MyProcNumber < 0)
+ elog(ERROR, "MyProcNumber not set");
+ if (MyProcNumber >= NumProcStateSlots)
+ elog(PANIC, "unexpected MyProcNumber %d in SharedInvalBackendInit (max %d)",
+ MyProcNumber, NumProcStateSlots);
+ stateP = &segP->procState[MyProcNumber];
/*
* This can run in parallel with read operations, but not with write
{
LWLockRelease(SInvalWriteLock);
elog(ERROR, "sinval slot for backend %d is already in use by process %d",
- MyBackendId, (int) oldPid);
+ MyProcNumber, (int) oldPid);
}
- shmInvalBuffer->pgprocnos[shmInvalBuffer->numProcs++] = pgprocno;
+ shmInvalBuffer->pgprocnos[shmInvalBuffer->numProcs++] = MyProcNumber;
/* Fetch next local transaction ID into local memory */
nextLocalTransactionId = stateP->nextLXID;
{
SISeg *segP = (SISeg *) DatumGetPointer(arg);
ProcState *stateP;
- int pgprocno = MyBackendId - 1;
int i;
Assert(PointerIsValid(segP));
LWLockAcquire(SInvalWriteLock, LW_EXCLUSIVE);
- stateP = &segP->procState[pgprocno];
+ stateP = &segP->procState[MyProcNumber];
- /* Update next local transaction ID for next holder of this backendID */
+ /* Update next local transaction ID for next holder of this proc number */
stateP->nextLXID = nextLocalTransactionId;
/* Mark myself inactive */
for (i = segP->numProcs - 1; i >= 0; i--)
{
- if (segP->pgprocnos[i] == pgprocno)
+ if (segP->pgprocnos[i] == MyProcNumber)
{
if (i != segP->numProcs - 1)
segP->pgprocnos[i] = segP->pgprocnos[segP->numProcs - 1];
int n;
segP = shmInvalBuffer;
- stateP = &segP->procState[MyBackendId - 1];
+ stateP = &segP->procState[MyProcNumber];
/*
* Before starting to take locks, do a quick, unlocked test to see whether
if (needSig)
{
pid_t his_pid = needSig->procPid;
- BackendId his_backendId = (needSig - &segP->procState[0]) + 1;
+ ProcNumber his_procNumber = (needSig - &segP->procState[0]);
needSig->signaled = true;
LWLockRelease(SInvalReadLock);
LWLockRelease(SInvalWriteLock);
elog(DEBUG4, "sending sinval catchup signal to PID %d", (int) his_pid);
- SendProcSignal(his_pid, PROCSIG_CATCHUP_INTERRUPT, his_backendId);
+ SendProcSignal(his_pid, PROCSIG_CATCHUP_INTERRUPT, his_procNumber);
if (callerHasWriteLock)
LWLockAcquire(SInvalWriteLock, LW_EXCLUSIVE);
}
* We split VirtualTransactionIds into two parts so that it is possible
* to allocate a new one without any contention for shared memory, except
* for a bit of additional overhead during backend startup/shutdown.
- * The high-order part of a VirtualTransactionId is a BackendId, and the
+ * The high-order part of a VirtualTransactionId is a ProcNumber, and the
* low-order part is a LocalTransactionId, which we assign from a local
* counter. To avoid the risk of a VirtualTransactionId being reused
- * within a short interval, successive procs occupying the same backend ID
- * slot should use a consecutive sequence of local IDs, which is implemented
+ * within a short interval, successive procs occupying the same PGPROC slot
+ * should use a consecutive sequence of local IDs, which is implemented
* by copying nextLocalTransactionId as seen above.
*/
LocalTransactionId
* are held by vxids and row level locks are held by xids. All queries
* hold AccessShareLocks so never block while we write or lock new rows.
*/
- MyProc->vxid.backendId = MyBackendId;
- vxid.backendId = MyBackendId;
+ MyProc->vxid.procNumber = MyProcNumber;
+ vxid.procNumber = MyProcNumber;
vxid.localTransactionId = GetNextLocalTransactionId();
VirtualXactLockTableInsert(vxid);
vxids = wait_list;
while (VirtualTransactionIdIsValid(*vxids))
{
- PGPROC *proc = BackendIdGetProc(vxids->backendId);
+ PGPROC *proc = ProcNumberGetProc(vxids->procNumber);
/* proc can be NULL if the target backend is not active */
if (proc)
/* If requested, publish who we're going to wait for. */
if (progress)
{
- PGPROC *holder = BackendIdGetProc(lockholders->backendId);
+ PGPROC *holder = ProcNumberGetProc(lockholders->procNumber);
if (holder)
pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID,
* on this lockable object.
*/
LWLockRelease(partitionLock);
- vxids[count].backendId = InvalidBackendId;
+ vxids[count].procNumber = INVALID_PROC_NUMBER;
vxids[count].localTransactionId = InvalidLocalTransactionId;
if (countp)
*countp = count;
if (count > MaxBackends + max_prepared_xacts) /* should never happen */
elog(PANIC, "too many conflicting locks found");
- vxids[count].backendId = InvalidBackendId;
+ vxids[count].procNumber = INVALID_PROC_NUMBER;
vxids[count].localTransactionId = InvalidLocalTransactionId;
if (countp)
*countp = count;
proc->fpRelId[f]);
instance->holdMask = lockbits << FAST_PATH_LOCKNUMBER_OFFSET;
instance->waitLockMode = NoLock;
- instance->vxid.backendId = proc->vxid.backendId;
+ instance->vxid.procNumber = proc->vxid.procNumber;
instance->vxid.localTransactionId = proc->vxid.lxid;
instance->pid = proc->pid;
instance->leaderPid = proc->pid;
repalloc(data->locks, sizeof(LockInstanceData) * els);
}
- vxid.backendId = proc->vxid.backendId;
+ vxid.procNumber = proc->vxid.procNumber;
vxid.localTransactionId = proc->fpLocalTransactionId;
instance = &data->locks[el];
SET_LOCKTAG_VIRTUALTRANSACTION(instance->locktag, vxid);
instance->holdMask = LOCKBIT_ON(ExclusiveLock);
instance->waitLockMode = NoLock;
- instance->vxid.backendId = proc->vxid.backendId;
+ instance->vxid.procNumber = proc->vxid.procNumber;
instance->vxid.localTransactionId = proc->vxid.lxid;
instance->pid = proc->pid;
instance->leaderPid = proc->pid;
instance->waitLockMode = proc->waitLockMode;
else
instance->waitLockMode = NoLock;
- instance->vxid.backendId = proc->vxid.backendId;
+ instance->vxid.procNumber = proc->vxid.procNumber;
instance->vxid.localTransactionId = proc->vxid.lxid;
instance->pid = proc->pid;
instance->leaderPid = proclock->groupLeader->pid;
instance->waitLockMode = proc->waitLockMode;
else
instance->waitLockMode = NoLock;
- instance->vxid.backendId = proc->vxid.backendId;
+ instance->vxid.procNumber = proc->vxid.procNumber;
instance->vxid.localTransactionId = proc->vxid.lxid;
instance->pid = proc->pid;
instance->leaderPid = proclock->groupLeader->pid;
LWLockAcquire(&MyProc->fpInfoLock, LW_EXCLUSIVE);
- Assert(MyProc->vxid.backendId == vxid.backendId);
+ Assert(MyProc->vxid.procNumber == vxid.procNumber);
Assert(MyProc->fpLocalTransactionId == InvalidLocalTransactionId);
Assert(MyProc->fpVXIDLock == false);
bool fastpath;
LocalTransactionId lxid;
- Assert(MyProc->vxid.backendId != InvalidBackendId);
+ Assert(MyProc->vxid.procNumber != INVALID_PROC_NUMBER);
/*
* Clean up shared memory state.
VirtualTransactionId vxid;
LOCKTAG locktag;
- vxid.backendId = MyBackendId;
+ vxid.procNumber = MyProcNumber;
vxid.localTransactionId = lxid;
SET_LOCKTAG_VIRTUALTRANSACTION(locktag, vxid);
* relevant lxid is no longer running here, that's enough to prove that
* it's no longer running anywhere.
*/
- proc = BackendIdGetProc(vxid.backendId);
+ proc = ProcNumberGetProc(vxid.procNumber);
if (proc == NULL)
return XactLockForVirtualXact(vxid, InvalidTransactionId, wait);
/*
- * We must acquire this lock before checking the backendId and lxid
+ * We must acquire this lock before checking the procNumber and lxid
* against the ones we're waiting for. The target backend will only set
* or clear lxid while holding this lock.
*/
LWLockAcquire(&proc->fpInfoLock, LW_EXCLUSIVE);
- if (proc->vxid.backendId != vxid.backendId
+ if (proc->vxid.procNumber != vxid.procNumber
|| proc->fpLocalTransactionId != vxid.localTransactionId)
{
/* VXID ended */
PredXact->OldCommittedSxact->xmin = InvalidTransactionId;
PredXact->OldCommittedSxact->flags = SXACT_FLAG_COMMITTED;
PredXact->OldCommittedSxact->pid = 0;
- PredXact->OldCommittedSxact->pgprocno = INVALID_PGPROCNO;
+ PredXact->OldCommittedSxact->pgprocno = INVALID_PROC_NUMBER;
}
/* This never changes, so let's keep a local copy. */
OldCommittedSxact = PredXact->OldCommittedSxact;
Assert(SxactIsPrepared(MySerializableXact));
MySerializableXact->pid = 0;
- MySerializableXact->pgprocno = INVALID_PGPROCNO;
+ MySerializableXact->pgprocno = INVALID_PROC_NUMBER;
hash_destroy(LocalPredicateLockHash);
LocalPredicateLockHash = NULL;
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
- /* vxid for a prepared xact is InvalidBackendId/xid; no pid */
- sxact->vxid.backendId = InvalidBackendId;
+ /* vxid for a prepared xact is INVALID_PROC_NUMBER/xid; no pid */
+ sxact->vxid.procNumber = INVALID_PROC_NUMBER;
sxact->vxid.localTransactionId = (LocalTransactionId) xid;
sxact->pid = 0;
- sxact->pgprocno = INVALID_PGPROCNO;
+ sxact->pgprocno = INVALID_PROC_NUMBER;
/* a prepared xact hasn't committed yet */
sxact->prepareSeqNo = RecoverySerCommitSeqNo;
/* Pointer to this process's PGPROC struct, if any */
PGPROC *MyProc = NULL;
-int MyProcNumber = INVALID_PGPROCNO;
/*
* This spinlock protects the freelist of recycled PGPROC structures.
ProcGlobal->startupBufferPinWaitBufId = -1;
ProcGlobal->walwriterLatch = NULL;
ProcGlobal->checkpointerLatch = NULL;
- pg_atomic_init_u32(&ProcGlobal->procArrayGroupFirst, INVALID_PGPROCNO);
- pg_atomic_init_u32(&ProcGlobal->clogGroupFirst, INVALID_PGPROCNO);
+ pg_atomic_init_u32(&ProcGlobal->procArrayGroupFirst, INVALID_PROC_NUMBER);
+ pg_atomic_init_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER);
/*
* Create and initialize all the PGPROC structures we'll need. There are
* Initialize the atomic variables, otherwise, it won't be safe to
* access them for backends that aren't currently in use.
*/
- pg_atomic_init_u32(&(proc->procArrayGroupNext), INVALID_PGPROCNO);
- pg_atomic_init_u32(&(proc->clogGroupNext), INVALID_PGPROCNO);
+ pg_atomic_init_u32(&(proc->procArrayGroupNext), INVALID_PROC_NUMBER);
+ pg_atomic_init_u32(&(proc->clogGroupNext), INVALID_PROC_NUMBER);
pg_atomic_init_u64(&(proc->waitStart), 0);
}
errmsg("sorry, too many clients already")));
}
MyProcNumber = GetNumberFromPGProc(MyProc);
- MyBackendId = GetBackendIdFromPGProc(MyProc);
/*
* Cross-check that the PGPROC is of the type we expect; if this were not
MyProc->xid = InvalidTransactionId;
MyProc->xmin = InvalidTransactionId;
MyProc->pid = MyProcPid;
- MyProc->vxid.backendId = MyBackendId;
+ MyProc->vxid.procNumber = MyProcNumber;
MyProc->vxid.lxid = InvalidLocalTransactionId;
/* databaseId and roleId will be filled in later */
MyProc->databaseId = InvalidOid;
/* Initialize fields for group XID clearing. */
MyProc->procArrayGroupMember = false;
MyProc->procArrayGroupMemberXid = InvalidTransactionId;
- Assert(pg_atomic_read_u32(&MyProc->procArrayGroupNext) == INVALID_PGPROCNO);
+ Assert(pg_atomic_read_u32(&MyProc->procArrayGroupNext) == INVALID_PROC_NUMBER);
/* Check that group locking fields are in a proper initial state. */
Assert(MyProc->lockGroupLeader == NULL);
MyProc->clogGroupMemberXidStatus = TRANSACTION_STATUS_IN_PROGRESS;
MyProc->clogGroupMemberPage = -1;
MyProc->clogGroupMemberLsn = InvalidXLogRecPtr;
- Assert(pg_atomic_read_u32(&MyProc->clogGroupNext) == INVALID_PGPROCNO);
+ Assert(pg_atomic_read_u32(&MyProc->clogGroupNext) == INVALID_PROC_NUMBER);
/*
* Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
MyProc = auxproc;
MyProcNumber = GetNumberFromPGProc(MyProc);
- MyBackendId = GetBackendIdFromPGProc(MyProc);
/*
* Initialize all fields of MyProc, except for those previously
MyProc->fpLocalTransactionId = InvalidLocalTransactionId;
MyProc->xid = InvalidTransactionId;
MyProc->xmin = InvalidTransactionId;
- MyProc->vxid.backendId = InvalidBackendId;
+ MyProc->vxid.procNumber = INVALID_PROC_NUMBER;
MyProc->vxid.lxid = InvalidLocalTransactionId;
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
proc = MyProc;
MyProc = NULL;
- MyProcNumber = INVALID_PGPROCNO;
- MyBackendId = InvalidBackendId;
+ MyProcNumber = INVALID_PROC_NUMBER;
DisownLatch(&proc->procLatch);
/* Mark the proc no longer in use */
proc->pid = 0;
- proc->vxid.backendId = InvalidBackendId;
+ proc->vxid.procNumber = INVALID_PROC_NUMBER;
proc->vxid.lxid = InvalidTransactionId;
procgloballist = proc->procgloballist;
proc = MyProc;
MyProc = NULL;
- MyProcNumber = INVALID_PGPROCNO;
- MyBackendId = InvalidBackendId;
+ MyProcNumber = INVALID_PROC_NUMBER;
DisownLatch(&proc->procLatch);
SpinLockAcquire(ProcStructLock);
/* Mark auxiliary proc no longer in use */
proc->pid = 0;
- proc->vxid.backendId = InvalidBackendId;
+ proc->vxid.procNumber = INVALID_PROC_NUMBER;
proc->vxid.lxid = InvalidTransactionId;
/* Update shared estimate of spins_per_delay */
}
/*
- * ProcSendSignal - set the latch of a backend identified by pgprocno
+ * ProcSendSignal - set the latch of a backend identified by ProcNumber
*/
void
-ProcSendSignal(int pgprocno)
+ProcSendSignal(ProcNumber procNumber)
{
- if (pgprocno < 0 || pgprocno >= ProcGlobal->allProcCount)
- elog(ERROR, "pgprocno out of range");
+ if (procNumber < 0 || procNumber >= ProcGlobal->allProcCount)
+ elog(ERROR, "procNumber out of range");
- SetLatch(&ProcGlobal->allProcs[pgprocno].procLatch);
+ SetLatch(&ProcGlobal->allProcs[procNumber].procLatch);
}
/*
srels = palloc(sizeof(SMgrRelation) * ndelrels);
for (i = 0; i < ndelrels; i++)
{
- SMgrRelation srel = smgropen(delrels[i], InvalidBackendId);
+ SMgrRelation srel = smgropen(delrels[i], INVALID_PROC_NUMBER);
if (isRedo)
{
int
mdsyncfiletag(const FileTag *ftag, char *path)
{
- SMgrRelation reln = smgropen(ftag->rlocator, InvalidBackendId);
+ SMgrRelation reln = smgropen(ftag->rlocator, INVALID_PROC_NUMBER);
File file;
instr_time io_start;
bool need_to_close;
* This does not attempt to actually open the underlying files.
*/
SMgrRelation
-smgropen(RelFileLocator rlocator, BackendId backend)
+smgropen(RelFileLocator rlocator, ProcNumber backend)
{
RelFileLocatorBackend brlocator;
SMgrRelation reln;
/*
* Initialize pgstats backend activity state, and set up our on-proc-exit
- * hook. Called from InitPostgres and AuxiliaryProcessMain. MyBackendId must
+ * hook. Called from InitPostgres and AuxiliaryProcessMain. MyProcNumber must
* be set, but we must not have started any transaction yet (since the exit
* hook must run after the last transaction exit).
*
pgstat_beinit(void)
{
/* Initialize MyBEEntry */
- Assert(MyBackendId != InvalidBackendId);
- Assert(MyBackendId >= 1 && MyBackendId <= NumBackendStatSlots);
- MyBEEntry = &BackendStatusArray[MyBackendId - 1];
+ Assert(MyProcNumber != INVALID_PROC_NUMBER);
+ Assert(MyProcNumber >= 0 && MyProcNumber < NumBackendStatSlots);
+ MyBEEntry = &BackendStatusArray[MyProcNumber];
/* Set up a process-exit hook to clean up */
on_shmem_exit(pgstat_beshutdown_hook, 0);
#ifdef ENABLE_GSS
PgBackendGSSStatus *localgssstatus;
#endif
- int i;
+ ProcNumber procNumber;
if (localBackendStatusTable)
return; /* already done */
beentry = BackendStatusArray;
localentry = localtable;
- for (i = 1; i <= NumBackendStatSlots; i++)
+ for (procNumber = 0; procNumber < NumBackendStatSlots; procNumber++)
{
/*
* Follow the protocol of retrying if st_changecount changes while we
if (localentry->backendStatus.st_procpid > 0)
{
/*
- * The BackendStatusArray index is exactly the BackendId of the
+ * The BackendStatusArray index is exactly the ProcNumber of the
* source backend. Note that this means localBackendStatusTable
- * is in order by backend_id. pgstat_get_beentry_by_backend_id()
+ * is in order by proc_number. pgstat_get_beentry_by_backend_id()
* depends on that.
*/
- localentry->backend_id = i;
- BackendIdGetTransactionIds(i,
- &localentry->backend_xid,
- &localentry->backend_xmin,
- &localentry->backend_subxact_count,
- &localentry->backend_subxact_overflowed);
+ localentry->proc_number = procNumber;
+ ProcNumberGetTransactionIds(procNumber,
+ &localentry->backend_xid,
+ &localentry->backend_xmin,
+ &localentry->backend_subxact_count,
+ &localentry->backend_subxact_overflowed);
localentry++;
localappname += NAMEDATALEN;
* cmp_lbestatus
*
* Comparison function for bsearch() on an array of LocalPgBackendStatus.
- * The backend_id field is used to compare the arguments.
+ * The proc_number field is used to compare the arguments.
* ----------
*/
static int
const LocalPgBackendStatus *lbestatus1 = (const LocalPgBackendStatus *) a;
const LocalPgBackendStatus *lbestatus2 = (const LocalPgBackendStatus *) b;
- return lbestatus1->backend_id - lbestatus2->backend_id;
+ return lbestatus1->proc_number - lbestatus2->proc_number;
}
/* ----------
- * pgstat_get_beentry_by_backend_id() -
+ * pgstat_get_beentry_by_proc_number() -
*
* Support function for the SQL-callable pgstat* functions. Returns
* our local copy of the current-activity entry for one backend,
* or NULL if the given beid doesn't identify any known session.
*
- * The beid argument is the BackendId of the desired session
+ * The argument is the ProcNumber of the desired session
* (note that this is unlike pgstat_get_local_beentry_by_index()).
*
* NB: caller is responsible for a check if the user is permitted to see
* ----------
*/
PgBackendStatus *
-pgstat_get_beentry_by_backend_id(BackendId beid)
+pgstat_get_beentry_by_proc_number(ProcNumber procNumber)
{
- LocalPgBackendStatus *ret = pgstat_get_local_beentry_by_backend_id(beid);
+ LocalPgBackendStatus *ret = pgstat_get_local_beentry_by_proc_number(procNumber);
if (ret)
return &ret->backendStatus;
/* ----------
- * pgstat_get_local_beentry_by_backend_id() -
+ * pgstat_get_local_beentry_by_proc_number() -
*
- * Like pgstat_get_beentry_by_backend_id() but with locally computed additions
+ * Like pgstat_get_beentry_by_proc_number() but with locally computed additions
* (like xid and xmin values of the backend)
*
- * The beid argument is the BackendId of the desired session
+ * The argument is the ProcNumber of the desired session
* (note that this is unlike pgstat_get_local_beentry_by_index()).
*
* NB: caller is responsible for checking if the user is permitted to see this
* ----------
*/
LocalPgBackendStatus *
-pgstat_get_local_beentry_by_backend_id(BackendId beid)
+pgstat_get_local_beentry_by_proc_number(ProcNumber procNumber)
{
LocalPgBackendStatus key;
* Since the localBackendStatusTable is in order by backend_id, we can use
* bsearch() to search it efficiently.
*/
- key.backend_id = beid;
+ key.proc_number = procNumber;
return bsearch(&key, localBackendStatusTable, localNumBackends,
sizeof(LocalPgBackendStatus), cmp_lbestatus);
}
* is no check here or at the call sites for that.
*/
static int64
-calculate_relation_size(RelFileLocator *rfn, BackendId backend, ForkNumber forknum)
+calculate_relation_size(RelFileLocator *rfn, ProcNumber backend, ForkNumber forknum)
{
int64 totalsize = 0;
char *relationpath;
HeapTuple tuple;
Form_pg_class relform;
RelFileLocator rlocator;
- BackendId backend;
+ ProcNumber backend;
char *path;
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
{
case RELPERSISTENCE_UNLOGGED:
case RELPERSISTENCE_PERMANENT:
- backend = InvalidBackendId;
+ backend = INVALID_PROC_NUMBER;
break;
case RELPERSISTENCE_TEMP:
if (isTempOrTempToastNamespace(relform->relnamespace))
- backend = BackendIdForTempRelations();
+ backend = ProcNumberForTempRelations();
else
{
/* Do it the hard way. */
- backend = GetTempNamespaceBackendId(relform->relnamespace);
- Assert(backend != InvalidBackendId);
+ backend = GetTempNamespaceProcNumber(relform->relnamespace);
+ Assert(backend != INVALID_PROC_NUMBER);
}
break;
default:
elog(ERROR, "invalid relpersistence: %c", relform->relpersistence);
- backend = InvalidBackendId; /* placate compiler */
+ backend = INVALID_PROC_NUMBER; /* placate compiler */
break;
}
* This is currently only used in pg_lock_status, so we put it here.
*/
static Datum
-VXIDGetDatum(BackendId bid, LocalTransactionId lxid)
+VXIDGetDatum(ProcNumber procNumber, LocalTransactionId lxid)
{
/*
- * The representation is "<bid>/<lxid>", decimal and unsigned decimal
- * respectively. Note that elog.c also knows how to format a vxid.
+ * The representation is "<procNumber>/<lxid>", decimal and unsigned
+ * decimal respectively. Note that elog.c also knows how to format a
+ * vxid.
*/
char vxidstr[32];
- snprintf(vxidstr, sizeof(vxidstr), "%d/%u", bid, lxid);
+ snprintf(vxidstr, sizeof(vxidstr), "%d/%u", procNumber, lxid);
return CStringGetTextDatum(vxidstr);
}
break;
}
- values[10] = VXIDGetDatum(instance->vxid.backendId, instance->vxid.localTransactionId);
+ values[10] = VXIDGetDatum(instance->vxid.procNumber, instance->vxid.localTransactionId);
if (instance->pid != 0)
values[11] = Int32GetDatum(instance->pid);
else
nulls[9] = true; /* objsubid */
/* lock holder */
- values[10] = VXIDGetDatum(xact->vxid.backendId,
+ values[10] = VXIDGetDatum(xact->vxid.procNumber,
xact->vxid.localTransactionId);
if (xact->pid != 0)
values[11] = Int32GetDatum(xact->pid);
{
int pid = PG_GETARG_INT32(0);
PGPROC *proc;
- BackendId backendId = InvalidBackendId;
+ ProcNumber procNumber = INVALID_PROC_NUMBER;
/*
* See if the process with given pid is a backend or an auxiliary process.
PG_RETURN_BOOL(false);
}
- if (proc != NULL)
- backendId = GetBackendIdFromPGProc(proc);
- if (SendProcSignal(pid, PROCSIG_LOG_MEMORY_CONTEXT, backendId) < 0)
+ procNumber = GetNumberFromPGProc(proc);
+ if (SendProcSignal(pid, PROCSIG_LOG_MEMORY_CONTEXT, procNumber) < 0)
{
/* Again, just a warning to allow loops */
ereport(WARNING,
/* do when there is more left to send */
LocalPgBackendStatus *local_beentry = pgstat_get_local_beentry_by_index(fctx[0]);
- SRF_RETURN_NEXT(funcctx, Int32GetDatum(local_beentry->backend_id));
+ SRF_RETURN_NEXT(funcctx, Int32GetDatum(local_beentry->proc_number));
}
else
{
Datum
pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
{
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
- if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
PG_RETURN_NULL();
PG_RETURN_INT32(beentry->st_procpid);
Datum
pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
{
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
- if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
PG_RETURN_NULL();
PG_RETURN_OID(beentry->st_databaseid);
Datum
pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
{
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
- if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
PG_RETURN_NULL();
PG_RETURN_OID(beentry->st_userid);
TupleDesc tupdesc;
Datum values[PG_STAT_GET_SUBXACT_COLS] = {0};
bool nulls[PG_STAT_GET_SUBXACT_COLS] = {0};
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
LocalPgBackendStatus *local_beentry;
/* Initialise attributes information in the tuple descriptor */
BlessTupleDesc(tupdesc);
- if ((local_beentry = pgstat_get_local_beentry_by_backend_id(beid)) != NULL)
+ if ((local_beentry = pgstat_get_local_beentry_by_proc_number(procNumber)) != NULL)
{
/* Fill values and NULLs */
values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
Datum
pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
{
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
const char *activity;
char *clipped_activity;
text *ret;
- if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
activity = "<backend information not available>";
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
activity = "<insufficient privilege>";
Datum
pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
{
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
PGPROC *proc;
const char *wait_event_type = NULL;
- if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
wait_event_type = "<backend information not available>";
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
wait_event_type = "<insufficient privilege>";
Datum
pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
{
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
PGPROC *proc;
const char *wait_event = NULL;
- if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
wait_event = "<backend information not available>";
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
wait_event = "<insufficient privilege>";
Datum
pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
{
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
TimestampTz result;
PgBackendStatus *beentry;
- if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
Datum
pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
{
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
TimestampTz result;
PgBackendStatus *beentry;
- if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
Datum
pg_stat_get_backend_start(PG_FUNCTION_ARGS)
{
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
TimestampTz result;
PgBackendStatus *beentry;
- if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
Datum
pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
{
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
SockAddr zero_clientaddr;
char remote_host[NI_MAXHOST];
int ret;
- if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
Datum
pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
{
- int32 beid = PG_GETARG_INT32(0);
+ int32 procNumber = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
SockAddr zero_clientaddr;
char remote_port[NI_MAXSERV];
int ret;
- if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
* replaying WAL as well as when creating it.
*
* Note: In order to avoid bloating SharedInvalidationMessage, we store only
- * three bytes of the backend ID using what would otherwise be padding space.
- * Thus, the maximum possible backend ID is 2^23-1.
+ * three bytes of the ProcNumber using what would otherwise be padding space.
+ * Thus, the maximum possible ProcNumber is 2^23-1.
*/
void
CacheInvalidateSmgr(RelFileLocatorBackend rlocator)
{
case RELPERSISTENCE_UNLOGGED:
case RELPERSISTENCE_PERMANENT:
- relation->rd_backend = InvalidBackendId;
+ relation->rd_backend = INVALID_PROC_NUMBER;
relation->rd_islocaltemp = false;
break;
case RELPERSISTENCE_TEMP:
if (isTempOrTempToastNamespace(relation->rd_rel->relnamespace))
{
- relation->rd_backend = BackendIdForTempRelations();
+ relation->rd_backend = ProcNumberForTempRelations();
relation->rd_islocaltemp = true;
}
else
* If it's a temp table, but not one of ours, we have to use
* the slow, grotty method to figure out the owning backend.
*
- * Note: it's possible that rd_backend gets set to MyBackendId
- * here, in case we are looking at a pg_class entry left over
- * from a crashed backend that coincidentally had the same
- * BackendId we're using. We should *not* consider such a
- * table to be "ours"; this is why we need the separate
- * rd_islocaltemp flag. The pg_class entry will get flushed
- * if/when we clean out the corresponding temp table namespace
- * in preparation for using it.
+ * Note: it's possible that rd_backend gets set to
+ * MyProcNumber here, in case we are looking at a pg_class
+ * entry left over from a crashed backend that coincidentally
+ * had the same ProcNumber we're using. We should *not*
+ * consider such a table to be "ours"; this is why we need the
+ * separate rd_islocaltemp flag. The pg_class entry will get
+ * flushed if/when we clean out the corresponding temp table
+ * namespace in preparation for using it.
*/
relation->rd_backend =
- GetTempNamespaceBackendId(relation->rd_rel->relnamespace);
- Assert(relation->rd_backend != InvalidBackendId);
+ GetTempNamespaceProcNumber(relation->rd_rel->relnamespace);
+ Assert(relation->rd_backend != INVALID_PROC_NUMBER);
relation->rd_islocaltemp = false;
}
break;
relation->rd_newRelfilelocatorSubid = InvalidSubTransactionId;
relation->rd_firstRelfilelocatorSubid = InvalidSubTransactionId;
relation->rd_droppedSubid = InvalidSubTransactionId;
- relation->rd_backend = InvalidBackendId;
+ relation->rd_backend = INVALID_PROC_NUMBER;
relation->rd_islocaltemp = false;
/*
{
case RELPERSISTENCE_UNLOGGED:
case RELPERSISTENCE_PERMANENT:
- rel->rd_backend = InvalidBackendId;
+ rel->rd_backend = INVALID_PROC_NUMBER;
rel->rd_islocaltemp = false;
break;
case RELPERSISTENCE_TEMP:
Assert(isTempOrTempToastNamespace(relnamespace));
- rel->rd_backend = BackendIdForTempRelations();
+ rel->rd_backend = ProcNumberForTempRelations();
rel->rd_islocaltemp = true;
break;
default:
/* Virtual transaction id */
/* keep VXID format in sync with lockfuncs.c */
- if (MyProc != NULL && MyProc->vxid.backendId != InvalidBackendId)
- appendStringInfo(&buf, "%d/%u", MyProc->vxid.backendId, MyProc->vxid.lxid);
+ if (MyProc != NULL && MyProc->vxid.procNumber != INVALID_PROC_NUMBER)
+ appendStringInfo(&buf, "%d/%u", MyProc->vxid.procNumber, MyProc->vxid.lxid);
appendStringInfoChar(&buf, ',');
/* Transaction id */
break;
case 'v':
/* keep VXID format in sync with lockfuncs.c */
- if (MyProc != NULL && MyProc->vxid.backendId != InvalidBackendId)
+ if (MyProc != NULL && MyProc->vxid.procNumber != INVALID_PROC_NUMBER)
{
if (padding != 0)
{
char strfbuf[128];
snprintf(strfbuf, sizeof(strfbuf) - 1, "%d/%u",
- MyProc->vxid.backendId, MyProc->vxid.lxid);
+ MyProc->vxid.procNumber, MyProc->vxid.lxid);
appendStringInfo(buf, "%*s", padding, strfbuf);
}
else
- appendStringInfo(buf, "%d/%u", MyProc->vxid.backendId, MyProc->vxid.lxid);
+ appendStringInfo(buf, "%d/%u", MyProc->vxid.procNumber, MyProc->vxid.lxid);
}
else if (padding != 0)
appendStringInfoSpaces(buf,
/* Virtual transaction id */
/* keep VXID format in sync with lockfuncs.c */
- if (MyProc != NULL && MyProc->vxid.backendId != InvalidBackendId)
+ if (MyProc != NULL && MyProc->vxid.procNumber != INVALID_PROC_NUMBER)
appendJSONKeyValueFmt(&buf, "vxid", true, "%d/%u",
- MyProc->vxid.backendId, MyProc->vxid.lxid);
+ MyProc->vxid.procNumber, MyProc->vxid.lxid);
/* Transaction id */
appendJSONKeyValueFmt(&buf, "txid", false, "%u",
#include "libpq/libpq-be.h"
#include "libpq/pqcomm.h"
#include "miscadmin.h"
-#include "storage/backendid.h"
+#include "storage/procnumber.h"
ProtocolVersion FrontendProtocol;
/* note: currently this is not valid in backend processes */
#endif
-BackendId MyBackendId = InvalidBackendId;
+ProcNumber MyProcNumber = INVALID_PROC_NUMBER;
-BackendId ParallelLeaderBackendId = InvalidBackendId;
+ProcNumber ParallelLeaderProcNumber = INVALID_PROC_NUMBER;
Oid MyDatabaseId = InvalidOid;
* inside the transaction from 1.
*/
snprintf(path, sizeof(path), SNAPSHOT_EXPORT_DIR "/%08X-%08X-%d",
- MyProc->vxid.backendId, MyProc->vxid.lxid,
+ MyProc->vxid.procNumber, MyProc->vxid.lxid,
list_length(exportedSnapshots) + 1);
/*
*/
initStringInfo(&buf);
- appendStringInfo(&buf, "vxid:%d/%u\n", MyProc->vxid.backendId, MyProc->vxid.lxid);
+ appendStringInfo(&buf, "vxid:%d/%u\n", MyProc->vxid.procNumber, MyProc->vxid.lxid);
appendStringInfo(&buf, "pid:%d\n", MyProcPid);
appendStringInfo(&buf, "dbid:%u\n", MyDatabaseId);
appendStringInfo(&buf, "iso:%d\n", XactIsoLevel);
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid snapshot data in file \"%s\"", filename)));
ptr += prefixlen;
- if (sscanf(ptr, "%d/%u", &vxid->backendId, &vxid->localTransactionId) != 2)
+ if (sscanf(ptr, "%d/%u", &vxid->procNumber, &vxid->localTransactionId) != 2)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid snapshot data in file \"%s\"", filename)));
#include "catalog/pg_tablespace_d.h"
#include "common/relpath.h"
-#include "storage/backendid.h"
+#include "storage/procnumber.h"
/*
*
* Result is a palloc'd string.
*
- * Note: ideally, backendId would be declared as type BackendId, but relpath.h
- * would have to include a backend-only header to do that; doesn't seem worth
- * the trouble considering BackendId is just int anyway.
+ * Note: ideally, procNumber would be declared as type ProcNumber, but
+ * relpath.h would have to include a backend-only header to do that; doesn't
+ * seem worth the trouble considering ProcNumber is just int anyway.
*/
char *
GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
- int backendId, ForkNumber forkNumber)
+ int procNumber, ForkNumber forkNumber)
{
char *path;
{
/* Shared system relations live in {datadir}/global */
Assert(dbOid == 0);
- Assert(backendId == InvalidBackendId);
+ Assert(procNumber == INVALID_PROC_NUMBER);
if (forkNumber != MAIN_FORKNUM)
path = psprintf("global/%u_%s",
relNumber, forkNames[forkNumber]);
else if (spcOid == DEFAULTTABLESPACE_OID)
{
/* The default tablespace is {datadir}/base */
- if (backendId == InvalidBackendId)
+ if (procNumber == INVALID_PROC_NUMBER)
{
if (forkNumber != MAIN_FORKNUM)
path = psprintf("base/%u/%u_%s",
{
if (forkNumber != MAIN_FORKNUM)
path = psprintf("base/%u/t%d_%u_%s",
- dbOid, backendId, relNumber,
+ dbOid, procNumber, relNumber,
forkNames[forkNumber]);
else
path = psprintf("base/%u/t%d_%u",
- dbOid, backendId, relNumber);
+ dbOid, procNumber, relNumber);
}
}
else
{
/* All other tablespaces are accessed via symlinks */
- if (backendId == InvalidBackendId)
+ if (procNumber == INVALID_PROC_NUMBER)
{
if (forkNumber != MAIN_FORKNUM)
path = psprintf("pg_tblspc/%u/%s/%u/%u_%s",
if (forkNumber != MAIN_FORKNUM)
path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u_%s",
spcOid, TABLESPACE_VERSION_DIRECTORY,
- dbOid, backendId, relNumber,
+ dbOid, procNumber, relNumber,
forkNames[forkNumber]);
else
path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u",
spcOid, TABLESPACE_VERSION_DIRECTORY,
- dbOid, backendId, relNumber);
+ dbOid, procNumber, relNumber);
}
}
return path;
extern TransactionId TwoPhaseGetXidByVirtualXID(VirtualTransactionId vxid,
bool *have_more);
extern PGPROC *TwoPhaseGetDummyProc(TransactionId xid, bool lock_held);
-extern BackendId TwoPhaseGetDummyBackendId(TransactionId xid, bool lock_held);
+extern int TwoPhaseGetDummyProcNumber(TransactionId xid, bool lock_held);
extern GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid,
TimestampTz prepared_at,
#include "nodes/primnodes.h"
#include "storage/lock.h"
+#include "storage/procnumber.h"
/*
extern bool isAnyTempNamespace(Oid namespaceId);
extern bool isOtherTempNamespace(Oid namespaceId);
extern TempNamespaceStatus checkTempNamespaceStatus(Oid namespaceId);
-extern int GetTempNamespaceBackendId(Oid namespaceId);
+extern ProcNumber GetTempNamespaceProcNumber(Oid namespaceId);
extern Oid GetTempToastNamespace(void);
extern void GetTempNamespaceState(Oid *tempNamespaceId,
Oid *tempToastNamespaceId);
extern char *GetDatabasePath(Oid dbOid, Oid spcOid);
extern char *GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
- int backendId, ForkNumber forkNumber);
+ int procNumber, ForkNumber forkNumber);
/*
* Wrapper macros for GetRelationPath. Beware of multiple
/* First argument is a RelFileLocator */
#define relpathperm(rlocator, forknum) \
- relpathbackend(rlocator, InvalidBackendId, forknum)
+ relpathbackend(rlocator, INVALID_PROC_NUMBER, forknum)
/* First argument is a RelFileLocatorBackend */
#define relpath(rlocator, forknum) \
#include "storage/shm_mq.h"
extern void pq_redirect_to_shm_mq(dsm_segment *seg, shm_mq_handle *mqh);
-extern void pq_set_parallel_leader(pid_t pid, BackendId backend_id);
+extern void pq_set_parallel_leader(pid_t pid, ProcNumber procNumber);
extern void pq_parse_errornotice(StringInfo msg, ErrorData *edata);
extern PGDLLIMPORT char postgres_exec_path[];
#endif
-/*
- * done in storage/backendid.h for now.
- *
- * extern BackendId MyBackendId;
- */
extern PGDLLIMPORT Oid MyDatabaseId;
extern PGDLLIMPORT Oid MyDatabaseTableSpace;
* by using a 64bit state; but it's unlikely to be worthwhile as 2^18-1
* backends exceed currently realistic configurations. Even if that limitation
* were removed, we still could not a) exceed 2^23-1 because inval.c stores
- * the backend ID as a 3-byte signed integer, b) INT_MAX/4 because some places
+ * the ProcNumber as a 3-byte signed integer, b) INT_MAX/4 because some places
* compute 4*MaxBackends without any overflow check. This is rechecked in the
* relevant GUC check hooks and in RegisterBackgroundWorker().
*/
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * backendid.h
- * POSTGRES backend id communication definitions
- *
- *
- * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * src/include/storage/backendid.h
- *
- *-------------------------------------------------------------------------
- */
-#ifndef BACKENDID_H
-#define BACKENDID_H
-
-/*
- * BackendId uniquely identifies an active backend or auxiliary process. It's
- * assigned at backend startup after authentication. Note that a backend ID
- * can be reused for a different backend immediately after a backend exits.
- *
- * Backend IDs are assigned starting from 1. For historical reasons, BackendId
- * 0 is unused, but InvalidBackendId is defined as -1.
- */
-typedef int BackendId;
-
-#define InvalidBackendId (-1)
-
-extern PGDLLIMPORT BackendId MyBackendId; /* backend id of this backend */
-
-/* backend id of our parallel session leader, or InvalidBackendId if none */
-extern PGDLLIMPORT BackendId ParallelLeaderBackendId;
-
-/*
- * The BackendId to use for our session's temp relations is normally our own,
- * but parallel workers should use their leader's ID.
- */
-#define BackendIdForTempRelations() \
- (ParallelLeaderBackendId == InvalidBackendId ? MyBackendId : ParallelLeaderBackendId)
-
-#endif /* BACKENDID_H */
#endif
#include "lib/ilist.h"
-#include "storage/backendid.h"
#include "storage/lockdefs.h"
#include "storage/lwlock.h"
+#include "storage/procnumber.h"
#include "storage/shmem.h"
#include "utils/timestamp.h"
/*
* Top-level transactions are identified by VirtualTransactionIDs comprising
- * PGPROC fields backendId and lxid. For recovered prepared transactions, the
+ * PGPROC fields procNumber and lxid. For recovered prepared transactions, the
* LocalTransactionId is an ordinary XID; LOCKTAG_VIRTUALTRANSACTION never
* refers to that kind. These are guaranteed unique over the short term, but
* will be reused after a database restart or XID wraparound; hence they
*
* Note that struct VirtualTransactionId can not be assumed to be atomically
* assignable as a whole. However, type LocalTransactionId is assumed to
- * be atomically assignable, and the backend ID doesn't change often enough
+ * be atomically assignable, and the proc number doesn't change often enough
* to be a problem, so we can fetch or assign the two fields separately.
* We deliberately refrain from using the struct within PGPROC, to prevent
* coding errors from trying to use struct assignment with it; instead use
*/
typedef struct
{
- BackendId backendId; /* backendId from PGPROC */
+ ProcNumber procNumber; /* proc number of the PGPROC */
LocalTransactionId localTransactionId; /* lxid from PGPROC */
} VirtualTransactionId;
#define VirtualTransactionIdIsValid(vxid) \
(LocalTransactionIdIsValid((vxid).localTransactionId))
#define VirtualTransactionIdIsRecoveredPreparedXact(vxid) \
- ((vxid).backendId == InvalidBackendId)
+ ((vxid).procNumber == INVALID_PROC_NUMBER)
#define VirtualTransactionIdEquals(vxid1, vxid2) \
- ((vxid1).backendId == (vxid2).backendId && \
+ ((vxid1).procNumber == (vxid2).procNumber && \
(vxid1).localTransactionId == (vxid2).localTransactionId)
#define SetInvalidVirtualTransactionId(vxid) \
- ((vxid).backendId = InvalidBackendId, \
+ ((vxid).procNumber = INVALID_PROC_NUMBER, \
(vxid).localTransactionId = InvalidLocalTransactionId)
#define GET_VXID_FROM_PGPROC(vxid_dst, proc) \
- ((vxid_dst).backendId = (proc).vxid.backendId, \
+ ((vxid_dst).procNumber = (proc).vxid.procNumber, \
(vxid_dst).localTransactionId = (proc).vxid.lxid)
/* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */
/* ID info for a virtual transaction is its VirtualTransactionId */
#define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \
- ((locktag).locktag_field1 = (vxid).backendId, \
+ ((locktag).locktag_field1 = (vxid).procNumber, \
(locktag).locktag_field2 = (vxid).localTransactionId, \
(locktag).locktag_field3 = 0, \
(locktag).locktag_field4 = 0, \
#include "storage/lock.h"
#include "storage/pg_sema.h"
#include "storage/proclist_types.h"
+#include "storage/procnumber.h"
/*
* Each backend advertises up to PGPROC_MAX_CACHED_SUBXIDS TransactionIds
*/
#define FP_LOCK_SLOTS_PER_BACKEND 16
-/*
- * An invalid pgprocno. Must be larger than the maximum number of PGPROC
- * structures we could possibly have. See comments for MAX_BACKENDS.
- */
-#define INVALID_PGPROCNO PG_INT32_MAX
-
/*
* Flags for PGPROC.delayChkptFlags
*
*/
struct
{
- BackendId backendId; /* For regular backends, equal to
- * GetBackendIdFromPGProc(proc). For prepared
+ ProcNumber procNumber; /* For regular backends, equal to
+ * GetNumberFromPGProc(proc). For prepared
* xacts, ID of the original backend that
* processed the transaction. For unused
- * PGPROC entries, InvalidBackendID. */
+ * PGPROC entries, INVALID_PROC_NUMBER. */
LocalTransactionId lxid; /* local id of top-level transaction
* currently * being executed by this
* proc, if running; else
extern PGDLLIMPORT PGPROC *MyProc;
-extern PGDLLIMPORT int MyProcNumber; /* same as GetNumberFromPGProc(MyProc) */
+
+/* Proc number of this backend. Equal to GetNumberFromPGProc(MyProc). */
+extern PGDLLIMPORT ProcNumber MyProcNumber;
+
+/* Our parallel session leader, or INVALID_PROC_NUMBER if none */
+extern PGDLLIMPORT ProcNumber ParallelLeaderProcNumber;
+
+/*
+ * The proc number to use for our session's temp relations is normally our own,
+ * but parallel workers should use their leader's ID.
+ */
+#define ProcNumberForTempRelations() \
+ (ParallelLeaderProcNumber == INVALID_PROC_NUMBER ? MyProcNumber : ParallelLeaderProcNumber)
/*
* There is one ProcGlobal struct for the whole database cluster.
extern PGDLLIMPORT PGPROC *PreparedXactProcs;
/*
- * Accessors for getting PGPROC given a pgprocno or BackendId, and vice versa.
- *
- * For historical reasons, some code uses 0-based "proc numbers", while other
- * code uses 1-based backend IDs.
+ * Accessors for getting PGPROC given a ProcNumber and vice versa.
*/
#define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)])
#define GetNumberFromPGProc(proc) ((proc) - &ProcGlobal->allProcs[0])
-#define GetPGProcByBackendId(n) (&ProcGlobal->allProcs[(n) - 1])
-#define GetBackendIdFromPGProc(proc) (GetNumberFromPGProc(proc) + 1)
/*
* We set aside some extra PGPROC structures for auxiliary processes,
extern void LockErrorCleanup(void);
extern void ProcWaitForSignal(uint32 wait_event_info);
-extern void ProcSendSignal(int pgprocno);
+extern void ProcSendSignal(ProcNumber procNumber);
extern PGPROC *AuxiliaryPidGetProc(int pid);
extern bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids,
int nvxids, int type);
-extern PGPROC *BackendIdGetProc(int backendID);
-extern void BackendIdGetTransactionIds(int backendID, TransactionId *xid,
- TransactionId *xmin, int *nsubxid,
- bool *overflowed);
+extern PGPROC *ProcNumberGetProc(int procNumber);
+extern void ProcNumberGetTransactionIds(int procNumber, TransactionId *xid,
+ TransactionId *xmin, int *nsubxid,
+ bool *overflowed);
extern PGPROC *BackendPidGetProc(int pid);
extern PGPROC *BackendPidGetProcWithLock(int pid);
extern int BackendXidGetPid(TransactionId xid);
static inline void
proclist_init(proclist_head *list)
{
- list->head = list->tail = INVALID_PGPROCNO;
+ list->head = list->tail = INVALID_PROC_NUMBER;
}
/*
static inline bool
proclist_is_empty(const proclist_head *list)
{
- return list->head == INVALID_PGPROCNO;
+ return list->head == INVALID_PROC_NUMBER;
}
/*
Assert(node->next == 0 && node->prev == 0);
- if (list->head == INVALID_PGPROCNO)
+ if (list->head == INVALID_PROC_NUMBER)
{
- Assert(list->tail == INVALID_PGPROCNO);
- node->next = node->prev = INVALID_PGPROCNO;
+ Assert(list->tail == INVALID_PROC_NUMBER);
+ node->next = node->prev = INVALID_PROC_NUMBER;
list->head = list->tail = procno;
}
else
{
- Assert(list->tail != INVALID_PGPROCNO);
+ Assert(list->tail != INVALID_PROC_NUMBER);
Assert(list->head != procno);
Assert(list->tail != procno);
node->next = list->head;
proclist_node_get(node->next, node_offset)->prev = procno;
- node->prev = INVALID_PGPROCNO;
+ node->prev = INVALID_PROC_NUMBER;
list->head = procno;
}
}
Assert(node->next == 0 && node->prev == 0);
- if (list->tail == INVALID_PGPROCNO)
+ if (list->tail == INVALID_PROC_NUMBER)
{
- Assert(list->head == INVALID_PGPROCNO);
- node->next = node->prev = INVALID_PGPROCNO;
+ Assert(list->head == INVALID_PROC_NUMBER);
+ node->next = node->prev = INVALID_PROC_NUMBER;
list->head = list->tail = procno;
}
else
{
- Assert(list->head != INVALID_PGPROCNO);
+ Assert(list->head != INVALID_PROC_NUMBER);
Assert(list->head != procno);
Assert(list->tail != procno);
node->prev = list->tail;
proclist_node_get(node->prev, node_offset)->next = procno;
- node->next = INVALID_PGPROCNO;
+ node->next = INVALID_PROC_NUMBER;
list->tail = procno;
}
}
Assert(node->next != 0 || node->prev != 0);
- if (node->prev == INVALID_PGPROCNO)
+ if (node->prev == INVALID_PROC_NUMBER)
{
Assert(list->head == procno);
list->head = node->next;
else
proclist_node_get(node->prev, node_offset)->next = node->next;
- if (node->next == INVALID_PGPROCNO)
+ if (node->next == INVALID_PROC_NUMBER)
{
Assert(list->tail == procno);
list->tail = node->prev;
* tail, and that seems worth doing, since in practice that should often
* be enough to catch mistakes.
*/
- Assert(node->prev != INVALID_PGPROCNO || list->head == procno);
- Assert(node->next != INVALID_PGPROCNO || list->tail == procno);
+ Assert(node->prev != INVALID_PROC_NUMBER || list->head == procno);
+ Assert(node->next != INVALID_PROC_NUMBER || list->tail == procno);
return true;
}
for (AssertVariableIsOfTypeMacro(iter, proclist_mutable_iter), \
AssertVariableIsOfTypeMacro(lhead, proclist_head *), \
(iter).cur = (lhead)->head, \
- (iter).next = (iter).cur == INVALID_PGPROCNO ? INVALID_PGPROCNO : \
+ (iter).next = (iter).cur == INVALID_PROC_NUMBER ? INVALID_PROC_NUMBER : \
proclist_node_get((iter).cur, \
offsetof(PGPROC, link_member))->next; \
- (iter).cur != INVALID_PGPROCNO; \
+ (iter).cur != INVALID_PROC_NUMBER; \
(iter).cur = (iter).next, \
- (iter).next = (iter).cur == INVALID_PGPROCNO ? INVALID_PGPROCNO : \
+ (iter).next = (iter).cur == INVALID_PROC_NUMBER ? INVALID_PROC_NUMBER : \
proclist_node_get((iter).cur, \
offsetof(PGPROC, link_member))->next)
#ifndef PROCLIST_TYPES_H
#define PROCLIST_TYPES_H
+#include "storage/procnumber.h"
+
/*
* A node in a doubly-linked list of processes. The link fields contain
* the 0-based PGPROC indexes of the next and previous process, or
- * INVALID_PGPROCNO in the next-link of the last node and the prev-link
+ * INVALID_PROC_NUMBER in the next-link of the last node and the prev-link
* of the first node. A node that is currently not in any list
* should have next == prev == 0; this is not a possible state for a node
* that is in a list, because we disallow circularity.
*/
typedef struct proclist_node
{
- int next; /* pgprocno of the next PGPROC */
- int prev; /* pgprocno of the prev PGPROC */
+ ProcNumber next; /* pgprocno of the next PGPROC */
+ ProcNumber prev; /* pgprocno of the prev PGPROC */
} proclist_node;
/*
* Header of a doubly-linked list of PGPROCs, identified by pgprocno.
- * An empty list is represented by head == tail == INVALID_PGPROCNO.
+ * An empty list is represented by head == tail == INVALID_PROC_NUMBER.
*/
typedef struct proclist_head
{
- int head; /* pgprocno of the head PGPROC */
- int tail; /* pgprocno of the tail PGPROC */
+ ProcNumber head; /* pgprocno of the head PGPROC */
+ ProcNumber tail; /* pgprocno of the tail PGPROC */
} proclist_head;
/*
*/
typedef struct proclist_mutable_iter
{
- int cur; /* pgprocno of the current PGPROC */
- int next; /* pgprocno of the next PGPROC */
+ ProcNumber cur; /* pgprocno of the current PGPROC */
+ ProcNumber next; /* pgprocno of the next PGPROC */
} proclist_mutable_iter;
#endif /* PROCLIST_TYPES_H */
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * procnumber.h
+ * definition of process number
+ *
+ *
+ * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/storage/procnumber.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PROCNUMBER_H
+#define PROCNUMBER_H
+
+/*
+ * ProcNumber uniquely identifies an active backend or auxiliary process.
+ * It's assigned at backend startup after authentication, when the process
+ * adds itself to the proc array. It is an index into the proc array,
+ * starting from 0. Note that a ProcNumber can be reused for a different
+ * backend immediately after a backend exits.
+ */
+typedef int ProcNumber;
+
+#define INVALID_PROC_NUMBER (-1)
+
+/*
+ * Proc number of this backend (same as GetNumberFromPGProc(MyProc))
+ */
+extern PGDLLIMPORT ProcNumber MyProcNumber;
+
+/* proc number of our parallel session leader, or INVALID_PROC_NUMBER if none */
+extern PGDLLIMPORT ProcNumber ParallelLeaderProcNumber;
+
+/*
+ * The ProcNumber to use for our session's temp relations is normally our own,
+ * but parallel workers should use their leader's proc number.
+ */
+#define ProcNumberForTempRelations() \
+ (ParallelLeaderProcNumber == INVALID_PROC_NUMBER ? MyProcNumber : ParallelLeaderProcNumber)
+
+#endif /* PROCNUMBER_H */
#ifndef PROCSIGNAL_H
#define PROCSIGNAL_H
-#include "storage/backendid.h"
+#include "storage/procnumber.h"
/*
extern void ProcSignalInit(void);
extern int SendProcSignal(pid_t pid, ProcSignalReason reason,
- BackendId backendId);
+ ProcNumber procNumber);
extern uint64 EmitProcSignalBarrier(ProcSignalBarrierType type);
extern void WaitForProcSignalBarrier(uint64 generation);
#define RELFILELOCATOR_H
#include "common/relpath.h"
-#include "storage/backendid.h"
+#include "storage/procnumber.h"
/*
* RelFileLocator must provide all that we need to know to physically access
- * a relation, with the exception of the backend ID, which can be provided
- * separately. Note, however, that a "physical" relation is comprised of
- * multiple files on the filesystem, as each fork is stored as a separate
- * file, and each fork can be divided into multiple segments. See md.c.
+ * a relation, with the exception of the backend's proc number, which can be
+ * provided separately. Note, however, that a "physical" relation is
+ * comprised of multiple files on the filesystem, as each fork is stored as
+ * a separate file, and each fork can be divided into multiple segments. See
+ * md.c.
*
* spcOid identifies the tablespace of the relation. It corresponds to
* pg_tablespace.oid.
} RelFileLocator;
/*
- * Augmenting a relfilelocator with the backend ID provides all the information
- * we need to locate the physical storage. The backend ID is InvalidBackendId
- * for regular relations (those accessible to more than one backend), or the
- * owning backend's ID for backend-local relations. Backend-local relations
- * are always transient and removed in case of a database crash; they are
- * never WAL-logged or fsync'd.
+ * Augmenting a relfilelocator with the backend's proc number provides all the
+ * information we need to locate the physical storage. 'backend' is
+ * INVALID_PROC_NUMBER for regular relations (those accessible to more than
+ * one backend), or the owning backend's proc number for backend-local
+ * relations. Backend-local relations are always transient and removed in
+ * case of a database crash; they are never WAL-logged or fsync'd.
*/
typedef struct RelFileLocatorBackend
{
RelFileLocator locator;
- BackendId backend;
+ ProcNumber backend;
} RelFileLocatorBackend;
#define RelFileLocatorBackendIsTemp(rlocator) \
- ((rlocator).backend != InvalidBackendId)
+ ((rlocator).backend != INVALID_PROC_NUMBER)
/*
* Note: RelFileLocatorEquals and RelFileLocatorBackendEquals compare relNumber
* first since that is most likely to be different in two unequal
* RelFileLocators. It is probably redundant to compare spcOid if the other
* fields are found equal, but do it anyway to be sure. Likewise for checking
- * the backend ID in RelFileLocatorBackendEquals.
+ * the backend number in RelFileLocatorBackendEquals.
*/
#define RelFileLocatorEquals(locator1, locator2) \
((locator1).relNumber == (locator2).relNumber && \
{
/* note: field layout chosen to pack into 16 bytes */
int8 id; /* type field --- must be first */
- int8 backend_hi; /* high bits of backend ID, if temprel */
- uint16 backend_lo; /* low bits of backend ID, if temprel */
+ int8 backend_hi; /* high bits of backend procno, if temprel */
+ uint16 backend_lo; /* low bits of backend procno, if temprel */
RelFileLocator rlocator; /* spcOid, dbOid, relNumber */
} SharedInvalSmgrMsg;
RelFileLocatorBackendIsTemp((smgr)->smgr_rlocator)
extern void smgrinit(void);
-extern SMgrRelation smgropen(RelFileLocator rlocator, BackendId backend);
+extern SMgrRelation smgropen(RelFileLocator rlocator, ProcNumber backend);
extern bool smgrexists(SMgrRelation reln, ForkNumber forknum);
extern void smgrpin(SMgrRelation reln);
extern void smgrunpin(SMgrRelation reln);
#include "datatype/timestamp.h"
#include "libpq/pqcomm.h"
#include "miscadmin.h" /* for BackendType */
-#include "storage/backendid.h"
+#include "storage/procnumber.h"
#include "utils/backend_progress.h"
*
* Each live backend maintains a PgBackendStatus struct in shared memory
* showing its current activity. (The structs are allocated according to
- * BackendId, but that is not critical.) Note that this is unrelated to the
+ * ProcNumber, but that is not critical.) Note that this is unrelated to the
* cumulative stats system (i.e. pgstat.c et al).
*
* Each auxiliary process also maintains a PgBackendStatus struct in shared
PgBackendStatus backendStatus;
/*
- * The backend ID. For auxiliary processes, this will be set to a value
- * greater than MaxBackends (since auxiliary processes do not have proper
- * backend IDs).
+ * The proc number.
*/
- BackendId backend_id;
+ ProcNumber proc_number;
/*
* The xid of the current transaction if available, InvalidTransactionId
* ----------
*/
extern int pgstat_fetch_stat_numbackends(void);
-extern PgBackendStatus *pgstat_get_beentry_by_backend_id(BackendId beid);
-extern LocalPgBackendStatus *pgstat_get_local_beentry_by_backend_id(BackendId beid);
+extern PgBackendStatus *pgstat_get_beentry_by_proc_number(ProcNumber procNumber);
+extern LocalPgBackendStatus *pgstat_get_local_beentry_by_proc_number(ProcNumber procNumber);
extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int idx);
extern char *pgstat_clip_activity(const char *raw_activity);
RelFileLocator rd_locator; /* relation physical identifier */
SMgrRelation rd_smgr; /* cached file handle, or NULL */
int rd_refcnt; /* reference count */
- BackendId rd_backend; /* owning backend id, if temporary relation */
+ ProcNumber rd_backend; /* owning backend's proc number, if temp rel */
bool rd_islocaltemp; /* rel is a temp rel of this session */
bool rd_isnailed; /* rel is nailed in cache */
bool rd_isvalid; /* relcache entry is valid */