PostgreSQL Source Code  git master
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  * HeapTupleSatisfiesNonVacuumable()
49  * Snapshot-style API for HeapTupleSatisfiesVacuum
50  * HeapTupleSatisfiesToast()
51  * visible unless part of interrupted vacuum, used for TOAST
52  * HeapTupleSatisfiesAny()
53  * all tuples are visible
54  *
55  * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
56  * Portions Copyright (c) 1994, Regents of the University of California
57  *
58  * IDENTIFICATION
59  * src/backend/utils/time/tqual.c
60  *
61  *-------------------------------------------------------------------------
62  */
63 
64 #include "postgres.h"
65 
66 #include "access/htup_details.h"
67 #include "access/multixact.h"
68 #include "access/subtrans.h"
69 #include "access/transam.h"
70 #include "access/xact.h"
71 #include "access/xlog.h"
72 #include "storage/bufmgr.h"
73 #include "storage/procarray.h"
74 #include "utils/builtins.h"
75 #include "utils/combocid.h"
76 #include "utils/snapmgr.h"
77 #include "utils/tqual.h"
78 
79 
80 /* Static variables representing various special snapshot semantics */
83 
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 = HeapTupleGetUpdateXid(tuple);
1315 
1316  /* already checked above */
1318 
1319  /* not LOCKED_ONLY, so it has to have an xmax */
1321 
1322  if (TransactionIdIsInProgress(xmax))
1324  else if (TransactionIdDidCommit(xmax))
1325  {
1326  /*
1327  * The multixact might still be running due to lockers. If the
1328  * updater is below the xid horizon, we have to return DEAD
1329  * regardless -- otherwise we could end up with a tuple where the
1330  * updater has to be removed due to the horizon, but is not pruned
1331  * away. It's not a problem to prune that tuple, because any
1332  * remaining lockers will also be present in newer tuple versions.
1333  */
1334  if (!TransactionIdPrecedes(xmax, OldestXmin))
1335  return HEAPTUPLE_RECENTLY_DEAD;
1336 
1337  return HEAPTUPLE_DEAD;
1338  }
1339  else if (!MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
1340  {
1341  /*
1342  * Not in Progress, Not Committed, so either Aborted or crashed.
1343  * Mark the Xmax as invalid.
1344  */
1346  }
1347 
1348  return HEAPTUPLE_LIVE;
1349  }
1350 
1351  if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
1352  {
1356  SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
1357  HeapTupleHeaderGetRawXmax(tuple));
1358  else
1359  {
1360  /*
1361  * Not in Progress, Not Committed, so either Aborted or crashed
1362  */
1363  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
1365  return HEAPTUPLE_LIVE;
1366  }
1367 
1368  /*
1369  * At this point the xmax is known committed, but we might not have
1370  * been able to set the hint bit yet; so we can no longer Assert that
1371  * it's set.
1372  */
1373  }
1374 
1375  /*
1376  * Deleter committed, but perhaps it was recent enough that some open
1377  * transactions could still see the tuple.
1378  */
1379  if (!TransactionIdPrecedes(HeapTupleHeaderGetRawXmax(tuple), OldestXmin))
1380  return HEAPTUPLE_RECENTLY_DEAD;
1381 
1382  /* Otherwise, it's dead and removable */
1383  return HEAPTUPLE_DEAD;
1384 }
1385 
1386 
1387 /*
1388  * HeapTupleSatisfiesNonVacuumable
1389  *
1390  * True if tuple might be visible to some transaction; false if it's
1391  * surely dead to everyone, ie, vacuumable.
1392  *
1393  * This is an interface to HeapTupleSatisfiesVacuum that meets the
1394  * SnapshotSatisfiesFunc API, so it can be used through a Snapshot.
1395  * snapshot->xmin must have been set up with the xmin horizon to use.
1396  */
1397 bool
1399  Buffer buffer)
1400 {
1401  return HeapTupleSatisfiesVacuum(htup, snapshot->xmin, buffer)
1402  != HEAPTUPLE_DEAD;
1403 }
1404 
1405 
1406 /*
1407  * HeapTupleIsSurelyDead
1408  *
1409  * Cheaply determine whether a tuple is surely dead to all onlookers.
1410  * We sometimes use this in lieu of HeapTupleSatisfiesVacuum when the
1411  * tuple has just been tested by another visibility routine (usually
1412  * HeapTupleSatisfiesMVCC) and, therefore, any hint bits that can be set
1413  * should already be set. We assume that if no hint bits are set, the xmin
1414  * or xmax transaction is still running. This is therefore faster than
1415  * HeapTupleSatisfiesVacuum, because we don't consult PGXACT nor CLOG.
1416  * It's okay to return false when in doubt, but we must return true only
1417  * if the tuple is removable.
1418  */
1419 bool
1421 {
1422  HeapTupleHeader tuple = htup->t_data;
1423 
1424  Assert(ItemPointerIsValid(&htup->t_self));
1425  Assert(htup->t_tableOid != InvalidOid);
1426 
1427  /*
1428  * If the inserting transaction is marked invalid, then it aborted, and
1429  * the tuple is definitely dead. If it's marked neither committed nor
1430  * invalid, then we assume it's still alive (since the presumption is that
1431  * all relevant hint bits were just set moments ago).
1432  */
1433  if (!HeapTupleHeaderXminCommitted(tuple))
1434  return HeapTupleHeaderXminInvalid(tuple) ? true : false;
1435 
1436  /*
1437  * If the inserting transaction committed, but any deleting transaction
1438  * aborted, the tuple is still alive.
1439  */
1440  if (tuple->t_infomask & HEAP_XMAX_INVALID)
1441  return false;
1442 
1443  /*
1444  * If the XMAX is just a lock, the tuple is still alive.
1445  */
1447  return false;
1448 
1449  /*
1450  * If the Xmax is a MultiXact, it might be dead or alive, but we cannot
1451  * know without checking pg_multixact.
1452  */
1453  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1454  return false;
1455 
1456  /* If deleter isn't known to have committed, assume it's still running. */
1457  if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
1458  return false;
1459 
1460  /* Deleter committed, so tuple is dead if the XID is old enough. */
1461  return TransactionIdPrecedes(HeapTupleHeaderGetRawXmax(tuple), OldestXmin);
1462 }
1463 
1464 /*
1465  * XidInMVCCSnapshot
1466  * Is the given XID still-in-progress according to the snapshot?
1467  *
1468  * Note: GetSnapshotData never stores either top xid or subxids of our own
1469  * backend into a snapshot, so these xids will not be reported as "running"
1470  * by this function. This is OK for current uses, because we always check
1471  * TransactionIdIsCurrentTransactionId first, except when it's known the
1472  * XID could not be ours anyway.
1473  */
1474 bool
1476 {
1477  uint32 i;
1478 
1479  /*
1480  * Make a quick range check to eliminate most XIDs without looking at the
1481  * xip arrays. Note that this is OK even if we convert a subxact XID to
1482  * its parent below, because a subxact with XID < xmin has surely also got
1483  * a parent with XID < xmin, while one with XID >= xmax must belong to a
1484  * parent that was not yet committed at the time of this snapshot.
1485  */
1486 
1487  /* Any xid < xmin is not in-progress */
1488  if (TransactionIdPrecedes(xid, snapshot->xmin))
1489  return false;
1490  /* Any xid >= xmax is in-progress */
1491  if (TransactionIdFollowsOrEquals(xid, snapshot->xmax))
1492  return true;
1493 
1494  /*
1495  * Snapshot information is stored slightly differently in snapshots taken
1496  * during recovery.
1497  */
1498  if (!snapshot->takenDuringRecovery)
1499  {
1500  /*
1501  * If the snapshot contains full subxact data, the fastest way to
1502  * check things is just to compare the given XID against both subxact
1503  * XIDs and top-level XIDs. If the snapshot overflowed, we have to
1504  * use pg_subtrans to convert a subxact XID to its parent XID, but
1505  * then we need only look at top-level XIDs not subxacts.
1506  */
1507  if (!snapshot->suboverflowed)
1508  {
1509  /* we have full data, so search subxip */
1510  int32 j;
1511 
1512  for (j = 0; j < snapshot->subxcnt; j++)
1513  {
1514  if (TransactionIdEquals(xid, snapshot->subxip[j]))
1515  return true;
1516  }
1517 
1518  /* not there, fall through to search xip[] */
1519  }
1520  else
1521  {
1522  /*
1523  * Snapshot overflowed, so convert xid to top-level. This is safe
1524  * because we eliminated too-old XIDs above.
1525  */
1526  xid = SubTransGetTopmostTransaction(xid);
1527 
1528  /*
1529  * If xid was indeed a subxact, we might now have an xid < xmin,
1530  * so recheck to avoid an array scan. No point in rechecking
1531  * xmax.
1532  */
1533  if (TransactionIdPrecedes(xid, snapshot->xmin))
1534  return false;
1535  }
1536 
1537  for (i = 0; i < snapshot->xcnt; i++)
1538  {
1539  if (TransactionIdEquals(xid, snapshot->xip[i]))
1540  return true;
1541  }
1542  }
1543  else
1544  {
1545  int32 j;
1546 
1547  /*
1548  * In recovery we store all xids in the subxact array because it is by
1549  * far the bigger array, and we mostly don't know which xids are
1550  * top-level and which are subxacts. The xip array is empty.
1551  *
1552  * We start by searching subtrans, if we overflowed.
1553  */
1554  if (snapshot->suboverflowed)
1555  {
1556  /*
1557  * Snapshot overflowed, so convert xid to top-level. This is safe
1558  * because we eliminated too-old XIDs above.
1559  */
1560  xid = SubTransGetTopmostTransaction(xid);
1561 
1562  /*
1563  * If xid was indeed a subxact, we might now have an xid < xmin,
1564  * so recheck to avoid an array scan. No point in rechecking
1565  * xmax.
1566  */
1567  if (TransactionIdPrecedes(xid, snapshot->xmin))
1568  return false;
1569  }
1570 
1571  /*
1572  * We now have either a top-level xid higher than xmin or an
1573  * indeterminate xid. We don't know whether it's top level or subxact
1574  * but it doesn't matter. If it's present, the xid is visible.
1575  */
1576  for (j = 0; j < snapshot->subxcnt; j++)
1577  {
1578  if (TransactionIdEquals(xid, snapshot->subxip[j]))
1579  return true;
1580  }
1581  }
1582 
1583  return false;
1584 }
1585 
1586 /*
1587  * Is the tuple really only locked? That is, is it not updated?
1588  *
1589  * It's easy to check just infomask bits if the locker is not a multi; but
1590  * otherwise we need to verify that the updating transaction has not aborted.
1591  *
1592  * This function is here because it follows the same time qualification rules
1593  * laid out at the top of this file.
1594  */
1595 bool
1597 {
1598  TransactionId xmax;
1599 
1600  /* if there's no valid Xmax, then there's obviously no update either */
1601  if (tuple->t_infomask & HEAP_XMAX_INVALID)
1602  return true;
1603 
1604  if (tuple->t_infomask & HEAP_XMAX_LOCK_ONLY)
1605  return true;
1606 
1607  /* invalid xmax means no update */
1609  return true;
1610 
1611  /*
1612  * if HEAP_XMAX_LOCK_ONLY is not set and not a multi, then this must
1613  * necessarily have been updated
1614  */
1615  if (!(tuple->t_infomask & HEAP_XMAX_IS_MULTI))
1616  return false;
1617 
1618  /* ... but if it's a multi, then perhaps the updating Xid aborted. */
1619  xmax = HeapTupleGetUpdateXid(tuple);
1620 
1621  /* not LOCKED_ONLY, so it has to have an xmax */
1623 
1625  return false;
1626  if (TransactionIdIsInProgress(xmax))
1627  return false;
1628  if (TransactionIdDidCommit(xmax))
1629  return false;
1630 
1631  /*
1632  * not current, not in progress, not committed -- must have aborted or
1633  * crashed
1634  */
1635  return true;
1636 }
1637 
1638 /*
1639  * check whether the transaction id 'xid' is in the pre-sorted array 'xip'.
1640  */
1641 static bool
1643 {
1644  return bsearch(&xid, xip, num,
1645  sizeof(TransactionId), xidComparator) != NULL;
1646 }
1647 
1648 /*
1649  * See the comments for HeapTupleSatisfiesMVCC for the semantics this function
1650  * obeys.
1651  *
1652  * Only usable on tuples from catalog tables!
1653  *
1654  * We don't need to support HEAP_MOVED_(IN|OFF) for now because we only support
1655  * reading catalog pages which couldn't have been created in an older version.
1656  *
1657  * We don't set any hint bits in here as it seems unlikely to be beneficial as
1658  * those should already be set by normal access and it seems to be too
1659  * dangerous to do so as the semantics of doing so during timetravel are more
1660  * complicated than when dealing "only" with the present.
1661  */
1662 bool
1664  Buffer buffer)
1665 {
1666  HeapTupleHeader tuple = htup->t_data;
1667  TransactionId xmin = HeapTupleHeaderGetXmin(tuple);
1669 
1670  Assert(ItemPointerIsValid(&htup->t_self));
1671  Assert(htup->t_tableOid != InvalidOid);
1672 
1673  /* inserting transaction aborted */
1674  if (HeapTupleHeaderXminInvalid(tuple))
1675  {
1677  return false;
1678  }
1679  /* check if it's one of our txids, toplevel is also in there */
1680  else if (TransactionIdInArray(xmin, snapshot->subxip, snapshot->subxcnt))
1681  {
1682  bool resolved;
1684  CommandId cmax = InvalidCommandId;
1685 
1686  /*
1687  * another transaction might have (tried to) delete this tuple or
1688  * cmin/cmax was stored in a combocid. So we need to lookup the actual
1689  * values externally.
1690  */
1692  htup, buffer,
1693  &cmin, &cmax);
1694 
1695  if (!resolved)
1696  elog(ERROR, "could not resolve cmin/cmax of catalog tuple");
1697 
1698  Assert(cmin != InvalidCommandId);
1699 
1700  if (cmin >= snapshot->curcid)
1701  return false; /* inserted after scan started */
1702  /* fall through */
1703  }
1704  /* committed before our xmin horizon. Do a normal visibility check. */
1705  else if (TransactionIdPrecedes(xmin, snapshot->xmin))
1706  {
1708  !TransactionIdDidCommit(xmin)));
1709 
1710  /* check for hint bit first, consult clog afterwards */
1711  if (!HeapTupleHeaderXminCommitted(tuple) &&
1712  !TransactionIdDidCommit(xmin))
1713  return false;
1714  /* fall through */
1715  }
1716  /* beyond our xmax horizon, i.e. invisible */
1717  else if (TransactionIdFollowsOrEquals(xmin, snapshot->xmax))
1718  {
1719  return false;
1720  }
1721  /* check if it's a committed transaction in [xmin, xmax) */
1722  else if (TransactionIdInArray(xmin, snapshot->xip, snapshot->xcnt))
1723  {
1724  /* fall through */
1725  }
1726 
1727  /*
1728  * none of the above, i.e. between [xmin, xmax) but hasn't committed. I.e.
1729  * invisible.
1730  */
1731  else
1732  {
1733  return false;
1734  }
1735 
1736  /* at this point we know xmin is visible, go on to check xmax */
1737 
1738  /* xid invalid or aborted */
1739  if (tuple->t_infomask & HEAP_XMAX_INVALID)
1740  return true;
1741  /* locked tuples are always visible */
1742  else if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
1743  return true;
1744 
1745  /*
1746  * We can see multis here if we're looking at user tables or if somebody
1747  * SELECT ... FOR SHARE/UPDATE a system table.
1748  */
1749  else if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1750  {
1751  xmax = HeapTupleGetUpdateXid(tuple);
1752  }
1753 
1754  /* check if it's one of our txids, toplevel is also in there */
1755  if (TransactionIdInArray(xmax, snapshot->subxip, snapshot->subxcnt))
1756  {
1757  bool resolved;
1758  CommandId cmin;
1760 
1761  /* Lookup actual cmin/cmax values */
1763  htup, buffer,
1764  &cmin, &cmax);
1765 
1766  if (!resolved)
1767  elog(ERROR, "could not resolve combocid to cmax");
1768 
1769  Assert(cmax != InvalidCommandId);
1770 
1771  if (cmax >= snapshot->curcid)
1772  return true; /* deleted after scan started */
1773  else
1774  return false; /* deleted before scan started */
1775  }
1776  /* below xmin horizon, normal transaction state is valid */
1777  else if (TransactionIdPrecedes(xmax, snapshot->xmin))
1778  {
1779  Assert(!(tuple->t_infomask & HEAP_XMAX_COMMITTED &&
1780  !TransactionIdDidCommit(xmax)));
1781 
1782  /* check hint bit first */
1783  if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
1784  return false;
1785 
1786  /* check clog */
1787  return !TransactionIdDidCommit(xmax);
1788  }
1789  /* above xmax horizon, we cannot possibly see the deleting transaction */
1790  else if (TransactionIdFollowsOrEquals(xmax, snapshot->xmax))
1791  return true;
1792  /* xmax is between [xmin, xmax), check known committed array */
1793  else if (TransactionIdInArray(xmax, snapshot->xip, snapshot->xcnt))
1794  return false;
1795  /* xmax is between [xmin, xmax), but known not to have committed yet */
1796  else
1797  return true;
1798 }
#define HeapTupleHeaderGetUpdateXid(tup)
Definition: htup_details.h:364
bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple)
Definition: tqual.c:1596
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:60
uint32 CommandId
Definition: c.h:477
bool HeapTupleSatisfiesNonVacuumable(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:1398
#define HEAP_XMAX_LOCK_ONLY
Definition: htup_details.h:187
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
#define HeapTupleHeaderGetSpeculativeToken(tup)
Definition: htup_details.h:433
uint32 TransactionId
Definition: c.h:463
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:766
TransactionId SubTransGetTopmostTransaction(TransactionId xid)
Definition: subtrans.c:150
bool XLogNeedsFlush(XLogRecPtr record)
Definition: xlog.c:3084
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:999
TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple)
Definition: heapam.c:7078
SnapshotData SnapshotAnyData
Definition: tqual.c:82
CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup)
Definition: combocid.c:105
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
#define HeapTupleHeaderIsSpeculative(tup)
Definition: htup_details.h:428
#define HEAP_LOCKED_UPGRADED(infomask)
Definition: htup_details.h:243
HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin, Buffer buffer)
Definition: tqual.c:1164
bool suboverflowed
Definition: snapshot.h:93
#define HeapTupleHeaderXminInvalid(tup)
Definition: htup_details.h:328
#define HEAP_XMAX_COMMITTED
Definition: htup_details.h:197
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
HTSV_Result
Definition: tqual.h:49
bool HeapTupleIsSurelyDead(HeapTuple htup, TransactionId OldestXmin)
Definition: tqual.c:1420
signed int int32
Definition: c.h:302
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:195
bool HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:366
#define true
Definition: c.h:269
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:374
unsigned short uint16
Definition: c.h:313
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:198
ItemPointerData t_self
Definition: htup.h:65
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:323
XLogRecPtr BufferGetLSNAtomic(Buffer buffer)
Definition: bufmgr.c:2832
#define InvalidTransactionId
Definition: transam.h:31
#define HeapTupleHeaderGetXvac(tup)
Definition: htup_details.h:414
HTSU_Result
Definition: snapshot.h:121
static TransactionId OldestXmin
Definition: vacuumlazy.c:138
unsigned int uint32
Definition: c.h:314
Oid t_tableOid
Definition: htup.h:66
static bool TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num)
Definition: tqual.c:1642
TransactionId xmax
Definition: snapshot.h:69
TransactionId xmin
Definition: snapshot.h:68
#define HEAP_MOVED_IN
Definition: htup_details.h:204
bool BufferIsPermanent(Buffer buffer)
Definition: bufmgr.c:2802
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
TransactionId * xip
Definition: snapshot.h:79
XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid)
Definition: transam.c:402
bool HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:1663
#define InvalidCommandId
Definition: c.h:480
#define HEAP_XMAX_IS_LOCKED_ONLY(infomask)
Definition: htup_details.h:221
#define HeapTupleHeaderXminFrozen(tup)
Definition: htup_details.h:334
#define HEAP_XMAX_IS_MULTI
Definition: htup_details.h:199
#define HEAP_XMIN_COMMITTED
Definition: htup_details.h:194
#define InvalidOid
Definition: postgres_ext.h:36
CommandId curcid
Definition: snapshot.h:98
static void SetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
Definition: tqual.c:117
uint32 speculativeToken
Definition: snapshot.h:104
#define HEAP_MOVED_OFF
Definition: htup_details.h:201
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:688
CommandId HeapTupleHeaderGetCmax(HeapTupleHeader tup)
Definition: combocid.c:119
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:215
bool takenDuringRecovery
Definition: snapshot.h:95
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:312
size_t Size
Definition: c.h:422
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:307
#define HeapTupleHeaderGetRawCommandId(tup)
Definition: htup_details.h:390
HTAB * HistoricSnapshotGetTupleCids(void)
Definition: snapmgr.c:2030
uint32 xcnt
Definition: snapshot.h:80
int i
SnapshotData SnapshotSelfData
Definition: tqual.c:81
#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
bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
Definition: tqual.c:1475
TransactionId * subxip
Definition: snapshot.h:91
int xidComparator(const void *arg1, const void *arg2)
Definition: xid.c:138
int32 subxcnt
Definition: snapshot.h:92
bool ResolveCminCmaxDuringDecoding(HTAB *tuplecid_data, Snapshot snapshot, HeapTuple htup, Buffer buffer, CommandId *cmin, CommandId *cmax)