fix stuff.
authorHeikki Linnakangas <[email protected]>
Mon, 22 Aug 2016 15:22:42 +0000 (18:22 +0300)
committerHeikki Linnakangas <[email protected]>
Mon, 22 Aug 2016 18:21:58 +0000 (21:21 +0300)
src/backend/access/index/indexam.c
src/backend/storage/ipc/procarray.c
src/backend/utils/time/tqual.c
src/include/access/transam.h

index 54b71cb2f77b722d0436c33c2f09be1093d79eb7..ea9e0b03429e5cd69ce1bfc1cb3cba63388f70fd 100644 (file)
@@ -404,8 +404,6 @@ index_getnext_tid(IndexScanDesc scan, ScanDirection direction)
        SCAN_CHECKS;
        CHECK_SCAN_PROCEDURE(amgettuple);
 
-       Assert(TransactionIdIsValid(RecentGlobalXmin));
-
        /*
         * The AM's amgettuple proc finds the next index entry matching the scan
         * keys, and puts the TID into scan->xs_ctup.t_self.  It should also set
index 1744e0b65b530763ae0496145399613bc2747ccc..8887c365122ce5ec6264309e01a6cdcffc9b343e 100644 (file)
@@ -262,6 +262,10 @@ ProcArrayEndTransaction(PGPROC *proc)
        /* If we were the oldest active XID, advance oldestXid */
        if (TransactionIdIsValid(myXid))
                AdvanceOldestActiveXid(myXid);
+
+       /* Reset cached variables */
+       RecentGlobalXmin = InvalidTransactionId;
+       RecentGlobalDataXmin = InvalidTransactionId;
 }
 
 void
@@ -275,7 +279,9 @@ ProcArrayResetXmin(PGPROC *proc)
         */
        pgxact->xmin = InvalidTransactionId;
 
+       /* Reset cached variables */
        RecentGlobalXmin = InvalidTransactionId;
+       RecentGlobalDataXmin = InvalidTransactionId;
 }
 
 /*
@@ -311,6 +317,10 @@ ProcArrayClearTransaction(PGPROC *proc)
         * We don't need to update oldestActiveXid, because the gxact entry in
         * the procarray is still running with the same XID.
         */
+
+       /* Reset cached variables */
+       RecentGlobalXmin = InvalidTransactionId;
+       RecentGlobalDataXmin = InvalidTransactionId;
 }
 
 /*
@@ -543,7 +553,7 @@ AdvanceOldestActiveXid(TransactionId myXid)
 
 
 /*
- *
+ * This is like GetOldestXmin(NULL, true), but can return slightly stale, cached value.
  */
 TransactionId
 GetRecentGlobalXmin(void)
index 5fe898ba0570c8e3e6712e7fa72ae8337721d60f..e92201b8be6629b63cacbdb11c0ba2dc4a1bb21e 100644 (file)
@@ -58,7 +58,9 @@ SnapshotData SnapshotSelfData = {HeapTupleSatisfiesSelf};
 SnapshotData SnapshotAnyData = {HeapTupleSatisfiesAny};
 
 /* local functions */
-static bool XidVisibleInSnapshot(TransactionId xid, Snapshot snapshot, bool known_committed, TransactionIdStatus *hintstatus);
+static bool XidVisibleInSnapshot(TransactionId xid, Snapshot snapshot,
+                                        TransactionIdStatus *hintstatus);
+static bool CommittedXidVisibleInSnapshot(TransactionId xid, Snapshot snapshot);
 static bool IsMovedTupleVisible(HeapTuple htup, Buffer buffer);
 
 /*
@@ -206,7 +208,7 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
                }
                else
                {
-                       visible = XidVisibleInSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot, false, &hintstatus);
+                       visible = XidVisibleInSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot, &hintstatus);
 
                        if (hintstatus == XID_COMMITTED)
                                SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
@@ -246,7 +248,7 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
                if (TransactionIdIsCurrentTransactionId(xmax))
                        return false;
 
-               visible = XidVisibleInSnapshot(xmax, snapshot, false, &hintstatus);
+               visible = XidVisibleInSnapshot(xmax, snapshot, &hintstatus);
                if (!visible)
                {
                        /* it must have aborted or crashed */
@@ -261,7 +263,7 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
                return false;
        }
 
-       visible = XidVisibleInSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot, false, &hintstatus);
+       visible = XidVisibleInSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot, &hintstatus);
        if (hintstatus == XID_ABORTED)
        {
                /* it must have aborted or crashed */
@@ -878,7 +880,7 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
                else
                {
                        visible = XidVisibleInSnapshot(HeapTupleHeaderGetXmin(tuple),
-                                                                                  snapshot, false, &hintstatus);
+                                                                                  snapshot, &hintstatus);
                        if (hintstatus == XID_COMMITTED)
                                SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                                        HeapTupleHeaderGetRawXmin(tuple));
@@ -894,18 +896,7 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
                /* xmin is committed, but maybe not according to our snapshot */
                if (!HeapTupleHeaderXminFrozen(tuple))
                {
-                       visible = XidVisibleInSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot,
-                                                                                  true, &hintstatus);
-                       if (hintstatus == XID_COMMITTED)
-                       {
-                               SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                       HeapTupleHeaderGetRawXmin(tuple));
-                       }
-                       if (hintstatus == XID_ABORTED)
-                       {
-                               SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                       InvalidTransactionId);
-                       }
+                       visible = CommittedXidVisibleInSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot);
                        if (!visible)
                                return false;           /* treat as still in progress */
                }
@@ -939,7 +930,7 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
                                return false;   /* deleted before scan started */
                }
 
