diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
new file mode 100644
index 9f55adc..c4d5efa
*** a/src/backend/access/transam/twophase.c
--- b/src/backend/access/transam/twophase.c
*************** MarkAsPreparing(TransactionId xid, const
*** 403,409 ****
  	TwoPhaseState->freeGXacts = gxact->next;
  
  	proc = &ProcGlobal->allProcs[gxact->pgprocno];
! 	pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
  
  	/* Initialize the PGPROC entry */
  	MemSet(proc, 0, sizeof(PGPROC));
--- 403,409 ----
  	TwoPhaseState->freeGXacts = gxact->next;
  
  	proc = &ProcGlobal->allProcs[gxact->pgprocno];
! 	pgxact = &ProcGlobal->allPgXact[gxact->pgprocno].xact;
  
  	/* Initialize the PGPROC entry */
  	MemSet(proc, 0, sizeof(PGPROC));
*************** GXactLoadSubxactData(GlobalTransaction g
*** 467,473 ****
  					 TransactionId *children)
  {
  	PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno];
! 	PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
  
  	/* We need no extra lock since the GXACT isn't valid yet */
  	if (nsubxacts > PGPROC_MAX_CACHED_SUBXIDS)
--- 467,473 ----
  					 TransactionId *children)
  {
  	PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno];
! 	PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno].xact;
  
  	/* We need no extra lock since the GXACT isn't valid yet */
  	if (nsubxacts > PGPROC_MAX_CACHED_SUBXIDS)
*************** pg_prepared_xact(PG_FUNCTION_ARGS)
*** 725,731 ****
  	{
  		GlobalTransaction gxact = &status->array[status->currIdx++];
  		PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno];
! 		PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
  		Datum		values[5];
  		bool		nulls[5];
  		HeapTuple	tuple;
--- 725,731 ----
  	{
  		GlobalTransaction gxact = &status->array[status->currIdx++];
  		PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno];
! 		PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno].xact;
  		Datum		values[5];
  		bool		nulls[5];
  		HeapTuple	tuple;
