/* * NOTE: The ProcArrayLock must already be held. */ void LocalDistribXact_StartOnMaster( DistributedTransactionTimeStamp newDistribTimeStamp, DistributedTransactionId newDistribXid, TransactionId *newLocalXid, LocalDistribXactData *masterLocalDistribXactRef) { LocalDistribXactData *ele = masterLocalDistribXactRef; TransactionId localXid; Assert(newDistribTimeStamp != 0); Assert(newDistribXid != InvalidDistributedTransactionId); Assert(newLocalXid != NULL); Assert(masterLocalDistribXactRef != NULL); localXid = GetNewTransactionId(false, false); // NOT subtrans, DO NOT Set PROC struct xid; ele->distribTimeStamp = newDistribTimeStamp; ele->distribXid = newDistribXid; ele->state = LOCALDISTRIBXACT_STATE_ACTIVE; MyProc->xid = localXid; *newLocalXid = localXid; }
void LocalDistribXact_StartOnSegment( DistributedTransactionTimeStamp newDistribTimeStamp, DistributedTransactionId newDistribXid, TransactionId *newLocalXid) { LocalDistribXactData *ele = &MyProc->localDistribXactData; TransactionId localXid; MIRRORED_LOCK_DECLARE; Assert(newDistribTimeStamp != 0); Assert(newDistribXid != InvalidDistributedTransactionId); Assert(newLocalXid != NULL); MIRRORED_LOCK; LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); localXid = GetNewTransactionId(false, false); // NOT subtrans, DO NOT Set PROC struct xid; ele->distribTimeStamp = newDistribTimeStamp; ele->distribXid = newDistribXid; ele->state = LOCALDISTRIBXACT_STATE_ACTIVE; MyProc->xid = localXid; *newLocalXid = localXid; LWLockRelease(ProcArrayLock); MIRRORED_UNLOCK; }
/* * StartTransaction */ static void StartTransaction(void) { TransactionState s = CurrentTransactionState; /* * check the current transaction state */ if (s->state != TRANS_DEFAULT) elog(WARNING, "StartTransaction and not in default state"); /* * set the current transaction state information appropriately during * start processing */ s->state = TRANS_START; /* * Make sure we've freed any old snapshot, and reset xact state variables */ FreeXactSnapshot(); XactIsoLevel = DefaultXactIsoLevel; XactReadOnly = DefaultXactReadOnly; /* * generate a new transaction id */ s->transactionIdData = GetNewTransactionId(); XactLockTableInsert(s->transactionIdData); /* * initialize current transaction state fields */ s->commandId = FirstCommandId; s->startTime = GetCurrentAbsoluteTimeUsec(&(s->startTimeUsec)); /* * initialize the various transaction subsystems */ AtStart_Memory(); AtStart_Cache(); AtStart_Locks(); /* * Tell the trigger manager to we're starting a transaction */ DeferredTriggerBeginXact(); /* * done with start processing, set current transaction state to "in * progress" */ s->state = TRANS_INPROGRESS; }
/* * Add local XID for any new distributed transactions. */ void PreallocLocalXidsForOpenDistributedTransactions(DistributedTransactionId *gxidArray, uint32 count) { int i; DistributedTransactionId gxid; int pageno; int entryno; int slotno; DISTRIBUTEDXIDMAP_ENTRY *ptr; LWLockAcquire(DistributedXidMapControlLock, LW_EXCLUSIVE); for (i = 0; i < count; i++) { gxid = gxidArray[i]; pageno = DistributedTransactionIdToPage(gxid); entryno = DistributedTransactionIdToEntry(gxid); elog((Debug_print_full_dtm ? LOG : DEBUG5), "PreallocLocalXidsForOpenDistributedTransactions: gxidArray[%d] is %u (pageno %d, entryno %d)", i, gxid, pageno, entryno); if (pageno > *shmDistributedXidMapHighestPageNo) { /* * Zero out the new page(s). */ DistributedXidMapMakeMorePages(pageno); } if (*shmMaxDistributedXid < gxid) { *shmMaxDistributedXid = gxid; } slotno = SimpleLruReadPage(DistributedXidMapCtl, pageno, InvalidTransactionId); ptr = (DISTRIBUTEDXIDMAP_ENTRY *) DistributedXidMapCtl->shared->page_buffer[slotno]; ptr += entryno; if (ptr->state == DISTRIBUTEDXIDMAP_STATE_NONE) { ptr->state = DISTRIBUTEDXIDMAP_STATE_PREALLOC_FOR_OPEN_TRANS; ptr->pid = MyProcPid; ptr->xid = GetNewTransactionId(false, false); // NOT subtrans, DO NOT Set PROC struct xid DistributedXidMapCtl->shared->page_dirty[slotno] = true; elog((Debug_print_full_dtm ? LOG : DEBUG5), "PreallocLocalXidsForOpenDistributedTransactions: Allocated local XID = %u for global XID = %u", ptr->xid, gxid); } } LWLockRelease(DistributedXidMapControlLock); }
/* * Get the local XID associated with a distributed transaction. We will * allocate the local XID and assign its value in the map if necessary. */ void AllocOrGetLocalXidForStartDistributedTransaction(DistributedTransactionId gxid, TransactionId *xid) { int pageno = DistributedTransactionIdToPage(gxid); int entryno = DistributedTransactionIdToEntry(gxid); int slotno; DISTRIBUTEDXIDMAP_ENTRY *ptr; Assert(gxid != InvalidDistributedTransactionId); Assert(xid != NULL); elog((Debug_print_full_dtm ? LOG : DEBUG5), "Entering AllocOrGetLocalXidForStartDistributedTransaction with distributed xid = %d (pageno = %d, entryno = %d, DistributedXidMapHighestPageNo = %d)", gxid, pageno, entryno, *shmDistributedXidMapHighestPageNo); LWLockAcquire(DistributedXidMapControlLock, LW_EXCLUSIVE); if (pageno > *shmDistributedXidMapHighestPageNo) { /* * Zero out the new page(s). */ DistributedXidMapMakeMorePages(pageno); } if (*shmMaxDistributedXid < gxid) { *shmMaxDistributedXid = gxid; } slotno = SimpleLruReadPage(DistributedXidMapCtl, pageno, InvalidTransactionId); ptr = (DISTRIBUTEDXIDMAP_ENTRY *) DistributedXidMapCtl->shared->page_buffer[slotno]; ptr += entryno; if (ptr->state == DISTRIBUTEDXIDMAP_STATE_NONE) { /* * Need to allocate a local XID and assign the map entry. */ *xid = GetNewTransactionId(false, false); // NOT subtrans, DO NOT Set PROC struct xid ptr->state = DISTRIBUTEDXIDMAP_STATE_IN_PROGRESS; ptr->pid = MyProcPid; ptr->xid = *xid; elog((Debug_print_full_dtm ? LOG : DEBUG5), "AllocOrGetLocalXidForStartDistributedTransaction allocated local XID = %d", *xid); DistributedXidMapCtl->shared->page_dirty[slotno] = true; } else if (ptr->state == DISTRIBUTEDXIDMAP_STATE_PREALLOC_FOR_OPEN_TRANS) { /* * The local XID was pre-allocated by another QE when it * received a distributed snapshot that listed the distributed transaction * in its in-doubt list. */ ptr->state = DISTRIBUTEDXIDMAP_STATE_IN_PROGRESS; ptr->pid = MyProcPid; *xid = ptr->xid; elog((Debug_print_full_dtm ? LOG : DEBUG5), "AllocOrGetLocalXidForStartDistributedTransaction found pre-allocated local XID = %d", *xid); DistributedXidMapCtl->shared->page_dirty[slotno] = true; } else { int pid = ptr->pid; TransactionId reuseXid = ptr->xid; DistributedMapState state = ptr->state; LWLockRelease(DistributedXidMapControlLock); elog(ERROR,"Attempting re-use local xid %u and distributed xid %u again (original start pid was %d, state = %s, pageno %d, entryno %d, slotno %d)", reuseXid, gxid, pid, DistributedMapStateToString(state), pageno, entryno, slotno); } SetProcXid(*xid, gxid); LWLockRelease(DistributedXidMapControlLock); }