00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #include "postgres.h"
00059
00060 #include "access/htup_details.h"
00061 #include "access/multixact.h"
00062 #include "access/subtrans.h"
00063 #include "access/transam.h"
00064 #include "access/xact.h"
00065 #include "storage/bufmgr.h"
00066 #include "storage/procarray.h"
00067 #include "utils/tqual.h"
00068
00069
00070
00071 SnapshotData SnapshotNowData = {HeapTupleSatisfiesNow};
00072 SnapshotData SnapshotSelfData = {HeapTupleSatisfiesSelf};
00073 SnapshotData SnapshotAnyData = {HeapTupleSatisfiesAny};
00074 SnapshotData SnapshotToastData = {HeapTupleSatisfiesToast};
00075
00076
00077 static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 static inline void
00111 SetHintBits(HeapTupleHeader tuple, Buffer buffer,
00112 uint16 infomask, TransactionId xid)
00113 {
00114 if (TransactionIdIsValid(xid))
00115 {
00116
00117 XLogRecPtr commitLSN = TransactionIdGetCommitLSN(xid);
00118
00119 if (XLogNeedsFlush(commitLSN) && BufferIsPermanent(buffer))
00120 return;
00121 }
00122
00123 tuple->t_infomask |= infomask;
00124 MarkBufferDirtyHint(buffer);
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 void
00134 HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
00135 uint16 infomask, TransactionId xid)
00136 {
00137 SetHintBits(tuple, buffer, infomask, xid);
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 bool
00166 HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
00167 {
00168 if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
00169 {
00170 if (tuple->t_infomask & HEAP_XMIN_INVALID)
00171 return false;
00172
00173
00174 if (tuple->t_infomask & HEAP_MOVED_OFF)
00175 {
00176 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
00177
00178 if (TransactionIdIsCurrentTransactionId(xvac))
00179 return false;
00180 if (!TransactionIdIsInProgress(xvac))
00181 {
00182 if (TransactionIdDidCommit(xvac))
00183 {
00184 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00185 InvalidTransactionId);
00186 return false;
00187 }
00188 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00189 InvalidTransactionId);
00190 }
00191 }
00192
00193 else if (tuple->t_infomask & HEAP_MOVED_IN)
00194 {
00195 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
00196
00197 if (!TransactionIdIsCurrentTransactionId(xvac))
00198 {
00199 if (TransactionIdIsInProgress(xvac))
00200 return false;
00201 if (TransactionIdDidCommit(xvac))
00202 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00203 InvalidTransactionId);
00204 else
00205 {
00206 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00207 InvalidTransactionId);
00208 return false;
00209 }
00210 }
00211 }
00212 else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))
00213 {
00214 if (tuple->t_infomask & HEAP_XMAX_INVALID)
00215 return true;
00216
00217 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00218 return true;
00219
00220 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
00221 {
00222 TransactionId xmax;
00223
00224 xmax = HeapTupleGetUpdateXid(tuple);
00225 if (!TransactionIdIsValid(xmax))
00226 return true;
00227
00228
00229 if (!TransactionIdIsCurrentTransactionId(xmax))
00230 return true;
00231 else
00232 return false;
00233 }
00234
00235 if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
00236 {
00237
00238 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
00239 InvalidTransactionId);
00240 return true;
00241 }
00242
00243 return false;
00244 }
00245 else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
00246 return false;
00247 else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
00248 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00249 HeapTupleHeaderGetXmin(tuple));
00250 else
00251 {
00252
00253 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00254 InvalidTransactionId);
00255 return false;
00256 }
00257 }
00258
00259
00260
00261 if (tuple->t_infomask & HEAP_XMAX_INVALID)
00262 return true;
00263
00264 if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
00265 {
00266 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00267 return true;
00268 return false;
00269 }
00270
00271 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
00272 {
00273 TransactionId xmax;
00274
00275 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00276 return true;
00277
00278 xmax = HeapTupleGetUpdateXid(tuple);
00279 if (!TransactionIdIsValid(xmax))
00280 return true;
00281 if (TransactionIdIsCurrentTransactionId(xmax))
00282 return false;
00283 if (TransactionIdIsInProgress(xmax))
00284 return true;
00285 if (TransactionIdDidCommit(xmax))
00286 return false;
00287 return true;
00288 }
00289
00290 if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
00291 {
00292 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00293 return true;
00294 return false;
00295 }
00296
00297 if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
00298 return true;
00299
00300 if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
00301 {
00302
00303 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
00304 InvalidTransactionId);
00305 return true;
00306 }
00307
00308
00309
00310 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00311 {
00312 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
00313 InvalidTransactionId);
00314 return true;
00315 }
00316
00317 SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
00318 HeapTupleHeaderGetRawXmax(tuple));
00319 return false;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 bool
00354 HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
00355 {
00356 if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
00357 {
00358 if (tuple->t_infomask & HEAP_XMIN_INVALID)
00359 return false;
00360
00361
00362 if (tuple->t_infomask & HEAP_MOVED_OFF)
00363 {
00364 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
00365
00366 if (TransactionIdIsCurrentTransactionId(xvac))
00367 return false;
00368 if (!TransactionIdIsInProgress(xvac))
00369 {
00370 if (TransactionIdDidCommit(xvac))
00371 {
00372 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00373 InvalidTransactionId);
00374 return false;
00375 }
00376 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00377 InvalidTransactionId);
00378 }
00379 }
00380
00381 else if (tuple->t_infomask & HEAP_MOVED_IN)
00382 {
00383 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
00384
00385 if (!TransactionIdIsCurrentTransactionId(xvac))
00386 {
00387 if (TransactionIdIsInProgress(xvac))
00388 return false;
00389 if (TransactionIdDidCommit(xvac))
00390 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00391 InvalidTransactionId);
00392 else
00393 {
00394 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00395 InvalidTransactionId);
00396 return false;
00397 }
00398 }
00399 }
00400 else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))
00401 {
00402 if (HeapTupleHeaderGetCmin(tuple) >= GetCurrentCommandId(false))
00403 return false;
00404
00405 if (tuple->t_infomask & HEAP_XMAX_INVALID)
00406 return true;
00407
00408 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00409 return true;
00410
00411 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
00412 {
00413 TransactionId xmax;
00414
00415 xmax = HeapTupleGetUpdateXid(tuple);
00416 if (!TransactionIdIsValid(xmax))
00417 return true;
00418
00419
00420 if (!TransactionIdIsCurrentTransactionId(xmax))
00421 return true;
00422 else
00423 return false;
00424 }
00425
00426 if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
00427 {
00428
00429 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
00430 InvalidTransactionId);
00431 return true;
00432 }
00433
00434 if (HeapTupleHeaderGetCmax(tuple) >= GetCurrentCommandId(false))
00435 return true;
00436 else
00437 return false;
00438 }
00439 else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
00440 return false;
00441 else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
00442 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00443 HeapTupleHeaderGetXmin(tuple));
00444 else
00445 {
00446
00447 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00448 InvalidTransactionId);
00449 return false;
00450 }
00451 }
00452
00453
00454
00455 if (tuple->t_infomask & HEAP_XMAX_INVALID)
00456 return true;
00457
00458 if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
00459 {
00460 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00461 return true;
00462 return false;
00463 }
00464
00465 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
00466 {
00467 TransactionId xmax;
00468
00469 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00470 return true;
00471
00472 xmax = HeapTupleGetUpdateXid(tuple);
00473 if (!TransactionIdIsValid(xmax))
00474 return true;
00475 if (TransactionIdIsCurrentTransactionId(xmax))
00476 {
00477 if (HeapTupleHeaderGetCmax(tuple) >= GetCurrentCommandId(false))
00478 return true;
00479 else
00480 return false;
00481 }
00482 if (TransactionIdIsInProgress(xmax))
00483 return true;
00484 if (TransactionIdDidCommit(xmax))
00485 return false;
00486 return true;
00487 }
00488
00489 if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
00490 {
00491 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00492 return true;
00493 if (HeapTupleHeaderGetCmax(tuple) >= GetCurrentCommandId(false))
00494 return true;
00495 else
00496 return false;
00497 }
00498
00499 if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
00500 return true;
00501
00502 if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
00503 {
00504
00505 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
00506 InvalidTransactionId);
00507 return true;
00508 }
00509
00510
00511
00512 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00513 {
00514 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
00515 InvalidTransactionId);
00516 return true;
00517 }
00518
00519 SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
00520 HeapTupleHeaderGetRawXmax(tuple));
00521 return false;
00522 }
00523
00524
00525
00526
00527
00528 bool
00529 HeapTupleSatisfiesAny(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
00530 {
00531 return true;
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 bool
00549 HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot,
00550 Buffer buffer)
00551 {
00552 if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
00553 {
00554 if (tuple->t_infomask & HEAP_XMIN_INVALID)
00555 return false;
00556
00557
00558 if (tuple->t_infomask & HEAP_MOVED_OFF)
00559 {
00560 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
00561
00562 if (TransactionIdIsCurrentTransactionId(xvac))
00563 return false;
00564 if (!TransactionIdIsInProgress(xvac))
00565 {
00566 if (TransactionIdDidCommit(xvac))
00567 {
00568 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00569 InvalidTransactionId);
00570 return false;
00571 }
00572 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00573 InvalidTransactionId);
00574 }
00575 }
00576
00577 else if (tuple->t_infomask & HEAP_MOVED_IN)
00578 {
00579 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
00580
00581 if (!TransactionIdIsCurrentTransactionId(xvac))
00582 {
00583 if (TransactionIdIsInProgress(xvac))
00584 return false;
00585 if (TransactionIdDidCommit(xvac))
00586 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00587 InvalidTransactionId);
00588 else
00589 {
00590 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00591 InvalidTransactionId);
00592 return false;
00593 }
00594 }
00595 }
00596 }
00597
00598
00599 return true;
00600 }
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629 HTSU_Result
00630 HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
00631 Buffer buffer)
00632 {
00633 if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
00634 {
00635 if (tuple->t_infomask & HEAP_XMIN_INVALID)
00636 return HeapTupleInvisible;
00637
00638
00639 if (tuple->t_infomask & HEAP_MOVED_OFF)
00640 {
00641 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
00642
00643 if (TransactionIdIsCurrentTransactionId(xvac))
00644 return HeapTupleInvisible;
00645 if (!TransactionIdIsInProgress(xvac))
00646 {
00647 if (TransactionIdDidCommit(xvac))
00648 {
00649 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00650 InvalidTransactionId);
00651 return HeapTupleInvisible;
00652 }
00653 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00654 InvalidTransactionId);
00655 }
00656 }
00657
00658 else if (tuple->t_infomask & HEAP_MOVED_IN)
00659 {
00660 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
00661
00662 if (!TransactionIdIsCurrentTransactionId(xvac))
00663 {
00664 if (TransactionIdIsInProgress(xvac))
00665 return HeapTupleInvisible;
00666 if (TransactionIdDidCommit(xvac))
00667 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00668 InvalidTransactionId);
00669 else
00670 {
00671 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00672 InvalidTransactionId);
00673 return HeapTupleInvisible;
00674 }
00675 }
00676 }
00677 else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))
00678 {
00679 if (HeapTupleHeaderGetCmin(tuple) >= curcid)
00680 return HeapTupleInvisible;
00681
00682 if (tuple->t_infomask & HEAP_XMAX_INVALID)
00683 return HeapTupleMayBeUpdated;
00684
00685 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00686 return HeapTupleMayBeUpdated;
00687
00688 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
00689 {
00690 TransactionId xmax;
00691
00692 xmax = HeapTupleGetUpdateXid(tuple);
00693 if (!TransactionIdIsValid(xmax))
00694 return HeapTupleMayBeUpdated;
00695
00696
00697 if (!TransactionIdIsCurrentTransactionId(xmax))
00698 return HeapTupleMayBeUpdated;
00699 else
00700 {
00701 if (HeapTupleHeaderGetCmax(tuple) >= curcid)
00702 return HeapTupleSelfUpdated;
00703 else
00704 return HeapTupleInvisible;
00705 }
00706 }
00707
00708 if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
00709 {
00710
00711 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
00712 InvalidTransactionId);
00713 return HeapTupleMayBeUpdated;
00714 }
00715
00716 if (HeapTupleHeaderGetCmax(tuple) >= curcid)
00717 return HeapTupleSelfUpdated;
00718 else
00719 return HeapTupleInvisible;
00720 }
00721 else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
00722 return HeapTupleInvisible;
00723 else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
00724 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00725 HeapTupleHeaderGetXmin(tuple));
00726 else
00727 {
00728
00729 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00730 InvalidTransactionId);
00731 return HeapTupleInvisible;
00732 }
00733 }
00734
00735
00736
00737 if (tuple->t_infomask & HEAP_XMAX_INVALID)
00738 return HeapTupleMayBeUpdated;
00739
00740 if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
00741 {
00742 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00743 return HeapTupleMayBeUpdated;
00744 return HeapTupleUpdated;
00745 }
00746
00747 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
00748 {
00749 TransactionId xmax;
00750
00751 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00752 {
00753
00754
00755
00756
00757
00758 if ((tuple->t_infomask & (HEAP_XMAX_EXCL_LOCK |
00759 HEAP_XMAX_KEYSHR_LOCK)) &&
00760 MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple)))
00761 return HeapTupleBeingUpdated;
00762
00763 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
00764 return HeapTupleMayBeUpdated;
00765 }
00766
00767 xmax = HeapTupleGetUpdateXid(tuple);
00768 if (!TransactionIdIsValid(xmax))
00769 {
00770 if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple)))
00771 return HeapTupleBeingUpdated;
00772
00773 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
00774 return HeapTupleMayBeUpdated;
00775 }
00776
00777 if (TransactionIdIsCurrentTransactionId(xmax))
00778 {
00779 if (HeapTupleHeaderGetCmax(tuple) >= curcid)
00780 return HeapTupleSelfUpdated;
00781 else
00782 return HeapTupleInvisible;
00783 }
00784
00785 if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple)))
00786 return HeapTupleBeingUpdated;
00787
00788 if (TransactionIdDidCommit(xmax))
00789 return HeapTupleUpdated;
00790
00791 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
00792 return HeapTupleMayBeUpdated;
00793 }
00794
00795 if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
00796 {
00797 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00798 return HeapTupleMayBeUpdated;
00799 if (HeapTupleHeaderGetCmax(tuple) >= curcid)
00800 return HeapTupleSelfUpdated;
00801 else
00802 return HeapTupleInvisible;
00803 }
00804
00805 if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
00806 return HeapTupleBeingUpdated;
00807
00808 if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
00809 {
00810
00811 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
00812 InvalidTransactionId);
00813 return HeapTupleMayBeUpdated;
00814 }
00815
00816
00817
00818 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00819 {
00820 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
00821 InvalidTransactionId);
00822 return HeapTupleMayBeUpdated;
00823 }
00824
00825 SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
00826 HeapTupleHeaderGetRawXmax(tuple));
00827 return HeapTupleUpdated;
00828 }
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850 bool
00851 HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
00852 Buffer buffer)
00853 {
00854 snapshot->xmin = snapshot->xmax = InvalidTransactionId;
00855
00856 if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
00857 {
00858 if (tuple->t_infomask & HEAP_XMIN_INVALID)
00859 return false;
00860
00861
00862 if (tuple->t_infomask & HEAP_MOVED_OFF)
00863 {
00864 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
00865
00866 if (TransactionIdIsCurrentTransactionId(xvac))
00867 return false;
00868 if (!TransactionIdIsInProgress(xvac))
00869 {
00870 if (TransactionIdDidCommit(xvac))
00871 {
00872 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00873 InvalidTransactionId);
00874 return false;
00875 }
00876 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00877 InvalidTransactionId);
00878 }
00879 }
00880
00881 else if (tuple->t_infomask & HEAP_MOVED_IN)
00882 {
00883 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
00884
00885 if (!TransactionIdIsCurrentTransactionId(xvac))
00886 {
00887 if (TransactionIdIsInProgress(xvac))
00888 return false;
00889 if (TransactionIdDidCommit(xvac))
00890 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00891 InvalidTransactionId);
00892 else
00893 {
00894 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00895 InvalidTransactionId);
00896 return false;
00897 }
00898 }
00899 }
00900 else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))
00901 {
00902 if (tuple->t_infomask & HEAP_XMAX_INVALID)
00903 return true;
00904
00905 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00906 return true;
00907
00908 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
00909 {
00910 TransactionId xmax;
00911
00912 xmax = HeapTupleGetUpdateXid(tuple);
00913 if (!TransactionIdIsValid(xmax))
00914 return true;
00915
00916
00917 if (!TransactionIdIsCurrentTransactionId(xmax))
00918 return true;
00919 else
00920 return false;
00921 }
00922
00923 if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
00924 {
00925
00926 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
00927 InvalidTransactionId);
00928 return true;
00929 }
00930
00931 return false;
00932 }
00933 else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
00934 {
00935 snapshot->xmin = HeapTupleHeaderGetXmin(tuple);
00936
00937 return true;
00938 }
00939 else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
00940 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
00941 HeapTupleHeaderGetXmin(tuple));
00942 else
00943 {
00944
00945 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
00946 InvalidTransactionId);
00947 return false;
00948 }
00949 }
00950
00951
00952
00953 if (tuple->t_infomask & HEAP_XMAX_INVALID)
00954 return true;
00955
00956 if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
00957 {
00958 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00959 return true;
00960 return false;
00961 }
00962
00963 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
00964 {
00965 TransactionId xmax;
00966
00967 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00968 return true;
00969
00970 xmax = HeapTupleGetUpdateXid(tuple);
00971 if (!TransactionIdIsValid(xmax))
00972 return true;
00973 if (TransactionIdIsCurrentTransactionId(xmax))
00974 return false;
00975 if (TransactionIdIsInProgress(xmax))
00976 {
00977 snapshot->xmax = xmax;
00978 return true;
00979 }
00980 if (TransactionIdDidCommit(xmax))
00981 return false;
00982 return true;
00983 }
00984
00985 if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
00986 {
00987 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
00988 return true;
00989 return false;
00990 }
00991
00992 if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
00993 {
00994 snapshot->xmax = HeapTupleHeaderGetRawXmax(tuple);
00995 return true;
00996 }
00997
00998 if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
00999 {
01000
01001 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
01002 InvalidTransactionId);
01003 return true;
01004 }
01005
01006
01007
01008 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
01009 {
01010 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
01011 InvalidTransactionId);
01012 return true;
01013 }
01014
01015 SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
01016 HeapTupleHeaderGetRawXmax(tuple));
01017 return false;
01018 }
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 bool
01042 HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
01043 Buffer buffer)
01044 {
01045 if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
01046 {
01047 if (tuple->t_infomask & HEAP_XMIN_INVALID)
01048 return false;
01049
01050
01051 if (tuple->t_infomask & HEAP_MOVED_OFF)
01052 {
01053 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
01054
01055 if (TransactionIdIsCurrentTransactionId(xvac))
01056 return false;
01057 if (!TransactionIdIsInProgress(xvac))
01058 {
01059 if (TransactionIdDidCommit(xvac))
01060 {
01061 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
01062 InvalidTransactionId);
01063 return false;
01064 }
01065 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
01066 InvalidTransactionId);
01067 }
01068 }
01069
01070 else if (tuple->t_infomask & HEAP_MOVED_IN)
01071 {
01072 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
01073
01074 if (!TransactionIdIsCurrentTransactionId(xvac))
01075 {
01076 if (TransactionIdIsInProgress(xvac))
01077 return false;
01078 if (TransactionIdDidCommit(xvac))
01079 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
01080 InvalidTransactionId);
01081 else
01082 {
01083 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
01084 InvalidTransactionId);
01085 return false;
01086 }
01087 }
01088 }
01089 else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))
01090 {
01091 if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)
01092 return false;
01093
01094 if (tuple->t_infomask & HEAP_XMAX_INVALID)
01095 return true;
01096
01097 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
01098 return true;
01099
01100 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
01101 {
01102 TransactionId xmax;
01103
01104 xmax = HeapTupleGetUpdateXid(tuple);
01105 if (!TransactionIdIsValid(xmax))
01106 return true;
01107
01108
01109 if (!TransactionIdIsCurrentTransactionId(xmax))
01110 return true;
01111 else if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
01112 return true;
01113 else
01114 return false;
01115 }
01116
01117 if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
01118 {
01119
01120 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
01121 InvalidTransactionId);
01122 return true;
01123 }
01124
01125 if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
01126 return true;
01127 else
01128 return false;
01129 }
01130 else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
01131 return false;
01132 else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
01133 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
01134 HeapTupleHeaderGetXmin(tuple));
01135 else
01136 {
01137
01138 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
01139 InvalidTransactionId);
01140 return false;
01141 }
01142 }
01143
01144
01145
01146
01147
01148 if (XidInMVCCSnapshot(HeapTupleHeaderGetXmin(tuple), snapshot))
01149 return false;
01150
01151 if (tuple->t_infomask & HEAP_XMAX_INVALID)
01152 return true;
01153
01154 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
01155 return true;
01156
01157 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
01158 {
01159 TransactionId xmax;
01160
01161
01162 Assert(!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask));
01163
01164 xmax = HeapTupleGetUpdateXid(tuple);
01165 if (!TransactionIdIsValid(xmax))
01166 return true;
01167 if (TransactionIdIsCurrentTransactionId(xmax))
01168 {
01169 if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
01170 return true;
01171 else
01172 return false;
01173 }
01174 if (TransactionIdIsInProgress(xmax))
01175 return true;
01176 if (TransactionIdDidCommit(xmax))
01177 {
01178
01179 if (XidInMVCCSnapshot(xmax, snapshot))
01180 return true;
01181 return false;
01182 }
01183 return true;
01184 }
01185
01186 if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
01187 {
01188 if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
01189 {
01190 if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
01191 return true;
01192 else
01193 return false;
01194 }
01195
01196 if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
01197 return true;
01198
01199 if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
01200 {
01201
01202 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
01203 InvalidTransactionId);
01204 return true;
01205 }
01206
01207
01208 SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
01209 HeapTupleHeaderGetRawXmax(tuple));
01210 }
01211
01212
01213
01214
01215 if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
01216 return true;
01217
01218 return false;
01219 }
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234 HTSV_Result
01235 HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
01236 Buffer buffer)
01237 {
01238
01239
01240
01241
01242
01243
01244 if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
01245 {
01246 if (tuple->t_infomask & HEAP_XMIN_INVALID)
01247 return HEAPTUPLE_DEAD;
01248
01249 else if (tuple->t_infomask & HEAP_MOVED_OFF)
01250 {
01251 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
01252
01253 if (TransactionIdIsCurrentTransactionId(xvac))
01254 return HEAPTUPLE_DELETE_IN_PROGRESS;
01255 if (TransactionIdIsInProgress(xvac))
01256 return HEAPTUPLE_DELETE_IN_PROGRESS;
01257 if (TransactionIdDidCommit(xvac))
01258 {
01259 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
01260 InvalidTransactionId);
01261 return HEAPTUPLE_DEAD;
01262 }
01263 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
01264 InvalidTransactionId);
01265 }
01266
01267 else if (tuple->t_infomask & HEAP_MOVED_IN)
01268 {
01269 TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
01270
01271 if (TransactionIdIsCurrentTransactionId(xvac))
01272 return HEAPTUPLE_INSERT_IN_PROGRESS;
01273 if (TransactionIdIsInProgress(xvac))
01274 return HEAPTUPLE_INSERT_IN_PROGRESS;
01275 if (TransactionIdDidCommit(xvac))
01276 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
01277 InvalidTransactionId);
01278 else
01279 {
01280 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
01281 InvalidTransactionId);
01282 return HEAPTUPLE_DEAD;
01283 }
01284 }
01285 else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
01286 {
01287 if (tuple->t_infomask & HEAP_XMAX_INVALID)
01288 return HEAPTUPLE_INSERT_IN_PROGRESS;
01289 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
01290 return HEAPTUPLE_INSERT_IN_PROGRESS;
01291
01292 return HEAPTUPLE_DELETE_IN_PROGRESS;
01293 }
01294 else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
01295 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
01296 HeapTupleHeaderGetXmin(tuple));
01297 else
01298 {
01299
01300
01301
01302 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
01303 InvalidTransactionId);
01304 return HEAPTUPLE_DEAD;
01305 }
01306
01307
01308
01309
01310
01311
01312 }
01313
01314
01315
01316
01317
01318 if (tuple->t_infomask & HEAP_XMAX_INVALID)
01319 return HEAPTUPLE_LIVE;
01320
01321 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
01322 {
01323
01324
01325
01326
01327
01328
01329
01330
01331 if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
01332 {
01333 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
01334 {
01335
01336
01337
01338
01339
01340 if ((tuple->t_infomask & (HEAP_XMAX_EXCL_LOCK |
01341 HEAP_XMAX_KEYSHR_LOCK)) &&
01342 MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple)))
01343 return HEAPTUPLE_LIVE;
01344 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
01345
01346 }
01347 else
01348 {
01349 if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
01350 return HEAPTUPLE_LIVE;
01351 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
01352 InvalidTransactionId);
01353 }
01354 }
01355
01356
01357
01358
01359
01360
01361
01362 return HEAPTUPLE_LIVE;
01363 }
01364
01365 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
01366 {
01367 TransactionId xmax;
01368
01369 if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple)))
01370 {
01371
01372 Assert(!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask));
01373
01374 xmax = HeapTupleGetUpdateXid(tuple);
01375 if (!TransactionIdIsValid(xmax))
01376 return HEAPTUPLE_LIVE;
01377 if (TransactionIdIsInProgress(xmax))
01378 return HEAPTUPLE_DELETE_IN_PROGRESS;
01379 else if (TransactionIdDidCommit(xmax))
01380
01381 return HEAPTUPLE_RECENTLY_DEAD;
01382
01383 return HEAPTUPLE_LIVE;
01384 }
01385
01386 Assert(!(tuple->t_infomask & HEAP_XMAX_COMMITTED));
01387
01388 xmax = HeapTupleGetUpdateXid(tuple);
01389 if (!TransactionIdIsValid(xmax))
01390 return HEAPTUPLE_LIVE;
01391
01392 Assert(!TransactionIdIsInProgress(xmax));
01393 if (TransactionIdDidCommit(xmax))
01394 {
01395 if (!TransactionIdPrecedes(xmax, OldestXmin))
01396 return HEAPTUPLE_RECENTLY_DEAD;
01397 else
01398 return HEAPTUPLE_DEAD;
01399 }
01400 else
01401 {
01402
01403
01404
01405 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
01406 return HEAPTUPLE_LIVE;
01407 }
01408
01409
01410
01411
01412
01413
01414
01415 return HEAPTUPLE_DEAD;
01416 }
01417
01418 if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
01419 {
01420 if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
01421 return HEAPTUPLE_DELETE_IN_PROGRESS;
01422 else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
01423 SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
01424 HeapTupleHeaderGetRawXmax(tuple));
01425 else
01426 {
01427
01428
01429
01430 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
01431 InvalidTransactionId);
01432 return HEAPTUPLE_LIVE;
01433 }
01434
01435
01436
01437
01438
01439
01440 }
01441
01442
01443
01444
01445
01446 if (!TransactionIdPrecedes(HeapTupleHeaderGetRawXmax(tuple), OldestXmin))
01447 return HEAPTUPLE_RECENTLY_DEAD;
01448
01449
01450 return HEAPTUPLE_DEAD;
01451 }
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465 bool
01466 HeapTupleIsSurelyDead(HeapTupleHeader tuple, TransactionId OldestXmin)
01467 {
01468
01469
01470
01471
01472
01473
01474 if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
01475 return (tuple->t_infomask & HEAP_XMIN_INVALID) != 0 ? true : false;
01476
01477
01478
01479
01480
01481 if (tuple->t_infomask & HEAP_XMAX_INVALID)
01482 return false;
01483
01484
01485
01486
01487 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
01488 return false;
01489
01490
01491
01492
01493
01494 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
01495 return false;
01496
01497
01498 if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
01499 return false;
01500
01501
01502 return TransactionIdPrecedes(HeapTupleHeaderGetRawXmax(tuple), OldestXmin);
01503 }
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514 static bool
01515 XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
01516 {
01517 uint32 i;
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528 if (TransactionIdPrecedes(xid, snapshot->xmin))
01529 return false;
01530
01531 if (TransactionIdFollowsOrEquals(xid, snapshot->xmax))
01532 return true;
01533
01534
01535
01536
01537
01538 if (!snapshot->takenDuringRecovery)
01539 {
01540
01541
01542
01543
01544
01545
01546
01547 if (!snapshot->suboverflowed)
01548 {
01549
01550 int32 j;
01551
01552 for (j = 0; j < snapshot->subxcnt; j++)
01553 {
01554 if (TransactionIdEquals(xid, snapshot->subxip[j]))
01555 return true;
01556 }
01557
01558
01559 }
01560 else
01561 {
01562
01563 xid = SubTransGetTopmostTransaction(xid);
01564
01565
01566
01567
01568
01569
01570 if (TransactionIdPrecedes(xid, snapshot->xmin))
01571 return false;
01572 }
01573
01574 for (i = 0; i < snapshot->xcnt; i++)
01575 {
01576 if (TransactionIdEquals(xid, snapshot->xip[i]))
01577 return true;
01578 }
01579 }
01580 else
01581 {
01582 int32 j;
01583
01584
01585
01586
01587
01588
01589
01590
01591 if (snapshot->suboverflowed)
01592 {
01593
01594 xid = SubTransGetTopmostTransaction(xid);
01595
01596
01597
01598
01599
01600
01601 if (TransactionIdPrecedes(xid, snapshot->xmin))
01602 return false;
01603 }
01604
01605
01606
01607
01608
01609
01610 for (j = 0; j < snapshot->subxcnt; j++)
01611 {
01612 if (TransactionIdEquals(xid, snapshot->subxip[j]))
01613 return true;
01614 }
01615 }
01616
01617 return false;
01618 }
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629 bool
01630 HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple)
01631 {
01632 TransactionId xmax;
01633
01634
01635 if (tuple->t_infomask & HEAP_XMAX_INVALID)
01636 return true;
01637
01638 if (tuple->t_infomask & HEAP_XMAX_LOCK_ONLY)
01639 return true;
01640
01641
01642 if (!TransactionIdIsValid(HeapTupleHeaderGetRawXmax(tuple)))
01643 return true;
01644
01645
01646
01647
01648
01649 if (!(tuple->t_infomask & HEAP_XMAX_IS_MULTI))
01650 return false;
01651
01652
01653 xmax = HeapTupleGetUpdateXid(tuple);
01654 if (!TransactionIdIsValid(xmax))
01655 return true;
01656
01657 if (TransactionIdIsCurrentTransactionId(xmax))
01658 return false;
01659 if (TransactionIdIsInProgress(xmax))
01660 return false;
01661 if (TransactionIdDidCommit(xmax))
01662 return false;
01663
01664
01665
01666
01667
01668 return true;
01669 }