Esempio n. 1
0
/*
 * 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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/*
 *	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);
}