PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
tqual.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * tqual.c
4  * POSTGRES "time qualification" code, ie, tuple visibility rules.
5  *
6  * NOTE: all the HeapTupleSatisfies routines will update the tuple's
7  * "hint" status bits if we see that the inserting or deleting transaction
8  * has now committed or aborted (and it is safe to set the hint bits).
9  * If the hint bits are changed, MarkBufferDirtyHint is called on
10  * the passed-in buffer. The caller must hold not only a pin, but at least
11  * shared buffer content lock on the buffer containing the tuple.
12  *
13  * NOTE: When using a non-MVCC snapshot, we must check
14  * TransactionIdIsInProgress (which looks in the PGXACT array)
15  * before TransactionIdDidCommit/TransactionIdDidAbort (which look in
16  * pg_xact). Otherwise we have a race condition: we might decide that a
17  * just-committed transaction crashed, because none of the tests succeed.
18  * xact.c is careful to record commit/abort in pg_xact before it unsets
19  * MyPgXact->xid in the PGXACT array. That fixes that problem, but it
20  * also means there is a window where TransactionIdIsInProgress and
21  * TransactionIdDidCommit will both return true. If we check only
22  * TransactionIdDidCommit, we could consider a tuple committed when a
23  * later GetSnapshotData call will still think the originating transaction
24  * is in progress, which leads to application-level inconsistency. The
25  * upshot is that we gotta check TransactionIdIsInProgress first in all
26  * code paths, except for a few cases where we are looking at
27  * subtransactions of our own main transaction and so there can't be any
28  * race condition.
29  *
30  * When using an MVCC snapshot, we rely on XidInMVCCSnapshot rather than
31  * TransactionIdIsInProgress, but the logic is otherwise the same: do not
32  * check pg_xact until after deciding that the xact is no longer in progress.
33  *
34  *
35  * Summary of visibility functions:
36  *
37  * HeapTupleSatisfiesMVCC()
38  * visible to supplied snapshot, excludes current command
39  * HeapTupleSatisfiesUpdate()
40  * visible to instant snapshot, with user-supplied command
41  * counter and more complex result
42  * HeapTupleSatisfiesSelf()
43  * visible to instant snapshot and current command
44  * HeapTupleSatisfiesDirty()
45  * like HeapTupleSatisfiesSelf(), but includes open transactions
46  * HeapTupleSatisfiesVacuum()
47  * visible to any running transaction, used by VACUUM
48  * HeapTupleSatisfiesToast()
49  * visible unless part of interrupted vacuum, used for TOAST
50  * HeapTupleSatisfiesAny()
51  * all tuples are visible
52  *
53  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
54  * Portions Copyright (c) 1994, Regents of the University of California
55  *
56  * IDENTIFICATION
57  * src/backend/utils/time/tqual.c
58  *
59  *-------------------------------------------------------------------------
60  */
61 
62 #include "postgres.h"
63 
64 #include "access/htup_details.h"
65 #include "access/multixact.h"
66 #include "access/subtrans.h"
67 #include "access/transam.h"
68 #include "access/xact.h"
69 #include "access/xlog.h"
70 #include "storage/bufmgr.h"
71 #include "storage/procarray.h"
72 #include "utils/builtins.h"
73 #include "utils/combocid.h"
74 #include "utils/snapmgr.h"
75 #include "utils/tqual.h"
76 
77 
78 /* Static variables representing various special snapshot semantics */
81 
82 /* local functions */
83 static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
84 
85 /*
86  * SetHintBits()
87  *
88  * Set commit/abort hint bits on a tuple, if appropriate at this time.
89  *
90  * It is only safe to set a transaction-committed hint bit if we know the
91  * transaction's commit record is guaranteed to be flushed to disk before the
92  * buffer, or if the table is temporary or unlogged and will be obliterated by
93  * a crash anyway. We cannot change the LSN of the page here, because we may
94  * hold only a share lock on the buffer, so we can only use the LSN to
95  * interlock this if the buffer's LSN already is newer than the commit LSN;
96  * otherwise we have to just refrain from setting the hint bit until some
97  * future re-examination of the tuple.
98  *
99  * We can always set hint bits when marking a transaction aborted. (Some
100  * code in heapam.c relies on that!)
101  *
102  * Also, if we are cleaning up HEAP_MOVED_IN or HEAP_MOVED_OFF entries, then
103  * we can always set the hint bits, since pre-9.0 VACUUM FULL always used
104  * synchronous commits and didn't move tuples that weren't previously
105  * hinted. (This is not known by this subroutine, but is applied by its
106  * callers.) Note: old-style VACUUM FULL is gone, but we have to keep this
107  * module's support for MOVED_OFF/MOVED_IN flag bits for as long as we
108  * support in-place update from pre-9.0 databases.
109  *
110  * Normal commits may be asynchronous, so for those we need to get the LSN
111  * of the transaction and then check whether this is flushed.
112  *
113  * The caller should pass xid as the XID of the transaction to check, or
114  * InvalidTransactionId if no check is needed.
115  */
116 static inline void
118  uint16 infomask, TransactionId xid)
119 {
120  if (TransactionIdIsValid(xid))
121  {
122  /* NB: xid must be known committed here! */
123  XLogRecPtr commitLSN = TransactionIdGetCommitLSN(xid);
124 
125  if (BufferIsPermanent(buffer) && XLogNeedsFlush(commitLSN) &&
126  BufferGetLSNAtomic(buffer) < commitLSN)
127  {
128  /* not flushed and no LSN interlock, so don't set hint */
129  return;
130  }
131  }
132 
133  tuple->t_infomask |= infomask;
134  MarkBufferDirtyHint(buffer, true);
135 }
136 
137 /*
138  * HeapTupleSetHintBits --- exported version of SetHintBits()
139  *
140  * This must be separate because of C99's brain-dead notions about how to
141  * implement inline functions.
142  */
143 void
145  uint16 infomask, TransactionId xid)
146 {
147  SetHintBits(tuple, buffer, infomask, xid);
148 }
149 
150 
151 /*
152  * HeapTupleSatisfiesSelf
153  * True iff heap tuple is valid "for itself".
154  *
155  * Here, we consider the effects of:
156  * all committed transactions (as of the current instant)
157  * previous commands of this transaction
158  * changes made by the current command
159  *
160  * Note:
161  * Assumes heap tuple is valid.
162  *
163  * The satisfaction of "itself" requires the following:
164  *
165  * ((Xmin == my-transaction && the row was updated by the current transaction, and
166  * (Xmax is null it was not deleted
167  * [|| Xmax != my-transaction)]) [or it was deleted by another transaction]
168  * ||
169  *
170  * (Xmin is committed && the row was modified by a committed transaction, and
171  * (Xmax is null || the row has not been deleted, or
172  * (Xmax != my-transaction && the row was deleted by another transaction
173  * Xmax is not committed))) that has not been committed
174  */
175 bool
177 {
178  HeapTupleHeader tuple = htup->t_data;
179 
181  Assert(htup->t_tableOid != InvalidOid);
182 
183  if (!HeapTupleHeaderXminCommitted(tuple))
184  {
185  if (HeapTupleHeaderXminInvalid(tuple))
186  return false;
187 
188  /* Used by pre-9.0 binary upgrades */
189  if (tuple->t_infomask & HEAP_MOVED_OFF)
190  {
192 
194  return false;
195  if (!TransactionIdIsInProgress(xvac))
196  {
197  if (TransactionIdDidCommit(xvac))
198  {
199  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
201  return false;
202  }
203  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
205  }
206  }
207  /* Used by pre-9.0 binary upgrades */
208  else if (tuple->t_infomask & HEAP_MOVED_IN)
209  {
211 
213  {
214  if (TransactionIdIsInProgress(xvac))
215  return false;
216  if (TransactionIdDidCommit(xvac))
217  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
219  else
220  {
221  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
223  return false;
224  }
225  }
226  }
228  {
229  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
230  return true;
231 
232  if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
233  return true;
234 
235  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
236  {
237  TransactionId xmax;
238 
239  xmax = HeapTupleGetUpdateXid(tuple);
240 
241  /* not LOCKED_ONLY, so it has to have an xmax */
243 
244  /* updating subtransaction must have aborted */
246  return true;
247  else
248  return false;
249  }
250 
252  {
253  /* deleting subtransaction must have aborted */
254  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
256  return true;
257  }
258 
259  return false;
260  }
262  return false;
264  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
266  else
267  {
268  /* it must have aborted or crashed */
269  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
271  return false;
272  }
273  }
274 
275  /* by here, the inserting transaction has committed */
276 
277  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
278  return true;
279 
280  if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
281  {
283  return true;
284  return false; /* updated by other */
285  }
286 
287  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
288  {
289  TransactionId xmax;
290 
292  return true;
293 
294  xmax = HeapTupleGetUpdateXid(tuple);
295 
296  /* not LOCKED_ONLY, so it has to have an xmax */
298 
300  return false;
301  if (TransactionIdIsInProgress(xmax))
302  return true;
303  if (TransactionIdDidCommit(xmax))
304  return false;
305  /* it must have aborted or crashed */
306  return true;
307  }
308 
310  {
312  return true;
313  return false;
314  }
315 
317  return true;
318 
320  {
321  /* it must have aborted or crashed */
322  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
324  return true;
325  }
326 
327  /* xmax transaction committed */
328 
330  {
331  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
333  return true;
334  }
335 
336  SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
338  return false;
339 }
340 
341 /*
342  * HeapTupleSatisfiesAny
343  * Dummy "satisfies" routine: any tuple satisfies SnapshotAny.
344  */
345 bool
347 {
348  return true;
349 }
350 
351 /*
352  * HeapTupleSatisfiesToast
353  * True iff heap tuple is valid as a TOAST row.
354  *
355  * This is a simplified version that only checks for VACUUM moving conditions.
356  * It's appropriate for TOAST usage because TOAST really doesn't want to do
357  * its own time qual checks; if you can see the main table row that contains
358  * a TOAST reference, you should be able to see the TOASTed value. However,
359  * vacuuming a TOAST table is independent of the main table, and in case such
360  * a vacuum fails partway through, we'd better do this much checking.
361  *
362  * Among other things, this means you can't do UPDATEs of rows in a TOAST
363  * table.
364  */
365 bool
367  Buffer buffer)
368 {
369  HeapTupleHeader tuple = htup->t_data;
370 
372  Assert(htup->t_tableOid != InvalidOid);
373 
374  if (!HeapTupleHeaderXminCommitted(tuple))
375  {
376  if (HeapTupleHeaderXminInvalid(tuple))
377  return false;
378 
379  /* Used by pre-9.0 binary upgrades */
380  if (tuple->t_infomask & HEAP_MOVED_OFF)
381  {
383 
385  return false;
386  if (!TransactionIdIsInProgress(xvac))
387  {
388  if (TransactionIdDidCommit(xvac))
389  {
390  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
392  return false;
393  }
394  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
396  }
397  }
398  /* Used by pre-9.0 binary upgrades */
399  else if (tuple->t_infomask & HEAP_MOVED_IN)
400  {
402 
404  {
405  if (TransactionIdIsInProgress(xvac))
406  return false;
407  if (TransactionIdDidCommit(xvac))
408  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
410  else
411  {
412  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
414  return false;
415  }
416  }
417  }
418 
419  /*
420  * An invalid Xmin can be left behind by a speculative insertion that
421  * is canceled by super-deleting the tuple. This also applies to
422  * TOAST tuples created during speculative insertion.
423  */
425  return false;
426  }
427 
428  /* otherwise assume the tuple is valid for TOAST. */
429  return true;
430 }
431 
432 /*
433  * HeapTupleSatisfiesUpdate
434  *
435  * This function returns a more detailed result code than most of the
436  * functions in this file, since UPDATE needs to know more than "is it
437  * visible?". It also allows for user-supplied CommandId rather than
438  * relying on CurrentCommandId.
439  *
440  * The possible return codes are:
441  *
442  * HeapTupleInvisible: the tuple didn't exist at all when the scan started,
443  * e.g. it was created by a later CommandId.
444  *
445  * HeapTupleMayBeUpdated: The tuple is valid and visible, so it may be
446  * updated.
447  *
448  * HeapTupleSelfUpdated: The tuple was updated by the current transaction,
449  * after the current scan started.
450  *
451  * HeapTupleUpdated: The tuple was updated by a committed transaction.
452  *
453  * HeapTupleBeingUpdated: The tuple is being updated by an in-progress
454  * transaction other than the current transaction. (Note: this includes
455  * the case where the tuple is share-locked by a MultiXact, even if the
456  * MultiXact includes the current transaction. Callers that want to
457  * distinguish that case must test for it themselves.)
458  */
461  Buffer buffer)
462 {
463  HeapTupleHeader tuple = htup->t_data;
464 
466  Assert(htup->t_tableOid != InvalidOid);
467 
468  if (!HeapTupleHeaderXminCommitted(tuple))
469  {
470  if (HeapTupleHeaderXminInvalid(tuple))
471  return HeapTupleInvisible;
472 
473  /* Used by pre-9.0 binary upgrades */
474  if (tuple->t_infomask & HEAP_MOVED_OFF)
475  {
477 
479  return HeapTupleInvisible;
480  if (!TransactionIdIsInProgress(xvac))
481  {
482  if (TransactionIdDidCommit(xvac))
483  {
484  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
486  return HeapTupleInvisible;
487  }
488  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
490  }
491  }
492  /* Used by pre-9.0 binary upgrades */
493  else if (tuple->t_infomask & HEAP_MOVED_IN)
494  {
496 
498  {
499  if (TransactionIdIsInProgress(xvac))
500  return HeapTupleInvisible;
501  if (TransactionIdDidCommit(xvac))
502  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
504  else
505  {
506  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
508  return HeapTupleInvisible;
509  }
510  }
511  }
513  {
514  if (HeapTupleHeaderGetCmin(tuple) >= curcid)
515  return HeapTupleInvisible; /* inserted after scan started */
516 
517  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
518  return HeapTupleMayBeUpdated;
519 
521  {
522  TransactionId xmax;
523 
524  xmax = HeapTupleHeaderGetRawXmax(tuple);
525 
526  /*
527  * Careful here: even though this tuple was created by our own
528  * transaction, it might be locked by other transactions, if
529  * the original version was key-share locked when we updated
530  * it.
531  */
532 
533  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
534  {
535  if (MultiXactIdIsRunning(xmax, true))
536  return HeapTupleBeingUpdated;
537  else
538  return HeapTupleMayBeUpdated;
539  }
540 
541  /*
542  * If the locker is gone, then there is nothing of interest
543  * left in this Xmax; otherwise, report the tuple as
544  * locked/updated.
545  */
546  if (!TransactionIdIsInProgress(xmax))
547  return HeapTupleMayBeUpdated;
548  return HeapTupleBeingUpdated;
549  }
550 
551  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
552  {
553  TransactionId xmax;
554 
555  xmax = HeapTupleGetUpdateXid(tuple);
556 
557  /* not LOCKED_ONLY, so it has to have an xmax */
559 
560  /* deleting subtransaction must have aborted */
562  {
564  false))
565  return HeapTupleBeingUpdated;
566  return HeapTupleMayBeUpdated;
567  }
568  else
569  {
570  if (HeapTupleHeaderGetCmax(tuple) >= curcid)
571  return HeapTupleSelfUpdated; /* updated after scan
572  * started */
573  else
574  return HeapTupleInvisible; /* updated before scan
575  * started */
576  }
577  }
578 
580  {
581  /* deleting subtransaction must have aborted */
582  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
584  return HeapTupleMayBeUpdated;
585  }
586 
587  if (HeapTupleHeaderGetCmax(tuple) >= curcid)
588  return HeapTupleSelfUpdated; /* updated after scan started */
589  else
590  return HeapTupleInvisible; /* updated before scan started */
591  }
593  return HeapTupleInvisible;
595  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
597  else
598  {
599  /* it must have aborted or crashed */
600  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
602  return HeapTupleInvisible;
603  }
604  }
605 
606  /* by here, the inserting transaction has committed */
607 
608  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
609  return HeapTupleMayBeUpdated;
610 
611  if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
612  {
614  return HeapTupleMayBeUpdated;
615  return HeapTupleUpdated; /* updated by other */
616  }
617 
618  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
619  {
620  TransactionId xmax;
621 
622  if (HEAP_LOCKED_UPGRADED(tuple->t_infomask))
623  return HeapTupleMayBeUpdated;
624 
626  {
628  return HeapTupleBeingUpdated;
629 
631  return HeapTupleMayBeUpdated;
632  }
633 
634  xmax = HeapTupleGetUpdateXid(tuple);
635  if (!TransactionIdIsValid(xmax))
636  {
638  return HeapTupleBeingUpdated;
639  }
640 
641  /* not LOCKED_ONLY, so it has to have an xmax */
643 
645  {
646  if (HeapTupleHeaderGetCmax(tuple) >= curcid)
647  return HeapTupleSelfUpdated; /* updated after scan started */
648  else
649  return HeapTupleInvisible; /* updated before scan started */
650  }
651 
653  return HeapTupleBeingUpdated;
654 
655  if (TransactionIdDidCommit(xmax))
656  return HeapTupleUpdated;
657 
658  /*
659  * By here, the update in the Xmax is either aborted or crashed, but
660  * what about the other members?
661  */
662 
664  {
665  /*
666  * There's no member, even just a locker, alive anymore, so we can
667  * mark the Xmax as invalid.
668  */
669  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
671  return HeapTupleMayBeUpdated;
672  }
673  else
674  {
675  /* There are lockers running */
676  return HeapTupleBeingUpdated;
677  }
678  }
679 
681  {
683  return HeapTupleBeingUpdated;
684  if (HeapTupleHeaderGetCmax(tuple) >= curcid)
685  return HeapTupleSelfUpdated; /* updated after scan started */
686  else
687  return HeapTupleInvisible; /* updated before scan started */
688  }
689 
691  return HeapTupleBeingUpdated;
692 
694  {
695  /* it must have aborted or crashed */
696  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
698  return HeapTupleMayBeUpdated;
699  }
700 
701  /* xmax transaction committed */
702 
704  {
705  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
707  return HeapTupleMayBeUpdated;
708  }
709 
710  SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
712  return HeapTupleUpdated; /* updated by other */
713 }
714 
715 /*
716  * HeapTupleSatisfiesDirty
717  * True iff heap tuple is valid including effects of open transactions.
718  *
719  * Here, we consider the effects of:
720  * all committed and in-progress transactions (as of the current instant)
721  * previous commands of this transaction
722  * changes made by the current command
723  *
724  * This is essentially like HeapTupleSatisfiesSelf as far as effects of
725  * the current transaction and committed/aborted xacts are concerned.
726  * However, we also include the effects of other xacts still in progress.
727  *
728  * A special hack is that the passed-in snapshot struct is used as an
729  * output argument to return the xids of concurrent xacts that affected the
730  * tuple. snapshot->xmin is set to the tuple's xmin if that is another
731  * transaction that's still in progress; or to InvalidTransactionId if the
732  * tuple's xmin is committed good, committed dead, or my own xact.
733  * Similarly for snapshot->xmax and the tuple's xmax. If the tuple was
734  * inserted speculatively, meaning that the inserter might still back down
735  * on the insertion without aborting the whole transaction, the associated
736  * token is also returned in snapshot->speculativeToken.
737  */
738 bool
740  Buffer buffer)
741 {
742  HeapTupleHeader tuple = htup->t_data;
743 
745  Assert(htup->t_tableOid != InvalidOid);
746 
747  snapshot->xmin = snapshot->xmax = InvalidTransactionId;
748  snapshot->speculativeToken = 0;
749 
750  if (!HeapTupleHeaderXminCommitted(tuple))
751  {
752  if (HeapTupleHeaderXminInvalid(tuple))
753  return false;
754 
755  /* Used by pre-9.0 binary upgrades */
756  if (tuple->t_infomask & HEAP_MOVED_OFF)
757  {
759 
761  return false;
762  if (!TransactionIdIsInProgress(xvac))
763  {
764  if (TransactionIdDidCommit(xvac))
765  {
766  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
768  return false;
769  }
770  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
772  }
773  }
774  /* Used by pre-9.0 binary upgrades */
775  else if (tuple->t_infomask & HEAP_MOVED_IN)
776  {
778 
780  {
781  if (TransactionIdIsInProgress(xvac))
782  return false;
783  if (TransactionIdDidCommit(xvac))
784  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
786  else
787  {
788  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
790  return false;
791  }
792  }
793  }
795  {
796  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
797  return true;
798 
799  if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
800  return true;
801 
802  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
803  {
804  TransactionId xmax;
805 
806  xmax = HeapTupleGetUpdateXid(tuple);
807 
808  /* not LOCKED_ONLY, so it has to have an xmax */
810 
811  /* updating subtransaction must have aborted */
813  return true;
814  else
815  return false;
816  }
817 
819  {
820  /* deleting subtransaction must have aborted */
821  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
823  return true;
824  }
825 
826  return false;
827  }
829  {
830  /*
831  * Return the speculative token to caller. Caller can worry about
832  * xmax, since it requires a conclusively locked row version, and
833  * a concurrent update to this tuple is a conflict of its
834  * purposes.
835  */
836  if (HeapTupleHeaderIsSpeculative(tuple))
837  {
838  snapshot->speculativeToken =
840 
841  Assert(snapshot->speculativeToken != 0);
842  }
843 
844  snapshot->xmin = HeapTupleHeaderGetRawXmin(tuple);
845  /* XXX shouldn't we fall through to look at xmax? */
846  return true; /* in insertion by other */
847  }
849  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
851  else
852  {
853  /* it must have aborted or crashed */
854  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
856  return false;
857  }
858  }
859 
860  /* by here, the inserting transaction has committed */
861 
862  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
863  return true;
864 
865  if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
866  {
868  return true;
869  return false; /* updated by other */
870  }
871 
872  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
873  {
874  TransactionId xmax;
875 
877  return true;
878 
879  xmax = HeapTupleGetUpdateXid(tuple);
880 
881  /* not LOCKED_ONLY, so it has to have an xmax */
883 
885  return false;
886  if (TransactionIdIsInProgress(xmax))
887  {
888  snapshot->xmax = xmax;
889  return true;
890  }
891  if (TransactionIdDidCommit(xmax))
892  return false;
893  /* it must have aborted or crashed */
894  return true;
895  }
896 
898  {
900  return true;
901  return false;
902  }
903 
905  {
907  snapshot->xmax = HeapTupleHeaderGetRawXmax(tuple);
908  return true;
909  }
910 
912  {
913  /* it must have aborted or crashed */
914  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
916  return true;
917  }
918 
919  /* xmax transaction committed */
920 
922  {
923  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
925  return true;
926  }
927 
928  SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
930  return false; /* updated by other */
931 }
932 
933 /*
934  * HeapTupleSatisfiesMVCC
935  * True iff heap tuple is valid for the given MVCC snapshot.
936  *
937  * Here, we consider the effects of:
938  * all transactions committed as of the time of the given snapshot
939  * previous commands of this transaction
940  *
941  * Does _not_ include:
942  * transactions shown as in-progress by the snapshot
943  * transactions started after the snapshot was taken
944  * changes made by the current command
945  *
946  * Notice that here, we will not update the tuple status hint bits if the
947  * inserting/deleting transaction is still running according to our snapshot,
948  * even if in reality it's committed or aborted by now. This is intentional.
949  * Checking the true transaction state would require access to high-traffic
950  * shared data structures, creating contention we'd rather do without, and it
951  * would not change the result of our visibility check anyway. The hint bits
952  * will be updated by the first visitor that has a snapshot new enough to see
953  * the inserting/deleting transaction as done. In the meantime, the cost of
954  * leaving the hint bits unset is basically that each HeapTupleSatisfiesMVCC
955  * call will need to run TransactionIdIsCurrentTransactionId in addition to
956  * XidInMVCCSnapshot (but it would have to do the latter anyway). In the old
957  * coding where we tried to set the hint bits as soon as possible, we instead
958  * did TransactionIdIsInProgress in each call --- to no avail, as long as the
959  * inserting/deleting transaction was still running --- which was more cycles
960  * and more contention on the PGXACT array.
961  */
962 bool
964  Buffer buffer)
965 {
966  HeapTupleHeader tuple = htup->t_data;
967 
969  Assert(htup->t_tableOid != InvalidOid);
970 
971  if (!HeapTupleHeaderXminCommitted(tuple))
972  {
973  if (HeapTupleHeaderXminInvalid(tuple))
974  return false;
975 
976  /* Used by pre-9.0 binary upgrades */
977  if (tuple->t_infomask & HEAP_MOVED_OFF)
978  {
980 
982  return false;
983  if (!XidInMVCCSnapshot(xvac, snapshot))
984  {
985  if (TransactionIdDidCommit(xvac))
986  {
987  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
989  return false;
990  }
991  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
993  }
994  }
995  /* Used by pre-9.0 binary upgrades */
996  else if (tuple->t_infomask & HEAP_MOVED_IN)
997  {
999 
1001  {
1002  if (XidInMVCCSnapshot(xvac, snapshot))
1003  return false;
1004  if (TransactionIdDidCommit(xvac))
1005  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
1007  else
1008  {
1009  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
1011  return false;
1012  }
1013  }
1014  }
1016  {
1017  if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)
1018  return false; /* inserted after scan started */
1019 
1020  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
1021  return true;
1022 
1023  if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
1024  return true;
1025 
1026  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1027  {
1028  TransactionId xmax;
1029 
1030  xmax = HeapTupleGetUpdateXid(tuple);
1031 
1032  /* not LOCKED_ONLY, so it has to have an xmax */
1034 
1035  /* updating subtransaction must have aborted */
1037  return true;
1038  else if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
1039  return true; /* updated after scan started */
1040  else
1041  return false; /* updated before scan started */
1042  }
1043 
1045  {
1046  /* deleting subtransaction must have aborted */
1047  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
1049  return true;
1050  }
1051 
1052  if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
1053  return true; /* deleted after scan started */
1054  else
1055  return false; /* deleted before scan started */
1056  }
1057  else if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot))
1058  return false;
1060  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
1061  HeapTupleHeaderGetRawXmin(tuple));
1062  else
1063  {
1064  /* it must have aborted or crashed */
1065  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
1067  return false;
1068  }
1069  }
1070  else
1071  {
1072  /* xmin is committed, but maybe not according to our snapshot */
1073  if (!HeapTupleHeaderXminFrozen(tuple) &&
1074  XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot))
1075  return false; /* treat as still in progress */
1076  }
1077 
1078  /* by here, the inserting transaction has committed */
1079 
1080  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
1081  return true;
1082 
1084  return true;
1085 
1086  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1087  {
1088  TransactionId xmax;
1089 
1090  /* already checked above */
1092 
1093  xmax = HeapTupleGetUpdateXid(tuple);
1094 
1095  /* not LOCKED_ONLY, so it has to have an xmax */
1097 
1099  {
1100  if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
1101  return true; /* deleted after scan started */
1102  else
1103  return false; /* deleted before scan started */
1104  }
1105  if (XidInMVCCSnapshot(xmax, snapshot))
1106  return true;
1107  if (TransactionIdDidCommit(xmax))
1108  return false; /* updating transaction committed */
1109  /* it must have aborted or crashed */
1110  return true;
1111  }
1112 
1113  if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
1114  {
1116  {
1117  if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
1118  return true; /* deleted after scan started */
1119  else
1120  return false; /* deleted before scan started */
1121  }
1122 
1123  if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
1124  return true;
1125 
1127  {
1128  /* it must have aborted or crashed */
1129  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
1131  return true;
1132  }
1133 
1134  /* xmax transaction committed */
1135  SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
1136  HeapTupleHeaderGetRawXmax(tuple));
1137  }
1138  else
1139  {
1140  /* xmax is committed, but maybe not according to our snapshot */
1141  if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
1142  return true; /* treat as still in progress */
1143  }
1144 
1145  /* xmax transaction committed */
1146 
1147  return false;
1148 }
1149 
1150 
1151 /*
1152  * HeapTupleSatisfiesVacuum
1153  *
1154  * Determine the status of tuples for VACUUM purposes. Here, what
1155  * we mainly want to know is if a tuple is potentially visible to *any*
1156  * running transaction. If so, it can't be removed yet by VACUUM.
1157  *
1158  * OldestXmin is a cutoff XID (obtained from GetOldestXmin()). Tuples
1159  * deleted by XIDs >= OldestXmin are deemed "recently dead"; they might
1160  * still be visible to some open transaction, so we can't remove them,
1161  * even if we see that the deleting transaction has committed.
1162  */
1165  Buffer buffer)
1166 {
1167  HeapTupleHeader tuple = htup->t_data;
1168 
1169  Assert(ItemPointerIsValid(&htup->t_self));
1170  Assert(htup->t_tableOid != InvalidOid);
1171 
1172  /*
1173  * Has inserting transaction committed?
1174  *
1175  * If the inserting transaction aborted, then the tuple was never visible
1176  * to any other transaction, so we can delete it immediately.
1177  */
1178  if (!HeapTupleHeaderXminCommitted(tuple))
1179  {
1180  if (HeapTupleHeaderXminInvalid(tuple))
1181  return HEAPTUPLE_DEAD;
1182  /* Used by pre-9.0 binary upgrades */
1183  else if (tuple->t_infomask & HEAP_MOVED_OFF)
1184  {
1185  TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
1186 
1189  if (TransactionIdIsInProgress(xvac))
1191  if (TransactionIdDidCommit(xvac))
1192  {
1193  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
1195  return HEAPTUPLE_DEAD;
1196  }
1197  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
1199  }
1200  /* Used by pre-9.0 binary upgrades */
1201  else if (tuple->t_infomask & HEAP_MOVED_IN)
1202  {
1203  TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
1204 
1207  if (TransactionIdIsInProgress(xvac))
1209  if (TransactionIdDidCommit(xvac))
1210  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
1212  else
1213  {
1214  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
1216  return HEAPTUPLE_DEAD;
1217  }
1218  }
1220  {
1221  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
1223  /* only locked? run infomask-only check first, for performance */
1224  if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask) ||
1227  /* inserted and then deleted by same xact */
1230  /* deleting subtransaction must have aborted */
1232  }
1234  {
1235  /*
1236  * It'd be possible to discern between INSERT/DELETE in progress
1237  * here by looking at xmax - but that doesn't seem beneficial for
1238  * the majority of callers and even detrimental for some. We'd
1239  * rather have callers look at/wait for xmin than xmax. It's
1240  * always correct to return INSERT_IN_PROGRESS because that's
1241  * what's happening from the view of other backends.
1242  */
1244  }
1246  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
1247  HeapTupleHeaderGetRawXmin(tuple));
1248  else
1249  {
1250  /*
1251  * Not in Progress, Not Committed, so either Aborted or crashed
1252  */
1253  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
1255  return HEAPTUPLE_DEAD;
1256  }
1257 
1258  /*
1259  * At this point the xmin is known committed, but we might not have
1260  * been able to set the hint bit yet; so we can no longer Assert that
1261  * it's set.
1262  */
1263  }
1264 
1265  /*
1266  * Okay, the inserter committed, so it was good at some point. Now what
1267  * about the deleting transaction?
1268  */
1269  if (tuple->t_infomask & HEAP_XMAX_INVALID)
1270  return HEAPTUPLE_LIVE;
1271 
1273  {
1274  /*
1275  * "Deleting" xact really only locked it, so the tuple is live in any
1276  * case. However, we should make sure that either XMAX_COMMITTED or
1277  * XMAX_INVALID gets set once the xact is gone, to reduce the costs of
1278  * examining the tuple for future xacts.
1279  */
1280  if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
1281  {
1282  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1283  {
1284  /*
1285  * If it's a pre-pg_upgrade tuple, the multixact cannot
1286  * possibly be running; otherwise have to check.
1287  */
1288  if (!HEAP_LOCKED_UPGRADED(tuple->t_infomask) &&
1290  true))
1291  return HEAPTUPLE_LIVE;
1293  }
1294  else
1295  {
1297  return HEAPTUPLE_LIVE;
1298  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
1300  }
1301  }
1302 
1303  /*
1304  * We don't really care whether xmax did commit, abort or crash. We
1305  * know that xmax did lock the tuple, but it did not and will never
1306  * actually update it.
1307  */
1308 
1309  return HEAPTUPLE_LIVE;
1310  }
1311 
1312  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1313  {
1314  TransactionId xmax;
1315 
1317  {
1318  /* already checked above */
1320 
1321  xmax = HeapTupleGetUpdateXid(tuple);
1322 
1323  /* not LOCKED_ONLY, so it has to have an xmax */
1325 
1326  if (TransactionIdIsInProgress(xmax))
1328  else if (TransactionIdDidCommit(xmax))
1329  /* there are still lockers around -- can't return DEAD here */
1330  return HEAPTUPLE_RECENTLY_DEAD;
1331  /* updating transaction aborted */
1332  return HEAPTUPLE_LIVE;
1333  }
1334 
1335  Assert(!(tuple->t_infomask & HEAP_XMAX_COMMITTED));
1336 
1337  xmax = HeapTupleGetUpdateXid(tuple);
1338 
1339  /* not LOCKED_ONLY, so it has to have an xmax */
1341 
1342  /* multi is not running -- updating xact cannot be */
1344  if (TransactionIdDidCommit(xmax))
1345  {
1346  if (!TransactionIdPrecedes(xmax, OldestXmin))
1347  return HEAPTUPLE_RECENTLY_DEAD;
1348  else
1349  return HEAPTUPLE_DEAD;
1350  }
1351 
1352  /*
1353  * Not in Progress, Not Committed, so either Aborted or crashed.
1354  * Remove the Xmax.
1355  */
1357  return HEAPTUPLE_LIVE;
1358  }
1359 
1360  if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
1361  {
1365  SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
1366  HeapTupleHeaderGetRawXmax(tuple));
1367  else
1368  {
1369  /*
1370  * Not in Progress, Not Committed, so either Aborted or crashed
1371  */
1372  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
1374  return HEAPTUPLE_LIVE;
1375  }
1376 
1377  /*
1378  * At this point the xmax is known committed, but we might not have
1379  * been able to set the hint bit yet; so we can no longer Assert that
1380  * it's set.
1381  */
1382  }
1383 
1384  /*
1385  * Deleter committed, but perhaps it was recent enough that some open
1386  * transactions could still see the tuple.
1387  */
1388  if (!TransactionIdPrecedes(HeapTupleHeaderGetRawXmax(tuple), OldestXmin))
1389  return HEAPTUPLE_RECENTLY_DEAD;
1390 
1391  /* Otherwise, it's dead and removable */
1392  return HEAPTUPLE_DEAD;
1393 }
1394 
1395 /*
1396  * HeapTupleIsSurelyDead
1397  *
1398  * Cheaply determine whether a tuple is surely dead to all onlookers.
1399  * We sometimes use this in lieu of HeapTupleSatisfiesVacuum when the
1400  * tuple has just been tested by another visibility routine (usually
1401  * HeapTupleSatisfiesMVCC) and, therefore, any hint bits that can be set
1402  * should already be set. We assume that if no hint bits are set, the xmin
1403  * or xmax transaction is still running. This is therefore faster than
1404  * HeapTupleSatisfiesVacuum, because we don't consult PGXACT nor CLOG.
1405  * It's okay to return FALSE when in doubt, but we must return TRUE only
1406  * if the tuple is removable.
1407  */
1408 bool
1410 {
1411  HeapTupleHeader tuple = htup->t_data;
1412 
1413  Assert(ItemPointerIsValid(&htup->t_self));
1414  Assert(htup->t_tableOid != InvalidOid);
1415 
1416  /*
1417  * If the inserting transaction is marked invalid, then it aborted, and
1418  * the tuple is definitely dead. If it's marked neither committed nor
1419  * invalid, then we assume it's still alive (since the presumption is that
1420  * all relevant hint bits were just set moments ago).
1421  */
1422  if (!HeapTupleHeaderXminCommitted(tuple))
1423  return HeapTupleHeaderXminInvalid(tuple) ? true : false;
1424 
1425  /*
1426  * If the inserting transaction committed, but any deleting transaction
1427  * aborted, the tuple is still alive.
1428  */
1429  if (tuple->t_infomask & HEAP_XMAX_INVALID)
1430  return false;
1431 
1432  /*
1433  * If the XMAX is just a lock, the tuple is still alive.
1434  */
1436  return false;
1437 
1438  /*
1439  * If the Xmax is a MultiXact, it might be dead or alive, but we cannot
1440  * know without checking pg_multixact.
1441  */
1442  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1443  return false;
1444 
1445  /* If deleter isn't known to have committed, assume it's still running. */
1446  if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
1447  return false;
1448 
1449  /* Deleter committed, so tuple is dead if the XID is old enough. */
1450  return TransactionIdPrecedes(HeapTupleHeaderGetRawXmax(tuple), OldestXmin);
1451 }
1452 
1453 /*
1454  * XidInMVCCSnapshot
1455  * Is the given XID still-in-progress according to the snapshot?
1456  *
1457  * Note: GetSnapshotData never stores either top xid or subxids of our own
1458  * backend into a snapshot, so these xids will not be reported as "running"
1459  * by this function. This is OK for current uses, because we always check
1460  * TransactionIdIsCurrentTransactionId first, except for known-committed
1461  * XIDs which could not be ours anyway.
1462  */
1463 static bool
1465 {
1466  uint32 i;
1467 
1468  /*
1469  * Make a quick range check to eliminate most XIDs without looking at the
1470  * xip arrays. Note that this is OK even if we convert a subxact XID to
1471  * its parent below, because a subxact with XID < xmin has surely also got
1472  * a parent with XID < xmin, while one with XID >= xmax must belong to a
1473  * parent that was not yet committed at the time of this snapshot.
1474  */
1475 
1476  /* Any xid < xmin is not in-progress */
1477  if (TransactionIdPrecedes(xid, snapshot->xmin))
1478  return false;
1479  /* Any xid >= xmax is in-progress */
1480  if (TransactionIdFollowsOrEquals(xid, snapshot->xmax))
1481  return true;
1482 
1483  /*
1484  * Snapshot information is stored slightly differently in snapshots taken
1485  * during recovery.
1486  */
1487  if (!snapshot->takenDuringRecovery)
1488  {
1489  /*
1490  * If the snapshot contains full subxact data, the fastest way to
1491  * check things is just to compare the given XID against both subxact
1492  * XIDs and top-level XIDs. If the snapshot overflowed, we have to
1493  * use pg_subtrans to convert a subxact XID to its parent XID, but
1494  * then we need only look at top-level XIDs not subxacts.
1495  */
1496  if (!snapshot->suboverflowed)
1497  {
1498  /* we have full data, so search subxip */
1499  int32 j;
1500 
1501  for (j = 0; j < snapshot->subxcnt; j++)
1502  {
1503  if (TransactionIdEquals(xid, snapshot->subxip[j]))
1504  return true;
1505  }
1506 
1507  /* not there, fall through to search xip[] */
1508  }
1509  else
1510  {
1511  /*
1512  * Snapshot overflowed, so convert xid to top-level. This is safe
1513  * because we eliminated too-old XIDs above.
1514  */
1515  xid = SubTransGetTopmostTransaction(xid);
1516 
1517  /*
1518  * If xid was indeed a subxact, we might now have an xid < xmin,
1519  * so recheck to avoid an array scan. No point in rechecking
1520  * xmax.
1521  */
1522  if (TransactionIdPrecedes(xid, snapshot->xmin))
1523  return false;
1524  }
1525 
1526  for (i = 0; i < snapshot->xcnt; i++)
1527  {
1528  if (TransactionIdEquals(xid, snapshot->xip[i]))
1529  return true;
1530  }
1531  }
1532  else
1533  {
1534  int32 j;
1535 
1536  /*
1537  * In recovery we store all xids in the subxact array because it is by
1538  * far the bigger array, and we mostly don't know which xids are
1539  * top-level and which are subxacts. The xip array is empty.
1540  *
1541  * We start by searching subtrans, if we overflowed.
1542  */
1543  if (snapshot->suboverflowed)
1544  {
1545  /*
1546  * Snapshot overflowed, so convert xid to top-level. This is safe
1547  * because we eliminated too-old XIDs above.
1548  */
1549  xid = SubTransGetTopmostTransaction(xid);
1550 
1551  /*
1552  * If xid was indeed a subxact, we might now have an xid < xmin,
1553  * so recheck to avoid an array scan. No point in rechecking
1554  * xmax.
1555  */
1556  if (TransactionIdPrecedes(xid, snapshot->xmin))
1557  return false;
1558  }
1559 
1560  /*
1561  * We now have either a top-level xid higher than xmin or an
1562  * indeterminate xid. We don't know whether it's top level or subxact
1563  * but it doesn't matter. If it's present, the xid is visible.
1564  */
1565  for (j = 0; j < snapshot->subxcnt; j++)
1566  {
1567  if (TransactionIdEquals(xid, snapshot->subxip[j]))
1568  return true;
1569  }
1570  }
1571 
1572  return false;
1573 }
1574 
1575 /*
1576  * Is the tuple really only locked? That is, is it not updated?
1577  *
1578  * It's easy to check just infomask bits if the locker is not a multi; but
1579  * otherwise we need to verify that the updating transaction has not aborted.
1580  *
1581  * This function is here because it follows the same time qualification rules
1582  * laid out at the top of this file.
1583  */
1584 bool
1586 {
1587  TransactionId xmax;
1588 
1589  /* if there's no valid Xmax, then there's obviously no update either */
1590  if (tuple->t_infomask & HEAP_XMAX_INVALID)
1591  return true;
1592 
1593  if (tuple->t_infomask & HEAP_XMAX_LOCK_ONLY)
1594  return true;
1595 
1596  /* invalid xmax means no update */
1598  return true;
1599 
1600  /*
1601  * if HEAP_XMAX_LOCK_ONLY is not set and not a multi, then this must
1602  * necessarily have been updated
1603  */
1604  if (!(tuple->t_infomask & HEAP_XMAX_IS_MULTI))
1605  return false;
1606 
1607  /* ... but if it's a multi, then perhaps the updating Xid aborted. */
1608  xmax = HeapTupleGetUpdateXid(tuple);
1609 
1610  /* not LOCKED_ONLY, so it has to have an xmax */
1612 
1614  return false;
1615  if (TransactionIdIsInProgress(xmax))
1616  return false;
1617  if (TransactionIdDidCommit(xmax))
1618  return false;
1619 
1620  /*
1621  * not current, not in progress, not committed -- must have aborted or
1622  * crashed
1623  */
1624  return true;
1625 }
1626 
1627 /*
1628  * check whether the transaction id 'xid' is in the pre-sorted array 'xip'.
1629  */
1630 static bool
1632 {
1633  return bsearch(&xid, xip, num,
1634  sizeof(TransactionId), xidComparator) != NULL;
1635 }
1636 
1637 /*
1638  * See the comments for HeapTupleSatisfiesMVCC for the semantics this function
1639  * obeys.
1640  *
1641  * Only usable on tuples from catalog tables!
1642  *
1643  * We don't need to support HEAP_MOVED_(IN|OFF) for now because we only support
1644  * reading catalog pages which couldn't have been created in an older version.
1645  *
1646  * We don't set any hint bits in here as it seems unlikely to be beneficial as
1647  * those should already be set by normal access and it seems to be too
1648  * dangerous to do so as the semantics of doing so during timetravel are more
1649  * complicated than when dealing "only" with the present.
1650  */
1651 bool
1653  Buffer buffer)
1654 {
1655  HeapTupleHeader tuple = htup->t_data;
1656  TransactionId xmin = HeapTupleHeaderGetXmin(tuple);
1658 
1659  Assert(ItemPointerIsValid(&htup->t_self));
1660  Assert(htup->t_tableOid != InvalidOid);
1661 
1662  /* inserting transaction aborted */
1663  if (HeapTupleHeaderXminInvalid(tuple))
1664  {
1666  return false;
1667  }
1668  /* check if it's one of our txids, toplevel is also in there */
1669  else if (TransactionIdInArray(xmin, snapshot->subxip, snapshot->subxcnt))
1670  {
1671  bool resolved;
1673  CommandId cmax = InvalidCommandId;
1674 
1675  /*
1676  * another transaction might have (tried to) delete this tuple or
1677  * cmin/cmax was stored in a combocid. So we need to lookup the actual
1678  * values externally.
1679  */
1681  htup, buffer,
1682  &cmin, &cmax);
1683 
1684  if (!resolved)
1685  elog(ERROR, "could not resolve cmin/cmax of catalog tuple");
1686 
1687  Assert(cmin != InvalidCommandId);
1688 
1689  if (cmin >= snapshot->curcid)
1690  return false; /* inserted after scan started */
1691  /* fall through */
1692  }
1693  /* committed before our xmin horizon. Do a normal visibility check. */
1694  else if (TransactionIdPrecedes(xmin, snapshot->xmin))
1695  {
1697  !TransactionIdDidCommit(xmin)));
1698 
1699  /* check for hint bit first, consult clog afterwards */
1700  if (!HeapTupleHeaderXminCommitted(tuple) &&
1701  !TransactionIdDidCommit(xmin))
1702  return false;
1703  /* fall through */
1704  }
1705  /* beyond our xmax horizon, i.e. invisible */
1706  else if (TransactionIdFollowsOrEquals(xmin, snapshot->xmax))
1707  {
1708  return false;
1709  }
1710  /* check if it's a committed transaction in [xmin, xmax) */
1711  else if (TransactionIdInArray(xmin, snapshot->xip, snapshot->xcnt))
1712  {
1713  /* fall through */
1714  }
1715 
1716  /*
1717  * none of the above, i.e. between [xmin, xmax) but hasn't committed. I.e.
1718  * invisible.
1719  */
1720  else
1721  {
1722  return false;
1723  }
1724 
1725  /* at this point we know xmin is visible, go on to check xmax */
1726 
1727  /* xid invalid or aborted */
1728  if (tuple->t_infomask & HEAP_XMAX_INVALID)
1729  return true;
1730  /* locked tuples are always visible */
1731  else if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
1732  return true;
1733 
1734  /*
1735  * We can see multis here if we're looking at user tables or if somebody
1736  * SELECT ... FOR SHARE/UPDATE a system table.
1737  */
1738  else if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1739  {
1740  xmax = HeapTupleGetUpdateXid(tuple);
1741  }
1742 
1743  /* check if it's one of our txids, toplevel is also in there */
1744  if (TransactionIdInArray(xmax, snapshot->subxip, snapshot->subxcnt))
1745  {
1746  bool resolved;
1747  CommandId cmin;
1749 
1750  /* Lookup actual cmin/cmax values */
1752  htup, buffer,
1753  &cmin, &cmax);
1754 
1755  if (!resolved)
1756  elog(ERROR, "could not resolve combocid to cmax");
1757 
1758  Assert(cmax != InvalidCommandId);
1759 
1760  if (cmax >= snapshot->curcid)
1761  return true; /* deleted after scan started */
1762  else
1763  return false; /* deleted before scan started */
1764  }
1765  /* below xmin horizon, normal transaction state is valid */
1766  else if (TransactionIdPrecedes(xmax, snapshot->xmin))
1767  {
1768  Assert(!(tuple->t_infomask & HEAP_XMAX_COMMITTED &&
1769  !TransactionIdDidCommit(xmax)));
1770 
1771  /* check hint bit first */
1772  if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
1773  return false;
1774 
1775  /* check clog */
1776  return !TransactionIdDidCommit(xmax);
1777  }
1778  /* above xmax horizon, we cannot possibly see the deleting transaction */
1779  else if (TransactionIdFollowsOrEquals(xmax, snapshot->xmax))
1780  return true;
1781  /* xmax is between [xmin, xmax), check known committed array */
1782  else if (TransactionIdInArray(xmax, snapshot->xip, snapshot->xcnt))
1783  return false;
1784  /* xmax is between [xmin, xmax), but known not to have committed yet */
1785  else
1786  return true;
1787 }
#define HeapTupleHeaderGetUpdateXid(tup)
Definition: htup_details.h:359
bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple)
Definition: tqual.c:1585
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:59
uint32 CommandId
Definition: c.h:411
#define HEAP_XMAX_LOCK_ONLY
Definition: htup_details.h:182
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
#define HeapTupleHeaderGetSpeculativeToken(tup)
Definition: htup_details.h:428
uint32 TransactionId
Definition: c.h:397
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
Definition: bufmgr.c:3379
HTSU_Result HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, Buffer buffer)
Definition: tqual.c:460
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:773
TransactionId SubTransGetTopmostTransaction(TransactionId xid)
Definition: subtrans.c:149
bool XLogNeedsFlush(XLogRecPtr record)
Definition: xlog.c:3078
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:998
TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple)
Definition: heapam.c:6929
SnapshotData SnapshotAnyData
Definition: tqual.c:80
CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup)
Definition: combocid.c:105
static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
Definition: tqual.c:1464
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
#define HeapTupleHeaderIsSpeculative(tup)
Definition: htup_details.h:423
#define HEAP_LOCKED_UPGRADED(infomask)
Definition: htup_details.h:238
HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin, Buffer buffer)
Definition: tqual.c:1164
bool suboverflowed
Definition: snapshot.h:91
#define HeapTupleHeaderXminInvalid(tup)
Definition: htup_details.h:323
#define HEAP_XMAX_COMMITTED
Definition: htup_details.h:192
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
HTSV_Result
Definition: tqual.h:49
bool HeapTupleIsSurelyDead(HeapTuple htup, TransactionId OldestXmin)
Definition: tqual.c:1409
signed int int32
Definition: c.h:256
bool HeapTupleSatisfiesAny(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:346
HeapTupleHeader t_data
Definition: htup.h:67
#define HEAP_XMIN_INVALID
Definition: htup_details.h:190
bool HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:366
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:369
unsigned short uint16
Definition: c.h:267
void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
Definition: tqual.c:144
#define ERROR
Definition: elog.h:43
bool HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:176
#define HEAP_XMAX_INVALID
Definition: htup_details.h:193
ItemPointerData t_self
Definition: htup.h:65
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:318
XLogRecPtr BufferGetLSNAtomic(Buffer buffer)
Definition: bufmgr.c:2832
#define InvalidTransactionId
Definition: transam.h:31
#define HeapTupleHeaderGetXvac(tup)
Definition: htup_details.h:409
HTSU_Result
Definition: snapshot.h:119
static TransactionId OldestXmin
Definition: vacuumlazy.c:139
unsigned int uint32
Definition: c.h:268
Oid t_tableOid
Definition: htup.h:66
static bool TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num)
Definition: tqual.c:1631
TransactionId xmax
Definition: snapshot.h:67
TransactionId xmin
Definition: snapshot.h:66
#define HEAP_MOVED_IN
Definition: htup_details.h:199
bool BufferIsPermanent(Buffer buffer)
Definition: bufmgr.c:2802
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
TransactionId * xip
Definition: snapshot.h:77
XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid)
Definition: transam.c:402
bool HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:1652
#define InvalidCommandId
Definition: c.h:414
#define HEAP_XMAX_IS_LOCKED_ONLY(infomask)
Definition: htup_details.h:216
#define HeapTupleHeaderXminFrozen(tup)
Definition: htup_details.h:329
#define HEAP_XMAX_IS_MULTI
Definition: htup_details.h:194
#define HEAP_XMIN_COMMITTED
Definition: htup_details.h:189
#define InvalidOid
Definition: postgres_ext.h:36
CommandId curcid
Definition: snapshot.h:96
static void SetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
Definition: tqual.c:117
uint32 speculativeToken
Definition: snapshot.h:102
#define NULL
Definition: c.h:229
#define HEAP_MOVED_OFF
Definition: htup_details.h:196
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:675
CommandId HeapTupleHeaderGetCmax(HeapTupleHeader tup)
Definition: combocid.c:119
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:207
bool takenDuringRecovery
Definition: snapshot.h:93
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:307
size_t Size
Definition: c.h:356
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:302
#define HeapTupleHeaderGetRawCommandId(tup)
Definition: htup_details.h:385
HTAB * HistoricSnapshotGetTupleCids(void)
Definition: snapmgr.c:1987
uint32 xcnt
Definition: snapshot.h:78
int i
SnapshotData SnapshotSelfData
Definition: tqual.c:79
#define elog
Definition: elog.h:219
#define TransactionIdIsValid(xid)
Definition: transam.h:41
bool HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:963
int Buffer
Definition: buf.h:23
bool MultiXactIdIsRunning(MultiXactId multi, bool isLockOnly)
Definition: multixact.c:549
bool HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:739
TransactionId * subxip
Definition: snapshot.h:89
int xidComparator(const void *arg1, const void *arg2)
Definition: xid.c:138
int32 subxcnt
Definition: snapshot.h:90
bool ResolveCminCmaxDuringDecoding(HTAB *tuplecid_data, Snapshot snapshot, HeapTuple htup, Buffer buffer, CommandId *cmin, CommandId *cmax)