mirror of
https://github.com/postgres/postgres.git
synced 2025-11-25 12:03:53 +03:00
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:
@@ -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 */
|
||||
|
||||
43
src/include/storage/procnumber.h
Normal file
43
src/include/storage/procnumber.h
Normal file
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user