-               visible = XidVisibleInSnapshot(xmax, snapshot, false, &hintstatus);
+               visible = XidVisibleInSnapshot(xmax, snapshot, &hintstatus);
                if (visible)
                        return false;           /* updating transaction committed */
                else
@@ -960,7 +951,7 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
                }
 
                visible = XidVisibleInSnapshot(HeapTupleHeaderGetRawXmax(tuple),
-                                                                          snapshot, false, &hintstatus);
+                                                                          snapshot, &hintstatus);
                if (hintstatus == XID_COMMITTED)
                {
                        /* xmax transaction committed */
@@ -972,14 +963,14 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
                        /* it must have aborted or crashed */
                        SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                                InvalidTransactionId);
-                       return true;
                }
+               if (!visible)
+                       return true;            /* treat as still in progress */
        }
        else
        {
                /* xmax is committed, but maybe not according to our snapshot */
-               visible = XidVisibleInSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot,
-                                                                          false, &hintstatus);
+               visible = CommittedXidVisibleInSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot);
                if (!visible)
                        return true;            /* treat as still in progress */
        }
@@ -989,7 +980,6 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
        return false;
 }
 
-
 /*
  * HeapTupleSatisfiesVacuum
  *
@@ -1298,28 +1288,19 @@ HeapTupleIsSurelyDead(HeapTuple htup, TransactionId OldestXmin)
  */
 static bool
 XidVisibleInSnapshot(TransactionId xid, Snapshot snapshot,
-                                        bool known_committed, TransactionIdStatus *hintstatus)
+                                        TransactionIdStatus *hintstatus)
 {
        CommitSeqNo csn;
 
-       elog(DEBUG1, "XidVisibleInSnapshot %u, %u:%u",
-                xid, snapshot->xmin, snapshot->xmax);
-
        *hintstatus = XID_INPROGRESS;
 
-       /*
-        * Make a quick range check to eliminate most XIDs without looking at the
-        * CSN log.
-        */
-       if (known_committed && TransactionIdPrecedes(xid, snapshot->xmin))
-       {
-               *hintstatus = XID_COMMITTED;
-               return true;
-       }
-
        /*
         * Any xid >= xmax is in-progress (or aborted, but we don't distinguish
-        * that here.
+        * that here).
+        *
+        * We can't do anything useful with xmin, because the xmin only tells us
+        * whether we see it as completed. We have to check the transaction log to
+        * see if the transaction committed or aborted, in any case.
         */
        if (TransactionIdFollowsOrEquals(xid, snapshot->xmax))
                return false;
@@ -1342,6 +1323,52 @@ XidVisibleInSnapshot(TransactionId xid, Snapshot snapshot,
        }
 }
 
+/*
+ * CommittedXidVisibleInSnapshot
+ *             Is the given XID visible according to the snapshot?
+ *
+ * This is the same as XidVisibleInSnapshot, but the caller knows that the
+ * given XID committed. The only question is whether it's visible to our
+ * snapshot or not.
+ */
+static bool
+CommittedXidVisibleInSnapshot(TransactionId xid, Snapshot snapshot)
+{
+       CommitSeqNo csn;
+
+       /*
+        * Make a quick range check to eliminate most XIDs without looking at the
+        * CSN log.
+        */
+       if (TransactionIdPrecedes(xid, snapshot->xmin))
+               return true;
+
+       /*
+        * Any xid >= xmax is in-progress (or aborted, but we don't distinguish
+        * that here.
+        */
+       if (TransactionIdFollowsOrEquals(xid, snapshot->xmax))
+               return false;
+
+       csn = TransactionIdGetCommitSeqNo(xid);
+
+       if (!COMMITSEQNO_IS_COMMITTED(csn))
+       {
+               elog(WARNING, "transaction %u was hinted as committed, but was not marked as committed in the transaction log", xid);
+               /*
+                * We have contradicting evidence on whether the transaction committed or
+                * not. Let's assume that it did. That seems better than erroring out.
+                */
+               return true;
+       }
+
+       if (csn < snapshot->snapshotcsn)
+               return true;
+       else
+               return false;
+}
+
+
 /*
  * Is the tuple really only locked?  That is, is it not updated?
  *
@@ -1469,7 +1496,7 @@ HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot,
         * it's not "this" transaction. Do a normal visibility check using the
         * snapshot.
         */
-       else if (!XidVisibleInSnapshot(xmin, snapshot, false, &hintstatus))
+       else if (!XidVisibleInSnapshot(xmin, snapshot, &hintstatus))
        {
                return false;
        }
@@ -1519,7 +1546,7 @@ HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot,
         * it's not "this" transaction. Do a normal visibility check using the
         * snapshot.
         */
-       if (XidVisibleInSnapshot(xmax, snapshot, false, &hintstatus))
+       if (XidVisibleInSnapshot(xmax, snapshot, &hintstatus))
                return false;
        else
                return true;
index 66dcf311afb41549cad02d550c763f41c64944d2..2bf2202d2b4e8db5cf259c46b63be033cd6c296b 100644 (file)
                (dest)--; \
        } while ((dest) < FirstNormalTransactionId)
 
-static inline TransactionId
-TransactionIdNext(TransactionId xid)
-{
-       TransactionIdAdvance(xid);
-       return xid;
-}
-
-static inline TransactionId
-TransactionIdPrev(TransactionId xid)
-{
-       TransactionIdRetreat(xid);
-       return xid;
-}
-
 /* compare two XIDs already known to be normal; this is a macro for speed */
 #define NormalTransactionIdPrecedes(id1, id2) \
        (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \