static bool SerialPagePrecedesLogically(int64 page1, int64 page2);
static int serial_errdetail_for_io_error(const void *opaque_data);
-static void SerialInit(void);
static void SerialAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo);
static SerCommitSeqNo SerialGetMinConflictCommitSeqNo(TransactionId xid);
static void SerialSetActiveSerXmin(TransactionId xid);
}
#endif
-/*
- * Initialize for the tracking of old serializable committed xids.
- */
-static void
-SerialInit(void)
-{
- bool found;
-
- /*
- * Set up SLRU management of the pg_serial data.
- */
- SerialSlruCtl->PagePrecedes = SerialPagePrecedesLogically;
- SerialSlruCtl->errdetail_for_io_error = serial_errdetail_for_io_error;
- SimpleLruInit(SerialSlruCtl, "serializable",
- serializable_buffers, 0, "pg_serial",
- LWTRANCHE_SERIAL_BUFFER, LWTRANCHE_SERIAL_SLRU,
- SYNC_HANDLER_NONE, false);
-#ifdef USE_ASSERT_CHECKING
- SerialPagePrecedesLogicallyUnitTests();
-#endif
- SlruPagePrecedesUnitTests(SerialSlruCtl, SERIAL_ENTRIESPERPAGE);
-
- /*
- * Create or attach to the SerialControl structure.
- */
- serialControl = (SerialControl)
- ShmemInitStruct("SerialControlData", sizeof(SerialControlData), &found);
-
- Assert(found == IsUnderPostmaster);
- if (!found)
- {
- /*
- * Set control information to reflect empty SLRU.
- */
- LWLockAcquire(SerialControlLock, LW_EXCLUSIVE);
- serialControl->headPage = -1;
- serialControl->headXid = InvalidTransactionId;
- serialControl->tailXid = InvalidTransactionId;
- LWLockRelease(SerialControlLock);
- }
-}
-
/*
* GUC check_hook for serializable_buffers
*/
HASH_ELEM | HASH_BLOBS |
HASH_PARTITION | HASH_FIXED_SIZE);
- /*
- * Reserve a dummy entry in the hash table; we use it to make sure there's
- * always one entry available when we need to split or combine a page,
- * because running out of space there could mean aborting a
- * non-serializable transaction.
- */
- if (!IsUnderPostmaster)
- {
- (void) hash_search(PredicateLockTargetHash, &ScratchTargetTag,
- HASH_ENTER, &found);
- Assert(!found);
- }
-
/* Pre-calculate the hash and partition lock of the scratch entry */
ScratchTargetTagHash = PredicateLockTargetTagHashCode(&ScratchTargetTag);
ScratchPartitionLock = PredicateLockHashPartitionLock(ScratchTargetTagHash);
requestSize,
&found);
Assert(found == IsUnderPostmaster);
- if (!found)
- {
- int i;
-
- /* clean everything, both the header and the element */
- memset(PredXact, 0, requestSize);
-
- dlist_init(&PredXact->availableList);
- dlist_init(&PredXact->activeList);
- PredXact->SxactGlobalXmin = InvalidTransactionId;
- PredXact->SxactGlobalXminCount = 0;
- PredXact->WritableSxactCount = 0;
- PredXact->LastSxactCommitSeqNo = FirstNormalSerCommitSeqNo - 1;
- PredXact->CanPartialClearThrough = 0;
- PredXact->HavePartialClearedThrough = 0;
- PredXact->element
- = (SERIALIZABLEXACT *) ((char *) PredXact + PredXactListDataSize);
- /* Add all elements to available list, clean. */
- for (i = 0; i < max_serializable_xacts; i++)
- {
- LWLockInitialize(&PredXact->element[i].perXactPredicateListLock,
- LWTRANCHE_PER_XACT_PREDICATE_LIST);
- dlist_push_tail(&PredXact->availableList, &PredXact->element[i].xactLink);
- }
- PredXact->OldCommittedSxact = CreatePredXact();
- SetInvalidVirtualTransactionId(PredXact->OldCommittedSxact->vxid);
- PredXact->OldCommittedSxact->prepareSeqNo = 0;
- PredXact->OldCommittedSxact->commitSeqNo = 0;
- PredXact->OldCommittedSxact->SeqNo.lastCommitBeforeSnapshot = 0;
- dlist_init(&PredXact->OldCommittedSxact->outConflicts);
- dlist_init(&PredXact->OldCommittedSxact->inConflicts);
- dlist_init(&PredXact->OldCommittedSxact->predicateLocks);
- dlist_node_init(&PredXact->OldCommittedSxact->finishedLink);
- dlist_init(&PredXact->OldCommittedSxact->possibleUnsafeConflicts);
- PredXact->OldCommittedSxact->topXid = InvalidTransactionId;
- PredXact->OldCommittedSxact->finishedBefore = InvalidTransactionId;
- PredXact->OldCommittedSxact->xmin = InvalidTransactionId;
- PredXact->OldCommittedSxact->flags = SXACT_FLAG_COMMITTED;
- PredXact->OldCommittedSxact->pid = 0;
- PredXact->OldCommittedSxact->pgprocno = INVALID_PROC_NUMBER;
- }
- /* This never changes, so let's keep a local copy. */
- OldCommittedSxact = PredXact->OldCommittedSxact;
/*
* Allocate hash table for SERIALIZABLEXID structs. This stores per-xid
requestSize,
&found);
Assert(found == IsUnderPostmaster);
- if (!found)
- {
- int i;
-
- /* clean everything, including the elements */
- memset(RWConflictPool, 0, requestSize);
-
- dlist_init(&RWConflictPool->availableList);
- RWConflictPool->element = (RWConflict) ((char *) RWConflictPool +
- RWConflictPoolHeaderDataSize);
- /* Add all elements to available list, clean. */
- for (i = 0; i < max_rw_conflicts; i++)
- {
- dlist_push_tail(&RWConflictPool->availableList,
- &RWConflictPool->element[i].outLink);
- }
- }
/*
* Create or attach to the header for the list of finished serializable
sizeof(dlist_head),
&found);
Assert(found == IsUnderPostmaster);
- if (!found)
- dlist_init(FinishedSerializableTransactions);
/*
* Initialize the SLRU storage for old committed serializable
* transactions.
*/
- SerialInit();
+ SerialSlruCtl->PagePrecedes = SerialPagePrecedesLogically;
+ SerialSlruCtl->errdetail_for_io_error = serial_errdetail_for_io_error;
+ SimpleLruInit(SerialSlruCtl, "serializable",
+ serializable_buffers, 0, "pg_serial",
+ LWTRANCHE_SERIAL_BUFFER, LWTRANCHE_SERIAL_SLRU,
+ SYNC_HANDLER_NONE, false);
+#ifdef USE_ASSERT_CHECKING
+ SerialPagePrecedesLogicallyUnitTests();
+#endif
+ SlruPagePrecedesUnitTests(SerialSlruCtl, SERIAL_ENTRIESPERPAGE);
+
+ /*
+ * Create or attach to the SerialControl structure.
+ */
+ serialControl = (SerialControl)
+ ShmemInitStruct("SerialControlData", sizeof(SerialControlData), &found);
+ Assert(found == IsUnderPostmaster);
+
+ /*
+ * If we just attached to existing shared memory (EXEC_BACKEND), we're all
+ * done. Otherwise, during postmaster startup, proceed to initialize all
+ * the shared memory areas that we allocated.
+ */
+ if (IsUnderPostmaster)
+ {
+ /* This never changes, so let's keep a local copy. */
+ OldCommittedSxact = PredXact->OldCommittedSxact;
+ return;
+ }
+
+ /*
+ * Reserve a dummy entry in the hash table; we use it to make sure there's
+ * always one entry available when we need to split or combine a page,
+ * because running out of space there could mean aborting a
+ * non-serializable transaction.
+ */
+ (void) hash_search(PredicateLockTargetHash, &ScratchTargetTag,
+ HASH_ENTER, &found);
+ Assert(!found);
+
+ /* Initialize PredXact list */
+ dlist_init(&PredXact->availableList);
+ dlist_init(&PredXact->activeList);
+ PredXact->SxactGlobalXmin = InvalidTransactionId;
+ PredXact->SxactGlobalXminCount = 0;
+ PredXact->WritableSxactCount = 0;
+ PredXact->LastSxactCommitSeqNo = FirstNormalSerCommitSeqNo - 1;
+ PredXact->CanPartialClearThrough = 0;
+ PredXact->HavePartialClearedThrough = 0;
+ PredXact->element
+ = (SERIALIZABLEXACT *) ((char *) PredXact + PredXactListDataSize);
+ /* Add all elements to available list, clean. */
+ for (int i = 0; i < max_serializable_xacts; i++)
+ {
+ LWLockInitialize(&PredXact->element[i].perXactPredicateListLock,
+ LWTRANCHE_PER_XACT_PREDICATE_LIST);
+ dlist_push_tail(&PredXact->availableList, &PredXact->element[i].xactLink);
+ }
+ PredXact->OldCommittedSxact = CreatePredXact();
+ SetInvalidVirtualTransactionId(PredXact->OldCommittedSxact->vxid);
+ PredXact->OldCommittedSxact->prepareSeqNo = 0;
+ PredXact->OldCommittedSxact->commitSeqNo = 0;
+ PredXact->OldCommittedSxact->SeqNo.lastCommitBeforeSnapshot = 0;
+ dlist_init(&PredXact->OldCommittedSxact->outConflicts);
+ dlist_init(&PredXact->OldCommittedSxact->inConflicts);
+ dlist_init(&PredXact->OldCommittedSxact->predicateLocks);
+ dlist_node_init(&PredXact->OldCommittedSxact->finishedLink);
+ dlist_init(&PredXact->OldCommittedSxact->possibleUnsafeConflicts);
+ PredXact->OldCommittedSxact->topXid = InvalidTransactionId;
+ PredXact->OldCommittedSxact->finishedBefore = InvalidTransactionId;
+ PredXact->OldCommittedSxact->xmin = InvalidTransactionId;
+ PredXact->OldCommittedSxact->flags = SXACT_FLAG_COMMITTED;
+ PredXact->OldCommittedSxact->pid = 0;
+ PredXact->OldCommittedSxact->pgprocno = INVALID_PROC_NUMBER;
+
+ /* This never changes, so let's keep a local copy. */
+ OldCommittedSxact = PredXact->OldCommittedSxact;
+
+ /* Initialize the rw-conflict pool */
+ dlist_init(&RWConflictPool->availableList);
+ RWConflictPool->element = (RWConflict) ((char *) RWConflictPool +
+ RWConflictPoolHeaderDataSize);
+ /* Add all elements to available list, clean. */
+ for (int i = 0; i < max_rw_conflicts; i++)
+ {
+ dlist_push_tail(&RWConflictPool->availableList,
+ &RWConflictPool->element[i].outLink);
+ }
+
+ /* Initialize the list of finished serializable transactions */
+ dlist_init(FinishedSerializableTransactions);
+
+ /* Initialize SerialControl to reflect empty SLRU. */
+ LWLockAcquire(SerialControlLock, LW_EXCLUSIVE);
+ serialControl->headPage = -1;
+ serialControl->headXid = InvalidTransactionId;
+ serialControl->tailXid = InvalidTransactionId;
+ LWLockRelease(SerialControlLock);
}
/*