*************** TwoPhaseGetGXact(TransactionId xid)
*** 780,786 ****
  	for (i = 0; i < TwoPhaseState->numPrepXacts; i++)
  	{
  		GlobalTransaction gxact = TwoPhaseState->prepXacts[i];
! 		PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
  
  		if (pgxact->xid == xid)
  		{
--- 780,786 ----
  	for (i = 0; i < TwoPhaseState->numPrepXacts; i++)
  	{
  		GlobalTransaction gxact = TwoPhaseState->prepXacts[i];
! 		PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno].xact;
  
  		if (pgxact->xid == xid)
  		{
*************** void
*** 947,953 ****
  StartPrepare(GlobalTransaction gxact)
  {
  	PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno];
! 	PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
  	TransactionId xid = pgxact->xid;
  	TwoPhaseFileHeader hdr;
  	TransactionId *children;
--- 947,953 ----
  StartPrepare(GlobalTransaction gxact)
  {
  	PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno];
! 	PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno].xact;
  	TransactionId xid = pgxact->xid;
  	TwoPhaseFileHeader hdr;
  	TransactionId *children;
*************** FinishPreparedTransaction(const char *gi
*** 1343,1349 ****
  	 */
  	gxact = LockGXact(gid, GetUserId());
  	proc = &ProcGlobal->allProcs[gxact->pgprocno];
! 	pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
  	xid = pgxact->xid;
  
  	/*
--- 1343,1349 ----
  	 */
  	gxact = LockGXact(gid, GetUserId());
  	proc = &ProcGlobal->allProcs[gxact->pgprocno];
! 	pgxact = &ProcGlobal->allPgXact[gxact->pgprocno].xact;
  	xid = pgxact->xid;
  
  	/*
*************** CheckPointTwoPhase(XLogRecPtr redo_horiz
*** 1623,1629 ****
  	for (i = 0; i < TwoPhaseState->numPrepXacts; i++)
  	{
  		GlobalTransaction gxact = TwoPhaseState->prepXacts[i];
! 		PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
  
  		if (gxact->valid &&
  			!gxact->ondisk &&
--- 1623,1629 ----
  	for (i = 0; i < TwoPhaseState->numPrepXacts; i++)
  	{
  		GlobalTransaction gxact = TwoPhaseState->prepXacts[i];
! 		PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno].xact;
  
  		if (gxact->valid &&
  			!gxact->ondisk &&
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
new file mode 100644
index e5d487d..4af233e
*** a/src/backend/storage/ipc/procarray.c
--- b/src/backend/storage/ipc/procarray.c
*************** typedef struct ProcArrayStruct
*** 97,103 ****
  static ProcArrayStruct *procArray;
  
  static PGPROC *allProcs;
! static PGXACT *allPgXact;
  
  /*
   * Bookkeeping for tracking emulated transactions in recovery
--- 97,103 ----
  static ProcArrayStruct *procArray;
  
  static PGPROC *allProcs;
! static PGXACTPadded *allPgXact;
  
  /*
   * Bookkeeping for tracking emulated transactions in recovery
*************** ProcArrayRemove(PGPROC *proc, Transactio
*** 350,356 ****
  
  	if (TransactionIdIsValid(latestXid))
  	{
! 		Assert(TransactionIdIsValid(allPgXact[proc->pgprocno].xid));
  
  		/* Advance global latestCompletedXid while holding the lock */
  		if (TransactionIdPrecedes(ShmemVariableCache->latestCompletedXid,
--- 350,356 ----
  
  	if (TransactionIdIsValid(latestXid))
  	{
! 		Assert(TransactionIdIsValid(allPgXact[proc->pgprocno].xact.xid));
  
  		/* Advance global latestCompletedXid while holding the lock */
  		if (TransactionIdPrecedes(ShmemVariableCache->latestCompletedXid,
*************** ProcArrayRemove(PGPROC *proc, Transactio
*** 360,366 ****
  	else
  	{
  		/* Shouldn't be trying to remove a live transaction here */
! 		Assert(!TransactionIdIsValid(allPgXact[proc->pgprocno].xid));
  	}
  
  	for (index = 0; index < arrayP->numProcs; index++)
--- 360,366 ----
  	else
  	{
  		/* Shouldn't be trying to remove a live transaction here */
! 		Assert(!TransactionIdIsValid(allPgXact[proc->pgprocno].xact.xid));
  	}
  
  	for (index = 0; index < arrayP->numProcs; index++)
*************** ProcArrayRemove(PGPROC *proc, Transactio
*** 400,406 ****
  void
  ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
  {
! 	PGXACT	   *pgxact = &allPgXact[proc->pgprocno];
  
  	if (TransactionIdIsValid(latestXid))
  	{
--- 400,406 ----
  void
  ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
  {
! 	PGXACT	   *pgxact = &allPgXact[proc->pgprocno].xact;
  
  	if (TransactionIdIsValid(latestXid))
  	{
*************** ProcArrayEndTransaction(PGPROC *proc, Tr
*** 410,416 ****
  		 * else is taking a snapshot.  See discussion in
  		 * src/backend/access/transam/README.
  		 */
! 		Assert(TransactionIdIsValid(allPgXact[proc->pgprocno].xid));
  
  		/*
  		 * If we can immediately acquire ProcArrayLock, we clear our own XID
--- 410,416 ----
  		 * else is taking a snapshot.  See discussion in
  		 * src/backend/access/transam/README.
  		 */
! 		Assert(TransactionIdIsValid(allPgXact[proc->pgprocno].xact.xid));
  
  		/*
  		 * If we can immediately acquire ProcArrayLock, we clear our own XID
*************** ProcArrayEndTransaction(PGPROC *proc, Tr
*** 432,438 ****
  		 * anyone else's calculation of a snapshot.  We might change their
  		 * estimate of global xmin, but that's OK.
  		 */
! 		Assert(!TransactionIdIsValid(allPgXact[proc->pgprocno].xid));
  
  		proc->lxid = InvalidLocalTransactionId;
  		pgxact->xmin = InvalidTransactionId;
--- 432,438 ----
  		 * anyone else's calculation of a snapshot.  We might change their
  		 * estimate of global xmin, but that's OK.
  		 */
! 		Assert(!TransactionIdIsValid(allPgXact[proc->pgprocno].xact.xid));
  
  		proc->lxid = InvalidLocalTransactionId;
  		pgxact->xmin = InvalidTransactionId;
*************** ProcArrayGroupClearXid(PGPROC *proc, Tra
*** 494,500 ****
  	int			extraWaits = -1;
  
  	/* We should definitely have an XID to clear. */
! 	Assert(TransactionIdIsValid(allPgXact[proc->pgprocno].xid));
  
  	/* Add ourselves to the list of processes needing a group XID clear. */
  	proc->procArrayGroupMember = true;
--- 494,500 ----
  	int			extraWaits = -1;
  
  	/* We should definitely have an XID to clear. */
! 	Assert(TransactionIdIsValid(allPgXact[proc->pgprocno].xact.xid));
  
  	/* Add ourselves to the list of processes needing a group XID clear. */
  	proc->procArrayGroupMember = true;
*************** ProcArrayGroupClearXid(PGPROC *proc, Tra
*** 560,566 ****
  	while (nextidx != INVALID_PGPROCNO)
  	{
  		PGPROC	   *proc = &allProcs[nextidx];
! 		PGXACT	   *pgxact = &allPgXact[nextidx];
  
  		ProcArrayEndTransactionInternal(proc, pgxact, proc->procArrayGroupMemberXid);
  
--- 560,566 ----
  	while (nextidx != INVALID_PGPROCNO)
  	{
  		PGPROC	   *proc = &allProcs[nextidx];
! 		PGXACT	   *pgxact = &allPgXact[nextidx].xact;
  
  		ProcArrayEndTransactionInternal(proc, pgxact, proc->procArrayGroupMemberXid);
  
*************** ProcArrayGroupClearXid(PGPROC *proc, Tra
*** 606,612 ****
  void
  ProcArrayClearTransaction(PGPROC *proc)
  {
! 	PGXACT	   *pgxact = &allPgXact[proc->pgprocno];
  
  	/*
  	 * We can skip locking ProcArrayLock here, because this action does not
--- 606,612 ----
  void
  ProcArrayClearTransaction(PGPROC *proc)
  {
! 	PGXACT	   *pgxact = &allPgXact[proc->pgprocno].xact;
  
  	/*
  	 * We can skip locking ProcArrayLock here, because this action does not
*************** TransactionIdIsInProgress(TransactionId 
*** 1078,1084 ****
  	{
  		int			pgprocno = arrayP->pgprocnos[i];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  		TransactionId pxid;
  
  		/* Ignore my own proc --- dealt with it above */
--- 1078,1084 ----
  	{
  		int			pgprocno = arrayP->pgprocnos[i];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  		TransactionId pxid;
  
  		/* Ignore my own proc --- dealt with it above */
*************** TransactionIdIsActive(TransactionId xid)
*** 1234,1240 ****
  	{
  		int			pgprocno = arrayP->pgprocnos[i];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  		TransactionId pxid;
  
  		/* Fetch xid just once - see GetNewTransactionId */
--- 1234,1240 ----
  	{
  		int			pgprocno = arrayP->pgprocnos[i];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  		TransactionId pxid;
  
  		/* Fetch xid just once - see GetNewTransactionId */
*************** GetOldestXmin(Relation rel, bool ignoreV
*** 1344,1350 ****
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  
  		/*
  		 * Backend is doing logical decoding which manages xmin separately,
--- 1344,1350 ----
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  
  		/*
  		 * Backend is doing logical decoding which manages xmin separately,
*************** GetSnapshotData(Snapshot snapshot)
*** 1583,1589 ****
  		for (index = 0; index < numProcs; index++)
  		{
  			int			pgprocno = pgprocnos[index];
! 			volatile PGXACT *pgxact = &allPgXact[pgprocno];
  			TransactionId xid;
  
  			/*
--- 1583,1589 ----
  		for (index = 0; index < numProcs; index++)
  		{
  			int			pgprocno = pgprocnos[index];
! 			volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  			TransactionId xid;
  
  			/*
*************** ProcArrayInstallImportedXmin(Transaction
*** 1811,1817 ****
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  		TransactionId xid;
  
  		/* Ignore procs running LAZY VACUUM */
--- 1811,1817 ----
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  		TransactionId xid;
  
  		/* Ignore procs running LAZY VACUUM */
*************** ProcArrayInstallRestoredXmin(Transaction
*** 1878,1884 ****
  	/* Get lock so source xact can't end while we're doing this */
  	LWLockAcquire(ProcArrayLock, LW_SHARED);
  
! 	pgxact = &allPgXact[proc->pgprocno];
  
  	/*
  	 * Be certain that the referenced PGPROC has an advertised xmin which is
--- 1878,1884 ----
  	/* Get lock so source xact can't end while we're doing this */
  	LWLockAcquire(ProcArrayLock, LW_SHARED);
  
! 	pgxact = &allPgXact[proc->pgprocno].xact;
  
  	/*
  	 * Be certain that the referenced PGPROC has an advertised xmin which is
*************** GetRunningTransactionData(void)
*** 1989,1995 ****
  	for (index = 0; index < arrayP->numProcs; index++)
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  		TransactionId xid;
  
  		/* Fetch xid just once - see GetNewTransactionId */
--- 1989,1995 ----
  	for (index = 0; index < arrayP->numProcs; index++)
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  		TransactionId xid;
  
  		/* Fetch xid just once - see GetNewTransactionId */
*************** GetRunningTransactionData(void)
*** 2021,2027 ****
  		{
  			int			pgprocno = arrayP->pgprocnos[index];
  			volatile PGPROC *proc = &allProcs[pgprocno];
! 			volatile PGXACT *pgxact = &allPgXact[pgprocno];
  			int			nxids;
  
  			/*
--- 2021,2027 ----
  		{
  			int			pgprocno = arrayP->pgprocnos[index];
  			volatile PGPROC *proc = &allProcs[pgprocno];
! 			volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  			int			nxids;
  
  			/*
*************** GetOldestActiveTransactionId(void)
*** 2111,2117 ****
  	for (index = 0; index < arrayP->numProcs; index++)
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  		TransactionId xid;
  
  		/* Fetch xid just once - see GetNewTransactionId */
--- 2111,2117 ----
  	for (index = 0; index < arrayP->numProcs; index++)
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  		TransactionId xid;
  
  		/* Fetch xid just once - see GetNewTransactionId */
*************** GetOldestSafeDecodingTransactionId(void)
*** 2202,2208 ****
  		for (index = 0; index < arrayP->numProcs; index++)
  		{
  			int			pgprocno = arrayP->pgprocnos[index];
! 			volatile PGXACT *pgxact = &allPgXact[pgprocno];
  			TransactionId xid;
  
  			/* Fetch xid just once - see GetNewTransactionId */
--- 2202,2208 ----
  		for (index = 0; index < arrayP->numProcs; index++)
  		{
  			int			pgprocno = arrayP->pgprocnos[index];
! 			volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  			TransactionId xid;
  
  			/* Fetch xid just once - see GetNewTransactionId */
*************** GetVirtualXIDsDelayingChkpt(int *nvxids)
*** 2257,2263 ****
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  
  		if (pgxact->delayChkpt)
  		{
--- 2257,2263 ----
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  
  		if (pgxact->delayChkpt)
  		{
*************** HaveVirtualXIDsDelayingChkpt(VirtualTran
*** 2297,2303 ****
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  		VirtualTransactionId vxid;
  
  		GET_VXID_FROM_PGPROC(vxid, *proc);
--- 2297,2303 ----
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  		VirtualTransactionId vxid;
  
  		GET_VXID_FROM_PGPROC(vxid, *proc);
*************** BackendXidGetPid(TransactionId xid)
*** 2407,2413 ****
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  
  		if (pgxact->xid == xid)
  		{
--- 2407,2413 ----
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  
  		if (pgxact->xid == xid)
  		{
*************** GetCurrentVirtualXIDs(TransactionId limi
*** 2479,2485 ****
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  
  		if (proc == MyProc)
  			continue;
--- 2479,2485 ----
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  
  		if (proc == MyProc)
  			continue;
*************** GetConflictingVirtualXIDs(TransactionId 
*** 2576,2582 ****
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  
  		/* Exclude prepared transactions */
  		if (proc->pid == 0)
--- 2576,2582 ----
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  
  		/* Exclude prepared transactions */
  		if (proc->pid == 0)
*************** MinimumActiveBackends(int min)
*** 2690,2696 ****
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno];
  
  		/*
  		 * Since we're not holding a lock, need to be prepared to deal with
--- 2690,2696 ----
  	{
  		int			pgprocno = arrayP->pgprocnos[index];
  		volatile PGPROC *proc = &allProcs[pgprocno];
! 		volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  
  		/*
  		 * Since we're not holding a lock, need to be prepared to deal with
*************** CountOtherDBBackends(Oid databaseId, int
*** 2867,2873 ****
  		{
  			int			pgprocno = arrayP->pgprocnos[index];
  			volatile PGPROC *proc = &allProcs[pgprocno];
! 			volatile PGXACT *pgxact = &allPgXact[pgprocno];
  
  			if (proc->databaseId != databaseId)
  				continue;
--- 2867,2873 ----
  		{
  			int			pgprocno = arrayP->pgprocnos[index];
  			volatile PGPROC *proc = &allProcs[pgprocno];
! 			volatile PGXACT *pgxact = &allPgXact[pgprocno].xact;
  
  			if (proc->databaseId != databaseId)
  				continue;
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
new file mode 100644
index 44a9f2c..9a1d106
*** a/src/backend/storage/ipc/sinvaladt.c
--- b/src/backend/storage/ipc/sinvaladt.c
*************** BackendIdGetTransactionIds(int backendID
*** 418,424 ****
  
  		if (proc != NULL)
  		{
! 			PGXACT	   *xact = &ProcGlobal->allPgXact[proc->pgprocno];
  
  			*xid = xact->xid;
  			*xmin = xact->xmin;
--- 418,424 ----
  
  		if (proc != NULL)
  		{
! 			PGXACT	   *xact = &ProcGlobal->allPgXact[proc->pgprocno].xact;
  
  			*xid = xact->xid;
  			*xmin = xact->xmin;
diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c
new file mode 100644
index 3f3e24f..1f5528e
*** a/src/backend/storage/lmgr/deadlock.c
--- b/src/backend/storage/lmgr/deadlock.c
*************** FindLockCycleRecurseMember(PGPROC *check
*** 573,579 ****
  		PGPROC	   *leader;
  
  		proc = proclock->tag.myProc;
! 		pgxact = &ProcGlobal->allPgXact[proc->pgprocno];
  		leader = proc->lockGroupLeader == NULL ? proc : proc->lockGroupLeader;
  
  		/* A proc never blocks itself or any other lock group member */
--- 573,579 ----
  		PGPROC	   *leader;
  
  		proc = proclock->tag.myProc;
! 		pgxact = &ProcGlobal->allPgXact[proc->pgprocno].xact;
  		leader = proc->lockGroupLeader == NULL ? proc : proc->lockGroupLeader;
  
  		/* A proc never blocks itself or any other lock group member */
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
new file mode 100644
index dba3809..714b6bf
*** a/src/backend/storage/lmgr/lock.c
--- b/src/backend/storage/lmgr/lock.c
*************** GetRunningTransactionLocks(int *nlocks)
*** 3806,3812 ****
  			proclock->tag.myLock->tag.locktag_type == LOCKTAG_RELATION)
  		{
  			PGPROC	   *proc = proclock->tag.myProc;
! 			PGXACT	   *pgxact = &ProcGlobal->allPgXact[proc->pgprocno];
  			LOCK	   *lock = proclock->tag.myLock;
  			TransactionId xid = pgxact->xid;
  
--- 3806,3812 ----
  			proclock->tag.myLock->tag.locktag_type == LOCKTAG_RELATION)
  		{
  			PGPROC	   *proc = proclock->tag.myProc;
! 			PGXACT	   *pgxact = &ProcGlobal->allPgXact[proc->pgprocno].xact;
  			LOCK	   *lock = proclock->tag.myLock;
  			TransactionId xid = pgxact->xid;
  
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
new file mode 100644
index 9a758bd..a555b2a
*** a/src/backend/storage/lmgr/proc.c
--- b/src/backend/storage/lmgr/proc.c
*************** void
*** 160,166 ****
  InitProcGlobal(void)
  {
  	PGPROC	   *procs;
! 	PGXACT	   *pgxacts;
  	int			i,
  				j;
  	bool		found;
--- 160,166 ----
  InitProcGlobal(void)
  {
  	PGPROC	   *procs;
! 	PGXACTPadded *pgxacts;
  	int			i,
  				j;
  	bool		found;
*************** InitProcGlobal(void)
*** 211,218 ****
  	 * multiprocessor system.  There is one PGXACT structure for every PGPROC
  	 * structure.
  	 */
! 	pgxacts = (PGXACT *) ShmemAlloc(TotalProcs * sizeof(PGXACT));
! 	MemSet(pgxacts, 0, TotalProcs * sizeof(PGXACT));
  	ProcGlobal->allPgXact = pgxacts;
  
  	for (i = 0; i < TotalProcs; i++)
--- 211,218 ----
  	 * multiprocessor system.  There is one PGXACT structure for every PGPROC
  	 * structure.
  	 */
! 	pgxacts = (PGXACTPadded *) ShmemAlloc(TotalProcs * sizeof(PGXACTPadded));
! 	MemSet(pgxacts, 0, TotalProcs * sizeof(PGXACTPadded));
  	ProcGlobal->allPgXact = pgxacts;
  
  	for (i = 0; i < TotalProcs; i++)
*************** InitProcess(void)
*** 339,345 ****
  				(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
  				 errmsg("sorry, too many clients already")));
  	}
! 	MyPgXact = &ProcGlobal->allPgXact[MyProc->pgprocno];
  
  	/*
  	 * Cross-check that the PGPROC is of the type we expect; if this were not
--- 339,345 ----
  				(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
  				 errmsg("sorry, too many clients already")));
  	}
! 	MyPgXact = &ProcGlobal->allPgXact[MyProc->pgprocno].xact;
  
  	/*
  	 * Cross-check that the PGPROC is of the type we expect; if this were not
*************** InitAuxiliaryProcess(void)
*** 526,532 ****
  	((volatile PGPROC *) auxproc)->pid = MyProcPid;
  
  	MyProc = auxproc;
! 	MyPgXact = &ProcGlobal->allPgXact[auxproc->pgprocno];
  
  	SpinLockRelease(ProcStructLock);
  
--- 526,532 ----
  	((volatile PGPROC *) auxproc)->pid = MyProcPid;
  
  	MyProc = auxproc;
! 	MyPgXact = &ProcGlobal->allPgXact[auxproc->pgprocno].xact;
  
  	SpinLockRelease(ProcStructLock);
  
*************** ProcSleep(LOCALLOCK *locallock, LockMeth
*** 1241,1247 ****
  		if (deadlock_state == DS_BLOCKED_BY_AUTOVACUUM && allow_autovacuum_cancel)
  		{
  			PGPROC	   *autovac = GetBlockingAutoVacuumPgproc();
! 			PGXACT	   *autovac_pgxact = &ProcGlobal->allPgXact[autovac->pgprocno];
  
  			LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
  
--- 1241,1247 ----
  		if (deadlock_state == DS_BLOCKED_BY_AUTOVACUUM && allow_autovacuum_cancel)
  		{
  			PGPROC	   *autovac = GetBlockingAutoVacuumPgproc();
! 			PGXACT	   *autovac_pgxact = &ProcGlobal->allPgXact[autovac->pgprocno].xact;
  
  			LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
  
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
new file mode 100644
index f576f05..0686426
*** a/src/include/storage/proc.h
--- b/src/include/storage/proc.h
*************** typedef struct PGXACT
*** 209,214 ****
--- 209,225 ----
  } PGXACT;
  
  /*
+  * Cacheline aligned PGXACT which allows us to put each PGXACT to individual
+  * cacheline.  Assuming PGXACTs are under intensive write, cacheline alignment
+  * reduce cache misses during GetSnapshotData().
+  */
+ typedef union PGXACTPadded
+ {
+ 	PGXACT		xact;
+ 	char		pad[PG_CACHE_LINE_SIZE];
+ } PGXACTPadded;
+ 
+ /*
   * There is one ProcGlobal struct for the whole database cluster.
   */
  typedef struct PROC_HDR
*************** typedef struct PROC_HDR
*** 216,222 ****
  	/* Array of PGPROC structures (not including dummies for prepared txns) */
  	PGPROC	   *allProcs;
  	/* Array of PGXACT structures (not including dummies for prepared txns) */
! 	PGXACT	   *allPgXact;
  	/* Length of allProcs array */
  	uint32		allProcCount;
  	/* Head of list of free PGPROC structures */
--- 227,233 ----
  	/* Array of PGPROC structures (not including dummies for prepared txns) */
  	PGPROC	   *allProcs;
  	/* Array of PGXACT structures (not including dummies for prepared txns) */
! 	PGXACTPadded *allPgXact;
  	/* Length of allProcs array */
  	uint32		allProcCount;
  	/* Head of list of free PGPROC structures */
