Replace BackendIds with 0-based ProcNumbers
Now that BackendId was just another index into the proc array, it was redundant with the 0-based proc numbers used in other places. Replace all usage of backend IDs with proc numbers. The only place where the term "backend id" remains is in a few pgstat functions that expose backend IDs at the SQL level. Those IDs are now in fact 0-based ProcNumbers too, but the documentation still calls them "backend ids". That term still seems appropriate to describe what the numbers are, so I let it be. One user-visible effect is that pg_temp_0 is now a valid temp schema name, for backend with ProcNumber 0. Reviewed-by: Andres Freund Discussion: https://www.postgresql.org/message-id/8171f1aa-496f-46a6-afc3-c46fe7a9b407@iki.fi
This commit is contained in:
parent
ab355e3a88
commit
024c521117
|
@ -7495,7 +7495,7 @@ local0.* /var/log/postgresql
|
|||
</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>
|
||||
|
|
|
@ -4940,7 +4940,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage
|
|||
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.
|
||||
|
@ -6813,7 +6813,7 @@ FROM pg_stat_get_backend_idset() AS backendid;
|
|||
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>
|
||||
|
@ -6824,7 +6824,7 @@ FROM pg_stat_get_backend_idset() AS backendid;
|
|||
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
|
||||
|
@ -6839,7 +6839,7 @@ FROM pg_stat_get_backend_idset() AS backendid;
|
|||
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>
|
||||
|
@ -6850,7 +6850,7 @@ FROM pg_stat_get_backend_idset() AS backendid;
|
|||
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>
|
||||
|
@ -6903,7 +6903,7 @@ FROM pg_stat_get_backend_idset() AS backendid;
|
|||
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>
|
||||
|
@ -6913,7 +6913,7 @@ FROM pg_stat_get_backend_idset() AS backendid;
|
|||
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>
|
||||
|
@ -6925,7 +6925,7 @@ FROM pg_stat_get_backend_idset() AS backendid;
|
|||
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>
|
||||
|
@ -6935,7 +6935,7 @@ FROM pg_stat_get_backend_idset() AS backendid;
|
|||
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>
|
||||
|
|
|
@ -202,7 +202,7 @@ these files are named after the table or index's <firstterm>filenode</firstterm>
|
|||
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
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
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>
|
||||
|
|
|
@ -203,12 +203,12 @@ pg_subtrans and PGPROC are done at the time it is assigned.
|
|||
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
|
||||
|
|
|
@ -501,7 +501,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
|
|||
* 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)
|
||||
{
|
||||
/*
|
||||
|
@ -509,7 +509,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
|
|||
* 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;
|
||||
}
|
||||
|
||||
|
@ -525,9 +525,9 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
|
|||
* 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;
|
||||
|
||||
|
@ -543,7 +543,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
|
|||
}
|
||||
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)
|
||||
|
@ -568,13 +568,13 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
|
|||
* 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;
|
||||
|
@ -633,12 +633,12 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
|
|||
* 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();
|
||||
|
|
|
@ -237,11 +237,11 @@ typedef struct MultiXactStateData
|
|||
/*
|
||||
* 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
|
||||
|
@ -285,8 +285,7 @@ typedef struct MultiXactStateData
|
|||
} 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)
|
||||
|
||||
|
@ -397,7 +396,7 @@ MultiXactIdCreate(TransactionId xid1, MultiXactStatus status1,
|
|||
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
|
||||
|
@ -451,7 +450,7 @@ MultiXactIdExpand(MultiXactId multi, TransactionId xid, MultiXactStatus status)
|
|||
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));
|
||||
|
@ -626,7 +625,7 @@ MultiXactIdIsRunning(MultiXactId multi, bool isLockOnly)
|
|||
void
|
||||
MultiXactIdSetOldestMember(void)
|
||||
{
|
||||
if (!MultiXactIdIsValid(OldestMemberMXactId[MyBackendId]))
|
||||
if (!MultiXactIdIsValid(OldestMemberMXactId[MyProcNumber]))
|
||||
{
|
||||
MultiXactId nextMXact;
|
||||
|
||||
|
@ -655,12 +654,12 @@ MultiXactIdSetOldestMember(void)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -683,7 +682,7 @@ MultiXactIdSetOldestMember(void)
|
|||
static void
|
||||
MultiXactIdSetOldestVisible(void)
|
||||
{
|
||||
if (!MultiXactIdIsValid(OldestVisibleMXactId[MyBackendId]))
|
||||
if (!MultiXactIdIsValid(OldestVisibleMXactId[MyProcNumber]))
|
||||
{
|
||||
MultiXactId oldestMXact;
|
||||
int i;
|
||||
|
@ -699,7 +698,7 @@ MultiXactIdSetOldestVisible(void)
|
|||
if (oldestMXact < FirstMultiXactId)
|
||||
oldestMXact = FirstMultiXactId;
|
||||
|
||||
for (i = 1; i <= MaxOldestSlot; i++)
|
||||
for (i = 0; i < MaxOldestSlot; i++)
|
||||
{
|
||||
MultiXactId thisoldest = OldestMemberMXactId[i];
|
||||
|
||||
|
@ -708,12 +707,12 @@ MultiXactIdSetOldestVisible(void)
|
|||
oldestMXact = thisoldest;
|
||||
}
|
||||
|
||||
OldestVisibleMXactId[MyBackendId] = oldestMXact;
|
||||
OldestVisibleMXactId[MyProcNumber] = oldestMXact;
|
||||
|
||||
LWLockRelease(MultiXactGenLock);
|
||||
|
||||
debug_elog4(DEBUG2, "MultiXact: setting OldestVisible[%d] = %u",
|
||||
MyBackendId, oldestMXact);
|
||||
MyProcNumber, oldestMXact);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1285,7 +1284,7 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members,
|
|||
* 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;
|
||||
|
@ -1752,8 +1751,8 @@ AtEOXact_MultiXact(void)
|
|||
* 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
|
||||
|
@ -1773,7 +1772,7 @@ AtEOXact_MultiXact(void)
|
|||
void
|
||||
AtPrepare_MultiXact(void)
|
||||
{
|
||||
MultiXactId myOldestMember = OldestMemberMXactId[MyBackendId];
|
||||
MultiXactId myOldestMember = OldestMemberMXactId[MyProcNumber];
|
||||
|
||||
if (MultiXactIdIsValid(myOldestMember))
|
||||
RegisterTwoPhaseRecord(TWOPHASE_RM_MULTIXACT_ID, 0,
|
||||
|
@ -1793,10 +1792,10 @@ PostPrepare_MultiXact(TransactionId xid)
|
|||
* 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
|
||||
|
@ -1806,8 +1805,8 @@ PostPrepare_MultiXact(TransactionId xid)
|
|||
*/
|
||||
LWLockAcquire(MultiXactGenLock, LW_EXCLUSIVE);
|
||||
|
||||
OldestMemberMXactId[dummyBackendId] = myOldestMember;
|
||||
OldestMemberMXactId[MyBackendId] = InvalidMultiXactId;
|
||||
OldestMemberMXactId[dummyProcNumber] = myOldestMember;
|
||||
OldestMemberMXactId[MyProcNumber] = InvalidMultiXactId;
|
||||
|
||||
LWLockRelease(MultiXactGenLock);
|
||||
}
|
||||
|
@ -1820,7 +1819,7 @@ PostPrepare_MultiXact(TransactionId xid)
|
|||
* 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.
|
||||
|
@ -1837,7 +1836,7 @@ void
|
|||
multixact_twophase_recover(TransactionId xid, uint16 info,
|
||||
void *recdata, uint32 len)
|
||||
{
|
||||
BackendId dummyBackendId = TwoPhaseGetDummyBackendId(xid, false);
|
||||
ProcNumber dummyProcNumber = TwoPhaseGetDummyProcNumber(xid, false);
|
||||
MultiXactId oldestMember;
|
||||
|
||||
/*
|
||||
|
@ -1847,7 +1846,7 @@ multixact_twophase_recover(TransactionId xid, uint16 info,
|
|||
Assert(len == sizeof(MultiXactId));
|
||||
oldestMember = *((MultiXactId *) recdata);
|
||||
|
||||
OldestMemberMXactId[dummyBackendId] = oldestMember;
|
||||
OldestMemberMXactId[dummyProcNumber] = oldestMember;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1858,11 +1857,11 @@ void
|
|||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1886,9 +1885,9 @@ MultiXactShmemSize(void)
|
|||
{
|
||||
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;
|
||||
|
@ -1938,8 +1937,7 @@ MultiXactShmemInit(void)
|
|||
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;
|
||||
|
@ -2617,7 +2615,7 @@ GetOldestMultiXactId(void)
|
|||
nextMXact = FirstMultiXactId;
|
||||
|
||||
oldestMXact = nextMXact;
|
||||
for (i = 1; i <= MaxOldestSlot; i++)
|
||||
for (i = 0; i < MaxOldestSlot; i++)
|
||||
{
|
||||
MultiXactId thisoldest;
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ typedef struct FixedParallelState
|
|||
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;
|
||||
|
@ -337,7 +337,7 @@ InitializeParallelDSM(ParallelContext *pcxt)
|
|||
&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();
|
||||
|
@ -1351,7 +1351,7 @@ ParallelWorkerMain(Datum main_arg)
|
|||
|
||||
/* 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));
|
||||
|
||||
/*
|
||||
|
@ -1367,7 +1367,7 @@ ParallelWorkerMain(Datum main_arg)
|
|||
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
|
||||
|
@ -1594,7 +1594,7 @@ ParallelWorkerShutdown(int code, Datum arg)
|
|||
{
|
||||
SendProcSignal(ParallelLeaderPid,
|
||||
PROCSIG_PARALLEL_MESSAGE,
|
||||
ParallelLeaderBackendId);
|
||||
ParallelLeaderProcNumber);
|
||||
|
||||
dsm_detach((dsm_segment *) DatumGetPointer(arg));
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ int max_prepared_xacts = 0;
|
|||
*
|
||||
* 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
|
||||
|
@ -165,7 +165,7 @@ typedef struct GlobalTransactionData
|
|||
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 */
|
||||
|
@ -333,7 +333,7 @@ AtAbort_Twophase(void)
|
|||
if (!MyLockedGxact->valid)
|
||||
RemoveGXact(MyLockedGxact);
|
||||
else
|
||||
MyLockedGxact->locking_backend = InvalidBackendId;
|
||||
MyLockedGxact->locking_backend = INVALID_PROC_NUMBER;
|
||||
LWLockRelease(TwoPhaseStateLock);
|
||||
|
||||
MyLockedGxact = NULL;
|
||||
|
@ -347,7 +347,7 @@ void
|
|||
PostPrepare_Twophase(void)
|
||||
{
|
||||
LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
|
||||
MyLockedGxact->locking_backend = InvalidBackendId;
|
||||
MyLockedGxact->locking_backend = INVALID_PROC_NUMBER;
|
||||
LWLockRelease(TwoPhaseStateLock);
|
||||
|
||||
MyLockedGxact = NULL;
|
||||
|
@ -452,14 +452,14 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid,
|
|||
{
|
||||
/* 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);
|
||||
|
@ -484,7 +484,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid,
|
|||
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);
|
||||
|
@ -577,7 +577,7 @@ LockGXact(const char *gid, Oid user)
|
|||
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",
|
||||
|
@ -602,7 +602,7 @@ LockGXact(const char *gid, Oid user)
|
|||
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);
|
||||
|
@ -849,7 +849,7 @@ TwoPhaseGetGXact(TransactionId xid, bool lock_held)
|
|||
*
|
||||
* (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,
|
||||
|
@ -873,7 +873,10 @@ 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)
|
||||
|
@ -891,20 +894,20 @@ TwoPhaseGetXidByVirtualXID(VirtualTransactionId vxid,
|
|||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2549,7 +2552,7 @@ PrepareRedoAdd(char *buf, XLogRecPtr start_lsn,
|
|||
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 */
|
||||
|
|
|
@ -2084,10 +2084,10 @@ StartTransaction(void)
|
|||
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();
|
||||
|
||||
/*
|
||||
|
@ -2097,9 +2097,10 @@ StartTransaction(void)
|
|||
|
||||
/*
|
||||
* 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);
|
||||
|
|
|
@ -722,7 +722,7 @@ XLogPrefetcherNextBlock(uintptr_t pgsr_private, XLogRecPtr *lsn)
|
|||
* 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
|
||||
|
|
|
@ -491,7 +491,7 @@ XLogReadBufferExtended(RelFileLocator rlocator, ForkNumber forknum,
|
|||
}
|
||||
|
||||
/* 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
|
||||
|
@ -598,7 +598,7 @@ CreateFakeRelcacheEntry(RelFileLocator rlocator)
|
|||
* 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;
|
||||
|
@ -620,7 +620,7 @@ CreateFakeRelcacheEntry(RelFileLocator rlocator)
|
|||
* 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;
|
||||
}
|
||||
|
|
|
@ -672,7 +672,7 @@ GetIncrementalFilePath(Oid dboid, Oid spcoid, RelFileNumber relfilenumber,
|
|||
char *lastslash;
|
||||
char *ipath;
|
||||
|
||||
path = GetRelationPath(dboid, spcoid, relfilenumber, InvalidBackendId,
|
||||
path = GetRelationPath(dboid, spcoid, relfilenumber, INVALID_PROC_NUMBER,
|
||||
forknum);
|
||||
|
||||
lastslash = strrchr(path, '/');
|
||||
|
|
|
@ -504,7 +504,7 @@ GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence)
|
|||
RelFileLocatorBackend rlocator;
|
||||
char *rpath;
|
||||
bool collides;
|
||||
BackendId backend;
|
||||
ProcNumber procNumber;
|
||||
|
||||
/*
|
||||
* If we ever get here during pg_upgrade, there's something wrong; all
|
||||
|
@ -516,11 +516,11 @@ GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence)
|
|||
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);
|
||||
|
@ -534,11 +534,11 @@ GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char 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
|
||||
{
|
||||
|
|
|
@ -3714,18 +3714,18 @@ TempNamespaceStatus
|
|||
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;
|
||||
|
||||
|
@ -3742,13 +3742,13 @@ checkTempNamespaceStatus(Oid namespaceId)
|
|||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
@ -3756,13 +3756,13 @@ GetTempNamespaceBackendId(Oid namespaceId)
|
|||
/* 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;
|
||||
}
|
||||
|
@ -4400,8 +4400,8 @@ InitTempTableNamespace(void)
|
|||
/*
|
||||
* 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;
|
||||
|
@ -4418,7 +4418,7 @@ InitTempTableNamespace(void)
|
|||
(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))
|
||||
|
@ -4451,7 +4451,7 @@ InitTempTableNamespace(void)
|
|||
* 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))
|
||||
|
|
|
@ -61,7 +61,7 @@ int wal_skip_threshold = 2048; /* in kilobytes */
|
|||
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 */
|
||||
|
@ -122,7 +122,7 @@ RelationCreateStorage(RelFileLocator rlocator, char relpersistence,
|
|||
bool register_delete)
|
||||
{
|
||||
SMgrRelation srel;
|
||||
BackendId backend;
|
||||
ProcNumber procNumber;
|
||||
bool needs_wal;
|
||||
|
||||
Assert(!IsInParallelMode()); /* couldn't update pendingSyncHash */
|
||||
|
@ -130,15 +130,15 @@ RelationCreateStorage(RelFileLocator rlocator, char relpersistence,
|
|||
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:
|
||||
|
@ -146,7 +146,7 @@ RelationCreateStorage(RelFileLocator rlocator, char relpersistence,
|
|||
return NULL; /* placate compiler */
|
||||
}
|
||||
|
||||
srel = smgropen(rlocator, backend);
|
||||
srel = smgropen(rlocator, procNumber);
|
||||
smgrcreate(srel, MAIN_FORKNUM, false);
|
||||
|
||||
if (needs_wal)
|
||||
|
@ -163,7 +163,7 @@ RelationCreateStorage(RelFileLocator rlocator, char relpersistence,
|
|||
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;
|
||||
|
@ -172,7 +172,7 @@ RelationCreateStorage(RelFileLocator rlocator, char relpersistence,
|
|||
|
||||
if (relpersistence == RELPERSISTENCE_PERMANENT && !XLogIsNeeded())
|
||||
{
|
||||
Assert(backend == InvalidBackendId);
|
||||
Assert(procNumber == INVALID_PROC_NUMBER);
|
||||
AddPendingSync(&rlocator);
|
||||
}
|
||||
|
||||
|
@ -211,7 +211,7 @@ RelationDropStorage(Relation rel)
|
|||
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;
|
||||
|
@ -660,7 +660,7 @@ smgrDoPendingDeletes(bool isCommit)
|
|||
{
|
||||
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)
|
||||
|
@ -741,7 +741,7 @@ smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
|
|||
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.
|
||||
|
@ -860,7 +860,7 @@ smgrGetPendingDeletes(bool forCommit, RelFileLocator **ptr)
|
|||
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)
|
||||
|
@ -873,7 +873,7 @@ smgrGetPendingDeletes(bool forCommit, RelFileLocator **ptr)
|
|||
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++;
|
||||
|
@ -950,7 +950,7 @@ smgr_redo(XLogReaderState *record)
|
|||
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)
|
||||
|
@ -963,7 +963,7 @@ smgr_redo(XLogReaderState *record)
|
|||
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
|
||||
|
|
|
@ -247,7 +247,7 @@ typedef struct QueueBackendStatus
|
|||
{
|
||||
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;
|
||||
|
||||
|
@ -273,13 +273,12 @@ typedef struct 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
|
||||
|
@ -289,10 +288,10 @@ 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;
|
||||
|
@ -491,7 +490,7 @@ AsyncShmemSize(void)
|
|||
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));
|
||||
|
@ -510,11 +509,8 @@ AsyncShmemInit(void)
|
|||
|
||||
/*
|
||||
* 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 *)
|
||||
|
@ -526,14 +522,13 @@ AsyncShmemInit(void)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1050,7 +1045,7 @@ Exec_ListenPreCommit(void)
|
|||
{
|
||||
QueuePosition head;
|
||||
QueuePosition max;
|
||||
BackendId prevListener;
|
||||
ProcNumber prevListener;
|
||||
|
||||
/*
|
||||
* Nothing to do if we are already listening to something, nor if we
|
||||
|
@ -1095,28 +1090,28 @@ Exec_ListenPreCommit(void)
|
|||
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);
|
||||
|
||||
|
@ -1248,23 +1243,23 @@ asyncQueueUnregister(void)
|
|||
*/
|
||||
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 */
|
||||
|
@ -1549,7 +1544,7 @@ asyncQueueFillWarning(void)
|
|||
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));
|
||||
|
@ -1580,7 +1575,7 @@ asyncQueueFillWarning(void)
|
|||
* 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.
|
||||
|
@ -1589,7 +1584,7 @@ static void
|
|||
SignalBackends(void)
|
||||
{
|
||||
int32 *pids;
|
||||
BackendId *ids;
|
||||
ProcNumber *procnos;
|
||||
int count;
|
||||
|
||||
/*
|
||||
|
@ -1601,11 +1596,11 @@ SignalBackends(void)
|
|||
* 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;
|
||||
|
@ -1633,7 +1628,7 @@ SignalBackends(void)
|
|||
}
|
||||
/* OK, need to signal this one */
|
||||
pids[count] = pid;
|
||||
ids[count] = i;
|
||||
procnos[count] = i;
|
||||
count++;
|
||||
}
|
||||
LWLockRelease(NotifyQueueLock);
|
||||
|
@ -1659,12 +1654,12 @@ SignalBackends(void)
|
|||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1872,8 +1867,8 @@ asyncQueueReadAllNotifications(void)
|
|||
/* 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);
|
||||
|
||||
|
@ -1995,7 +1990,7 @@ asyncQueueReadAllNotifications(void)
|
|||
{
|
||||
/* Update shared state */
|
||||
LWLockAcquire(NotifyQueueLock, LW_SHARED);
|
||||
QUEUE_BACKEND_POS(MyBackendId) = pos;
|
||||
QUEUE_BACKEND_POS(MyProcNumber) = pos;
|
||||
LWLockRelease(NotifyQueueLock);
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
@ -2142,7 +2137,7 @@ asyncQueueAdvanceTail(void)
|
|||
*/
|
||||
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));
|
||||
|
|
|
@ -276,7 +276,7 @@ ScanSourceDatabasePgClass(Oid tbid, Oid dbid, char *srcpath)
|
|||
rlocator.dbOid = dbid;
|
||||
rlocator.relNumber = relfilenumber;
|
||||
|
||||
smgr = smgropen(rlocator, InvalidBackendId);
|
||||
smgr = smgropen(rlocator, INVALID_PROC_NUMBER);
|
||||
nblocks = smgrnblocks(smgr, MAIN_FORKNUM);
|
||||
smgrclose(smgr);
|
||||
|
||||
|
|
|
@ -476,7 +476,7 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress)
|
|||
/* 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,
|
||||
|
|
|
@ -343,7 +343,7 @@ fill_seq_with_data(Relation rel, HeapTuple tuple)
|
|||
{
|
||||
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);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
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);
|
||||
|
@ -75,11 +75,11 @@ pq_cleanup_redirect_to_shm_mq(dsm_segment *seg, Datum arg)
|
|||
* 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
|
||||
|
@ -168,13 +168,13 @@ mq_putmessage(char msgtype, const char *s, size_t len)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
/* 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().
|
||||
|
@ -170,7 +170,7 @@ PgArchShmemInit(void)
|
|||
{
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
@ -236,8 +236,8 @@ PgArchiverMain(void)
|
|||
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;
|
||||
|
||||
|
@ -271,7 +271,7 @@ PgArchWakeup(void)
|
|||
* 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);
|
||||
}
|
||||
|
||||
|
@ -741,7 +741,7 @@ pgarch_archiveDone(char *xlog)
|
|||
static void
|
||||
pgarch_die(int code, Datum arg)
|
||||
{
|
||||
PgArch->pgprocno = INVALID_PGPROCNO;
|
||||
PgArch->pgprocno = INVALID_PROC_NUMBER;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -71,8 +71,8 @@ typedef struct
|
|||
* 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
|
||||
|
@ -83,7 +83,7 @@ typedef struct
|
|||
TimeLineID summarized_tli;
|
||||
XLogRecPtr summarized_lsn;
|
||||
bool lsn_is_exact;
|
||||
int summarizer_pgprocno;
|
||||
ProcNumber summarizer_pgprocno;
|
||||
XLogRecPtr pending_lsn;
|
||||
|
||||
/*
|
||||
|
@ -195,7 +195,7 @@ WalSummarizerShmemInit(void)
|
|||
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);
|
||||
}
|
||||
|
@ -444,7 +444,7 @@ GetWalSummarizerState(TimeLineID *summarized_tli, XLogRecPtr *summarized_lsn,
|
|||
|
||||
*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
|
||||
|
@ -613,7 +613,7 @@ GetOldestUnsummarizedLSN(TimeLineID *tli, bool *lsn_is_exact,
|
|||
void
|
||||
SetWalSummarizerLatch(void)
|
||||
{
|
||||
int pgprocno;
|
||||
ProcNumber pgprocno;
|
||||
|
||||
if (WalSummarizerCtl == NULL)
|
||||
return;
|
||||
|
@ -622,7 +622,7 @@ SetWalSummarizerLatch(void)
|
|||
pgprocno = WalSummarizerCtl->summarizer_pgprocno;
|
||||
LWLockRelease(WALSummarizerLock);
|
||||
|
||||
if (pgprocno != INVALID_PGPROCNO)
|
||||
if (pgprocno != INVALID_PROC_NUMBER)
|
||||
SetLatch(&ProcGlobal->allProcs[pgprocno].procLatch);
|
||||
}
|
||||
|
||||
|
@ -683,7 +683,7 @@ static void
|
|||
WalSummarizerShutdown(int code, Datum arg)
|
||||
{
|
||||
LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
|
||||
WalSummarizerCtl->summarizer_pgprocno = INVALID_PGPROCNO;
|
||||
WalSummarizerCtl->summarizer_pgprocno = INVALID_PROC_NUMBER;
|
||||
LWLockRelease(WALSummarizerLock);
|
||||
}
|
||||
|
||||
|
|
|
@ -845,7 +845,7 @@ pa_shutdown(int code, Datum arg)
|
|||
{
|
||||
SendProcSignal(MyLogicalRepWorker->leader_pid,
|
||||
PROCSIG_PARALLEL_APPLY_MESSAGE,
|
||||
InvalidBackendId);
|
||||
INVALID_PROC_NUMBER);
|
||||
|
||||
dsm_detach((dsm_segment *) DatumGetPointer(arg));
|
||||
}
|
||||
|
@ -934,7 +934,7 @@ ParallelApplyWorkerMain(Datum main_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;
|
||||
|
|
|
@ -1651,7 +1651,7 @@ InvalidatePossiblyObsoleteSlot(ReplicationSlotInvalidationCause cause,
|
|||
if (MyBackendType == B_STARTUP)
|
||||
(void) SendProcSignal(active_pid,
|
||||
PROCSIG_RECOVERY_CONFLICT_LOGICALSLOT,
|
||||
InvalidBackendId);
|
||||
INVALID_PROC_NUMBER);
|
||||
else
|
||||
(void) kill(active_pid, SIGTERM);
|
||||
|
||||
|
|
|
@ -3646,7 +3646,7 @@ WalSndInitStopping(void)
|
|||
if (pid == 0)
|
||||
continue;
|
||||
|
||||
SendProcSignal(pid, PROCSIG_WALSND_INIT_STOPPING, InvalidBackendId);
|
||||
SendProcSignal(pid, PROCSIG_WALSND_INIT_STOPPING, INVALID_PROC_NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ InitBufferPool(void)
|
|||
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;
|
||||
|
||||
|
|
|
@ -816,7 +816,7 @@ ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum,
|
|||
* 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,
|
||||
|
@ -825,7 +825,7 @@ 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,
|
||||
|
@ -3322,7 +3322,7 @@ DebugPrintBufferRefcount(Buffer buffer)
|
|||
int32 loccount;
|
||||
char *path;
|
||||
char *result;
|
||||
BackendId backend;
|
||||
ProcNumber backend;
|
||||
uint32 buf_state;
|
||||
|
||||
Assert(BufferIsValid(buffer));
|
||||
|
@ -3330,13 +3330,13 @@ DebugPrintBufferRefcount(Buffer 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 */
|
||||
|
@ -3461,7 +3461,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln, IOObject io_object,
|
|||
|
||||
/* 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,
|
||||
|
@ -3696,7 +3696,7 @@ DropRelationBuffers(SMgrRelation smgr_reln, ForkNumber *forkNum,
|
|||
/* 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],
|
||||
|
@ -3826,7 +3826,7 @@ DropRelationsAllBuffers(SMgrRelation *smgr_reln, int nlocators)
|
|||
{
|
||||
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
|
||||
|
@ -4090,7 +4090,7 @@ PrintBufferDescs(void)
|
|||
"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));
|
||||
}
|
||||
|
@ -4364,7 +4364,7 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator,
|
|||
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. */
|
||||
|
@ -4376,7 +4376,7 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator,
|
|||
* 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. */
|
||||
|
@ -4443,8 +4443,8 @@ CreateAndCopyRelationData(RelFileLocator src_rlocator,
|
|||
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
|
||||
|
@ -5348,7 +5348,7 @@ local_buffer_write_error_callback(void *arg)
|
|||
if (bufHdr != NULL)
|
||||
{
|
||||
char *path = relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
|
||||
MyBackendId,
|
||||
MyProcNumber,
|
||||
BufTagGetForkNum(&bufHdr->tag));
|
||||
|
||||
errcontext("writing block %u of relation %s",
|
||||
|
@ -5653,7 +5653,7 @@ IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ GetLocalVictimBuffer(void)
|
|||
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);
|
||||
|
||||
|
@ -509,7 +509,7 @@ DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber forkNum,
|
|||
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]);
|
||||
|
||||
|
@ -554,7 +554,7 @@ DropRelationAllLocalBuffers(RelFileLocator rlocator)
|
|||
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 */
|
||||
|
|
|
@ -818,9 +818,9 @@ ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid)
|
|||
* 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;
|
||||
|
||||
|
@ -836,7 +836,7 @@ ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid)
|
|||
}
|
||||
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)
|
||||
|
@ -853,13 +853,13 @@ ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid)
|
|||
* 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];
|
||||
|
||||
|
@ -879,12 +879,12 @@ ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid)
|
|||
* 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();
|
||||
|
@ -2538,7 +2538,7 @@ ProcArrayInstallImportedXmin(TransactionId xmin,
|
|||
|
||||
/*
|
||||
* 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++)
|
||||
|
@ -2553,7 +2553,7 @@ ProcArrayInstallImportedXmin(TransactionId xmin,
|
|||
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;
|
||||
|
@ -3105,20 +3105,20 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
|
|||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
@ -3127,15 +3127,15 @@ BackendIdGetProc(int backendID)
|
|||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
@ -3144,9 +3144,9 @@ BackendIdGetTransactionIds(int backendID, TransactionId *xid,
|
|||
*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);
|
||||
|
@ -3453,7 +3453,7 @@ GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
|
|||
LWLockRelease(ProcArrayLock);
|
||||
|
||||
/* add the terminator */
|
||||
vxids[count].backendId = InvalidBackendId;
|
||||
vxids[count].procNumber = INVALID_PROC_NUMBER;
|
||||
vxids[count].localTransactionId = InvalidLocalTransactionId;
|
||||
|
||||
return vxids;
|
||||
|
@ -3488,7 +3488,7 @@ SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode,
|
|||
|
||||
GET_VXID_FROM_PGPROC(procvxid, *proc);
|
||||
|
||||
if (procvxid.backendId == vxid.backendId &&
|
||||
if (procvxid.procNumber == vxid.procNumber &&
|
||||
procvxid.localTransactionId == vxid.localTransactionId)
|
||||
{
|
||||
proc->recoveryConflictPending = conflictPending;
|
||||
|
@ -3499,7 +3499,7 @@ SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode,
|
|||
* 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;
|
||||
}
|
||||
|
@ -3662,7 +3662,7 @@ CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending)
|
|||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,10 +43,10 @@
|
|||
* 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
|
||||
|
@ -83,7 +83,7 @@ typedef struct
|
|||
} 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.)
|
||||
*/
|
||||
|
@ -161,16 +161,16 @@ ProcSignalInit(void)
|
|||
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));
|
||||
|
@ -218,6 +218,7 @@ CleanupProcSignalState(int status, Datum arg)
|
|||
* 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 */
|
||||
|
@ -246,7 +247,7 @@ CleanupProcSignalState(int status, Datum arg)
|
|||
* 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).
|
||||
|
@ -254,13 +255,13 @@ CleanupProcSignalState(int status, Datum arg)
|
|||
* 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
|
||||
|
@ -281,10 +282,11 @@ SendProcSignal(pid_t pid, ProcSignalReason reason, BackendId backendId)
|
|||
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;
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
|
||||
#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"
|
||||
|
@ -155,8 +155,8 @@ typedef struct ProcState
|
|||
|
||||
/*
|
||||
* 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;
|
||||
|
@ -197,7 +197,7 @@ typedef struct SISeg
|
|||
} 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.)
|
||||
*/
|
||||
|
@ -274,15 +274,13 @@ SharedInvalBackendInit(bool sendOnly)
|
|||
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
|
||||
|
@ -296,10 +294,10 @@ SharedInvalBackendInit(bool sendOnly)
|
|||
{
|
||||
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;
|
||||
|
@ -331,16 +329,15 @@ CleanupInvalidationState(int status, Datum arg)
|
|||
{
|
||||
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 */
|
||||
|
@ -351,7 +348,7 @@ CleanupInvalidationState(int status, Datum arg)
|
|||
|
||||
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];
|
||||
|
@ -481,7 +478,7 @@ SIGetDataEntries(SharedInvalidationMessage *data, int datasize)
|
|||
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
|
||||
|
@ -668,13 +665,13 @@ SICleanupQueue(bool callerHasWriteLock, int minFree)
|
|||
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);
|
||||
}
|
||||
|
@ -693,11 +690,11 @@ SICleanupQueue(bool callerHasWriteLock, int minFree)
|
|||
* 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
|
||||
|
|
|
@ -137,8 +137,8 @@ InitRecoveryTransactionEnvironment(void)
|
|||
* 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);
|
||||
|
||||
|
@ -300,7 +300,7 @@ LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start,
|
|||
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)
|
||||
|
|
|
@ -947,7 +947,7 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress)
|
|||
/* 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,
|
||||
|
|
|
@ -2995,7 +2995,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
|
|||
* on this lockable object.
|
||||
*/
|
||||
LWLockRelease(partitionLock);
|
||||
vxids[count].backendId = InvalidBackendId;
|
||||
vxids[count].procNumber = INVALID_PROC_NUMBER;
|
||||
vxids[count].localTransactionId = InvalidLocalTransactionId;
|
||||
if (countp)
|
||||
*countp = count;
|
||||
|
@ -3041,7 +3041,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
|
|||
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;
|
||||
|
@ -3625,7 +3625,7 @@ GetLockStatusData(void)
|
|||
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;
|
||||
|
@ -3652,14 +3652,14 @@ GetLockStatusData(void)
|
|||
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;
|
||||
|
@ -3712,7 +3712,7 @@ GetLockStatusData(void)
|
|||
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;
|
||||
|
@ -3888,7 +3888,7 @@ GetSingleProcBlockerStatusData(PGPROC *blocked_proc, BlockedProcsData *data)
|
|||
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;
|
||||
|
@ -4391,7 +4391,7 @@ VirtualXactLockTableInsert(VirtualTransactionId vxid)
|
|||
|
||||
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);
|
||||
|
||||
|
@ -4413,7 +4413,7 @@ VirtualXactLockTableCleanup(void)
|
|||
bool fastpath;
|
||||
LocalTransactionId lxid;
|
||||
|
||||
Assert(MyProc->vxid.backendId != InvalidBackendId);
|
||||
Assert(MyProc->vxid.procNumber != INVALID_PROC_NUMBER);
|
||||
|
||||
/*
|
||||
* Clean up shared memory state.
|
||||
|
@ -4436,7 +4436,7 @@ VirtualXactLockTableCleanup(void)
|
|||
VirtualTransactionId vxid;
|
||||
LOCKTAG locktag;
|
||||
|
||||
vxid.backendId = MyBackendId;
|
||||
vxid.procNumber = MyProcNumber;
|
||||
vxid.localTransactionId = lxid;
|
||||
SET_LOCKTAG_VIRTUALTRANSACTION(locktag, vxid);
|
||||
|
||||
|
@ -4530,18 +4530,18 @@ VirtualXactLock(VirtualTransactionId vxid, bool wait)
|
|||
* 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 */
|
||||
|
|
|
@ -1260,7 +1260,7 @@ InitPredicateLocks(void)
|
|||
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;
|
||||
|
@ -4846,7 +4846,7 @@ PostPrepare_PredicateLocks(TransactionId xid)
|
|||
Assert(SxactIsPrepared(MySerializableXact));
|
||||
|
||||
MySerializableXact->pid = 0;
|
||||
MySerializableXact->pgprocno = INVALID_PGPROCNO;
|
||||
MySerializableXact->pgprocno = INVALID_PROC_NUMBER;
|
||||
|
||||
hash_destroy(LocalPredicateLockHash);
|
||||
LocalPredicateLockHash = NULL;
|
||||
|
@ -4918,11 +4918,11 @@ predicatelock_twophase_recover(TransactionId xid, uint16 info,
|
|||
(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;
|
||||
|
|
|
@ -66,7 +66,6 @@ bool log_lock_waits = false;
|
|||
|
||||
/* 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.
|
||||
|
@ -181,8 +180,8 @@ InitProcGlobal(void)
|
|||
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
|
||||
|
@ -275,8 +274,8 @@ InitProcGlobal(void)
|
|||
* 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);
|
||||
}
|
||||
|
||||
|
@ -355,7 +354,6 @@ InitProcess(void)
|
|||
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
|
||||
|
@ -387,7 +385,7 @@ InitProcess(void)
|
|||
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;
|
||||
|
@ -423,7 +421,7 @@ InitProcess(void)
|
|||
/* 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);
|
||||
|
@ -438,7 +436,7 @@ InitProcess(void)
|
|||
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
|
||||
|
@ -573,7 +571,6 @@ InitAuxiliaryProcess(void)
|
|||
|
||||
MyProc = auxproc;
|
||||
MyProcNumber = GetNumberFromPGProc(MyProc);
|
||||
MyBackendId = GetBackendIdFromPGProc(MyProc);
|
||||
|
||||
/*
|
||||
* Initialize all fields of MyProc, except for those previously
|
||||
|
@ -585,7 +582,7 @@ InitAuxiliaryProcess(void)
|
|||
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;
|
||||
|
@ -916,13 +913,12 @@ ProcKill(int code, Datum arg)
|
|||
|
||||
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;
|
||||
|
@ -998,15 +994,14 @@ AuxiliaryProcKill(int code, Datum arg)
|
|||
|
||||
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 */
|
||||
|
@ -1863,15 +1858,15 @@ ProcWaitForSignal(uint32 wait_event_info)
|
|||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1454,7 +1454,7 @@ DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo)
|
|||
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)
|
||||
{
|
||||
|
@ -1738,7 +1738,7 @@ _mdnblocks(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg)
|
|||
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;
|
||||
|
|
|
@ -196,7 +196,7 @@ smgrshutdown(int code, Datum arg)
|
|||
* 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;
|
||||
|
|
|
@ -238,7 +238,7 @@ CreateSharedBackendStatus(void)
|
|||
|
||||
/*
|
||||
* 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).
|
||||
*
|
||||
|
@ -248,9 +248,9 @@ void
|
|||
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);
|
||||
|
@ -721,7 +721,7 @@ pgstat_read_current_status(void)
|
|||
#ifdef ENABLE_GSS
|
||||
PgBackendGSSStatus *localgssstatus;
|
||||
#endif
|
||||
int i;
|
||||
ProcNumber procNumber;
|
||||
|
||||
if (localBackendStatusTable)
|
||||
return; /* already done */
|
||||
|
@ -764,7 +764,7 @@ pgstat_read_current_status(void)
|
|||
|
||||
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
|
||||
|
@ -830,17 +830,17 @@ pgstat_read_current_status(void)
|
|||
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;
|
||||
|
@ -1043,7 +1043,7 @@ pgstat_get_my_query_id(void)
|
|||
* 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
|
||||
|
@ -1052,17 +1052,17 @@ cmp_lbestatus(const void *a, const void *b)
|
|||
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
|
||||
|
@ -1070,9 +1070,9 @@ cmp_lbestatus(const void *a, const void *b)
|
|||
* ----------
|
||||
*/
|
||||
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;
|
||||
|
@ -1082,12 +1082,12 @@ pgstat_get_beentry_by_backend_id(BackendId beid)
|
|||
|
||||
|
||||
/* ----------
|
||||
* 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
|
||||
|
@ -1095,7 +1095,7 @@ pgstat_get_beentry_by_backend_id(BackendId beid)
|
|||
* ----------
|
||||
*/
|
||||
LocalPgBackendStatus *
|
||||
pgstat_get_local_beentry_by_backend_id(BackendId beid)
|
||||
pgstat_get_local_beentry_by_proc_number(ProcNumber procNumber)
|
||||
{
|
||||
LocalPgBackendStatus key;
|
||||
|
||||
|
@ -1105,7 +1105,7 @@ pgstat_get_local_beentry_by_backend_id(BackendId beid)
|
|||
* 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);
|
||||
}
|
||||
|
|
|
@ -306,7 +306,7 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS)
|
|||
* 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;
|
||||
|
@ -951,7 +951,7 @@ pg_relation_filepath(PG_FUNCTION_ARGS)
|
|||
HeapTuple tuple;
|
||||
Form_pg_class relform;
|
||||
RelFileLocator rlocator;
|
||||
BackendId backend;
|
||||
ProcNumber backend;
|
||||
char *path;
|
||||
|
||||
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
|
||||
|
@ -996,21 +996,21 @@ pg_relation_filepath(PG_FUNCTION_ARGS)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,15 +73,16 @@ typedef struct
|
|||
* 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);
|
||||
}
|
||||
|
@ -353,7 +354,7 @@ pg_lock_status(PG_FUNCTION_ARGS)
|
|||
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
|
||||
|
@ -419,7 +420,7 @@ pg_lock_status(PG_FUNCTION_ARGS)
|
|||
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);
|
||||
|
|
|
@ -146,7 +146,7 @@ pg_log_backend_memory_contexts(PG_FUNCTION_ARGS)
|
|||
{
|
||||
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.
|
||||
|
@ -175,9 +175,8 @@ pg_log_backend_memory_contexts(PG_FUNCTION_ARGS)
|
|||
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,
|
||||
|
|
|
@ -213,7 +213,7 @@ pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
|
|||
/* 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
|
||||
{
|
||||
|
@ -669,10 +669,10 @@ pg_backend_pid(PG_FUNCTION_ARGS)
|
|||
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);
|
||||
|
@ -682,10 +682,10 @@ pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
|
|||
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);
|
||||
|
@ -695,10 +695,10 @@ pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
|
|||
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);
|
||||
|
@ -711,7 +711,7 @@ pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
|
|||
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 */
|
||||
|
@ -723,7 +723,7 @@ pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
|
|||
|
||||
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);
|
||||
|
@ -742,13 +742,13 @@ pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
|
|||
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>";
|
||||
|
@ -767,12 +767,12 @@ pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
|
|||
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>";
|
||||
|
@ -788,12 +788,12 @@ pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
|
|||
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>";
|
||||
|
@ -810,11 +810,11 @@ pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
|
|||
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))
|
||||
|
@ -836,11 +836,11 @@ pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
|
|||
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))
|
||||
|
@ -858,11 +858,11 @@ pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
|
|||
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))
|
||||
|
@ -880,13 +880,13 @@ pg_stat_get_backend_start(PG_FUNCTION_ARGS)
|
|||
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))
|
||||
|
@ -925,13 +925,13 @@ pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
|
|||
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))
|
||||
|
|
|
@ -1453,8 +1453,8 @@ CacheInvalidateRelcacheByRelid(Oid relid)
|
|||
* 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)
|
||||
|
|
|
@ -1144,13 +1144,13 @@ retry:
|
|||
{
|
||||
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
|
||||
|
@ -1159,18 +1159,18 @@ retry:
|
|||
* 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;
|
||||
|
@ -1896,7 +1896,7 @@ formrdesc(const char *relationName, Oid relationReltype,
|
|||
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;
|
||||
|
||||
/*
|
||||
|
@ -3611,12 +3611,12 @@ RelationBuildLocalRelation(const char *relname,
|
|||
{
|
||||
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:
|
||||
|
|
|
@ -152,8 +152,8 @@ write_csvlog(ErrorData *edata)
|
|||
|
||||
/* 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 */
|
||||
|
|
|
@ -3076,18 +3076,18 @@ log_status_format(StringInfo buf, const char *format, ErrorData *edata)
|
|||
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,
|
||||
|
|
|
@ -197,9 +197,9 @@ write_jsonlog(ErrorData *edata)
|
|||
|
||||
/* 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",
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "libpq/libpq-be.h"
|
||||
#include "libpq/pqcomm.h"
|
||||
#include "miscadmin.h"
|
||||
#include "storage/backendid.h"
|
||||
#include "storage/procnumber.h"
|
||||
|
||||
|
||||
ProtocolVersion FrontendProtocol;
|
||||
|
@ -83,9 +83,9 @@ char postgres_exec_path[MAXPGPATH]; /* full path to backend */
|
|||
/* 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;
|
||||
|
||||
|
|
|
@ -1154,7 +1154,7 @@ ExportSnapshot(Snapshot snapshot)
|
|||
* 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);
|
||||
|
||||
/*
|
||||
|
@ -1182,7 +1182,7 @@ ExportSnapshot(Snapshot snapshot)
|
|||
*/
|
||||
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);
|
||||
|
@ -1352,7 +1352,7 @@ parseVxidFromText(const char *prefix, char **s, const char *filename,
|
|||
(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)));
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "catalog/pg_tablespace_d.h"
|
||||
#include "common/relpath.h"
|
||||
#include "storage/backendid.h"
|
||||
#include "storage/procnumber.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -133,13 +133,13 @@ GetDatabasePath(Oid dbOid, Oid spcOid)
|
|||
*
|
||||
* 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;
|
||||
|
||||
|
@ -147,7 +147,7 @@ GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
|
|||
{
|
||||
/* 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]);
|
||||
|
@ -157,7 +157,7 @@ GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
|
|||
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",
|
||||
|
@ -171,17 +171,17 @@ GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
|
|||
{
|
||||
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",
|
||||
|
@ -198,12 +198,12 @@ GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
|
|||
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;
|
||||
|
|
|
@ -37,7 +37,7 @@ extern void PostPrepare_Twophase(void);
|
|||
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,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "nodes/primnodes.h"
|
||||
#include "storage/lock.h"
|
||||
#include "storage/procnumber.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -156,7 +157,7 @@ extern bool isTempOrTempToastNamespace(Oid namespaceId);
|
|||
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);
|
||||
|
|
|
@ -74,7 +74,7 @@ extern int forkname_chars(const char *str, ForkNumber *fork);
|
|||
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
|
||||
|
@ -88,7 +88,7 @@ extern char *GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
|
|||
|
||||
/* 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) \
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#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);
|
||||
|
||||
|
|
|
@ -203,11 +203,6 @@ extern PGDLLIMPORT char pkglib_path[];
|
|||
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;
|
||||
|
|
|
@ -72,7 +72,7 @@ extern void ShmemBackendArrayAllocation(void);
|
|||
* 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().
|
||||
*/
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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 */
|
|
@ -19,9 +19,9 @@
|
|||
#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"
|
||||
|
||||
|
@ -42,7 +42,7 @@ extern PGDLLIMPORT bool Debug_deadlocks;
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
@ -50,7 +50,7 @@ extern PGDLLIMPORT bool Debug_deadlocks;
|
|||
*
|
||||
* 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
|
||||
|
@ -58,7 +58,7 @@ extern PGDLLIMPORT bool Debug_deadlocks;
|
|||
*/
|
||||
typedef struct
|
||||
{
|
||||
BackendId backendId; /* backendId from PGPROC */
|
||||
ProcNumber procNumber; /* proc number of the PGPROC */
|
||||
LocalTransactionId localTransactionId; /* lxid from PGPROC */
|
||||
} VirtualTransactionId;
|
||||
|
||||
|
@ -67,15 +67,15 @@ typedef struct
|
|||
#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 */
|
||||
|
@ -233,7 +233,7 @@ typedef struct LOCKTAG
|
|||
|
||||
/* 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, \
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#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
|
||||
|
@ -84,12 +85,6 @@ struct XidCache
|
|||
*/
|
||||
#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
|
||||
*
|
||||
|
@ -199,11 +194,11 @@ struct PGPROC
|
|||
*/
|
||||
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
|
||||
|
@ -317,7 +312,19 @@ struct PGPROC
|
|||
|
||||
|
||||
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.
|
||||
|
@ -422,15 +429,10 @@ extern PGDLLIMPORT PROC_HDR *ProcGlobal;
|
|||
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,
|
||||
|
@ -477,7 +479,7 @@ extern bool IsWaitingForLock(void);
|
|||
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);
|
||||
|
||||
|
|
|
@ -64,10 +64,10 @@ extern VirtualTransactionId *GetVirtualXIDsDelayingChkpt(int *nvxids, int type);
|
|||
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);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
static inline void
|
||||
proclist_init(proclist_head *list)
|
||||
{
|
||||
list->head = list->tail = INVALID_PGPROCNO;
|
||||
list->head = list->tail = INVALID_PROC_NUMBER;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -37,7 +37,7 @@ proclist_init(proclist_head *list)
|
|||
static inline bool
|
||||
proclist_is_empty(const proclist_head *list)
|
||||
{
|
||||
return list->head == INVALID_PGPROCNO;
|
||||
return list->head == INVALID_PROC_NUMBER;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -62,20 +62,20 @@ proclist_push_head_offset(proclist_head *list, int procno, size_t node_offset)
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -90,20 +90,20 @@ proclist_push_tail_offset(proclist_head *list, int procno, size_t node_offset)
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ proclist_delete_offset(proclist_head *list, int procno, size_t node_offset)
|
|||
|
||||
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;
|
||||
|
@ -126,7 +126,7 @@ proclist_delete_offset(proclist_head *list, int procno, size_t node_offset)
|
|||
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;
|
||||
|
@ -160,8 +160,8 @@ proclist_contains_offset(const proclist_head *list, int procno,
|
|||
* 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;
|
||||
}
|
||||
|
@ -207,12 +207,12 @@ proclist_pop_head_node_offset(proclist_head *list, size_t node_offset)
|
|||
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)
|
||||
|
||||
|
|
|
@ -15,28 +15,30 @@
|
|||
#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;
|
||||
|
||||
/*
|
||||
|
@ -44,8 +46,8 @@ typedef struct 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 */
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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 */
|
|
@ -14,7 +14,7 @@
|
|||
#ifndef PROCSIGNAL_H
|
||||
#define PROCSIGNAL_H
|
||||
|
||||
#include "storage/backendid.h"
|
||||
#include "storage/procnumber.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -64,7 +64,7 @@ extern void ProcSignalShmemInit(void);
|
|||
|
||||
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);
|
||||
|
|
|
@ -15,14 +15,15 @@
|
|||
#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.
|
||||
|
@ -62,28 +63,28 @@ typedef struct RelFileLocator
|
|||
} 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 && \
|
||||
|
|
|
@ -88,8 +88,8 @@ typedef struct
|
|||
{
|
||||
/* 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;
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ typedef SMgrRelationData *SMgrRelation;
|
|||
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);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#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"
|
||||
|
||||
|
||||
|
@ -87,7 +87,7 @@ typedef struct PgBackendGSSStatus
|
|||
*
|
||||
* 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
|
||||
|
@ -250,11 +250,9 @@ typedef struct LocalPgBackendStatus
|
|||
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
|
||||
|
@ -333,8 +331,8 @@ extern uint64 pgstat_get_my_query_id(void);
|
|||
* ----------
|
||||
*/
|
||||
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);
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ typedef struct RelationData
|
|||
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 */
|
||||
|
|
Loading…
Reference in New Issue