Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5541abe

Browse files
committed
1. Additional fix against ERROR: Child itemid marked as unused
in CommitTransaction(). 2. Changes in GetSnapshotData().
1 parent f103501 commit 5541abe

File tree

2 files changed

+49
-25
lines changed

2 files changed

+49
-25
lines changed

src/backend/access/transam/xact.c

+23-13
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.38 1999/06/03 04:41:41 vadim Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.39 1999/06/03 13:33:12 vadim Exp $
1111
*
1212
* NOTES
1313
* Transaction aborts can now occur two ways:
@@ -646,18 +646,6 @@ RecordTransactionCommit()
646646
FlushBufferPool(!TransactionFlushEnabled());
647647
if (leak)
648648
ResetBufferPool();
649-
650-
/*
651-
* Let others know about no transaction in progress.
652-
* Note that this must be done _before_ releasing locks
653-
* we hold or bad (too high) XmaxRecent value might be
654-
* used by vacuum.
655-
*/
656-
if (MyProc != (PROC *) NULL)
657-
{
658-
MyProc->xid = InvalidTransactionId;
659-
MyProc->xmin = InvalidTransactionId;
660-
}
661649
}
662650

663651

@@ -950,6 +938,28 @@ CommitTransaction()
950938
DestroyNoNameRels();
951939
AtEOXact_portals();
952940
RecordTransactionCommit();
941+
942+
/*
943+
* Let others know about no transaction in progress by me.
944+
* Note that this must be done _before_ releasing locks we hold
945+
* and SpinAcquire(ShmemIndexLock) is required - or bad (too high)
946+
* XmaxRecent value might be used by vacuum: UPDATE with xid 0 is
947+
* blocked by xid 1' UPDATE, xid 1 is doing commit while xid 2
948+
* gets snapshot - if xid 2' GetSnapshotData sees xid 1 as running
949+
* then it must see xid 0 as running as well or XmaxRecent = 1
950+
* might be used by concurrent vacuum causing
951+
* ERROR: Child itemid marked as unused
952+
* This bug was reported by Hiroshi Inoue and I was able to reproduce
953+
* it with 3 sessions and gdb. - vadim 06/03/99
954+
*/
955+
if (MyProc != (PROC *) NULL)
956+
{
957+
SpinAcquire(ShmemIndexLock);
958+
MyProc->xid = InvalidTransactionId;
959+
MyProc->xmin = InvalidTransactionId;
960+
SpinRelease(ShmemIndexLock);
961+
}
962+
953963
RelationPurgeLocalRelation(true);
954964
AtCommit_Cache();
955965
AtCommit_Locks();

src/backend/storage/ipc/shmem.c

+26-12
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.40 1999/05/25 16:11:11 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.41 1999/06/03 13:33:13 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -593,6 +593,10 @@ ShmemInitStruct(char *name, unsigned long size, bool *foundPtr)
593593
*
594594
* Strange place for this func, but we have to lookup process data structures
595595
* for all running backends. - vadim 11/26/96
596+
*
597+
* We should keep all PROC structs not in ShmemIndex - this is too
598+
* general hash table...
599+
*
596600
*/
597601
bool
598602
TransactionIdIsInProgress(TransactionId xid)
@@ -648,10 +652,7 @@ GetSnapshotData(bool serializable)
648652

649653
snapshot->xip = (TransactionId *) malloc(have * sizeof(TransactionId));
650654
snapshot->xmin = cid;
651-
if (serializable)
652-
snapshot->xmax = cid;
653-
else
654-
ReadNewTransactionId(&(snapshot->xmax));
655+
ReadNewTransactionId(&(snapshot->xmax));
655656

656657
SpinAcquire(ShmemIndexLock);
657658

@@ -660,8 +661,10 @@ GetSnapshotData(bool serializable)
660661
{
661662
if (result == (ShmemIndexEnt *) TRUE)
662663
{
663-
if (MyProc->xmin == InvalidTransactionId)
664+
if (serializable)
664665
MyProc->xmin = snapshot->xmin;
666+
/* Serializable snapshot must be computed before any other... */
667+
Assert(MyProc->xmin != InvalidTransactionId);
665668
SpinRelease(ShmemIndexLock);
666669
snapshot->xcnt = count;
667670
return snapshot;
@@ -670,13 +673,24 @@ GetSnapshotData(bool serializable)
670673
strncmp(result->key, "PID ", 4) != 0)
671674
continue;
672675
proc = (PROC *) MAKE_PTR(result->location);
673-
xid = proc->xid; /* we don't use spin-locking in xact.c ! */
674-
if (proc == MyProc || xid < FirstTransactionId)
676+
/*
677+
* We don't use spin-locking when changing proc->xid
678+
* in GetNewTransactionId() and in AbortTransaction() !..
679+
*/
680+
xid = proc->xid;
681+
if (proc == MyProc ||
682+
xid < FirstTransactionId || xid >= snapshot->xmax)
683+
{
684+
/*
685+
* Seems that there is no sense to store xid >= snapshot->xmax
686+
* (what we got from ReadNewTransactionId above) in snapshot->xip
687+
* - we just assume that all xacts with such xid-s are running
688+
* and may be ignored.
689+
*/
675690
continue;
691+
}
676692
if (xid < snapshot->xmin)
677693
snapshot->xmin = xid;
678-
else if (xid > snapshot->xmax)
679-
snapshot->xmax = xid;
680694
if (have == 0)
681695
{
682696
snapshot->xip = (TransactionId *) realloc(snapshot->xip,
@@ -712,7 +726,7 @@ GetXmaxRecent(TransactionId *XmaxRecent)
712726

713727
Assert(ShmemIndex);
714728

715-
ReadNewTransactionId(XmaxRecent);
729+
*XmaxRecent = GetCurrentTransactionId();
716730

717731
SpinAcquire(ShmemIndexLock);
718732

@@ -728,7 +742,7 @@ GetXmaxRecent(TransactionId *XmaxRecent)
728742
strncmp(result->key, "PID ", 4) != 0)
729743
continue;
730744
proc = (PROC *) MAKE_PTR(result->location);
731-
xmin = proc->xmin; /* we don't use spin-locking in xact.c ! */
745+
xmin = proc->xmin; /* we don't use spin-locking in AbortTransaction() ! */
732746
if (proc == MyProc || xmin < FirstTransactionId)
733747
continue;
734748
if (xmin < *XmaxRecent)

0 commit comments

Comments
 (0)