// 下面三个不太好解释,直接贴原文 /*------------------------------------------------------------------------- * A tuple is visible iff the tuple is valid including effects of open * transactions. * * Here, we consider the effects of: * - all committed and in-progress transactions (as of the current instant) * - previous commands of this transaction * - changes made by the current command * * This is essentially like SNAPSHOT_SELF as far as effects of the current * transaction and committed/aborted xacts are concerned. However, it * also includes the effects of other xacts still in progress. * * A special hack is that when a snapshot of this type is used to * determine tuple visibility, the passed-in snapshot struct is used as an * output argument to return the xids of concurrent xacts that affected * the tuple. snapshot->xmin is set to the tuple's xmin if that is * another transaction that's still in progress; or to * InvalidTransactionId if the tuple's xmin is committed good, committed * dead, or my own xact. Similarly for snapshot->xmax and the tuple's * xmax. If the tuple was inserted speculatively, meaning that the * inserter might still back down on the insertion without aborting the * whole transaction, the associated token is also returned in * snapshot->speculativeToken. See also InitDirtySnapshot(). * ------------------------------------------------------------------------- */ SNAPSHOT_DIRTY,
/* * A tuple is visible iff it follows the rules of SNAPSHOT_MVCC, but * supports being called in timetravel context (for decoding catalog * contents in the context of logical decoding). */ // 元组对MVCC快照有效,且支持逻辑复制 SNAPSHOT_HISTORIC_MVCC,
/* * A tuple is visible iff the tuple might be visible to some transaction; * false if it's surely dead to everyone, i.e., vacuumable. * * For visibility checks snapshot->min must have been set up with the xmin * horizon to use. */ // 元组对某些事务可见,如果对所有事务都是dead tuple,也就是vacuumable,则返回false SNAPSHOT_NON_VACUUMABLE } SnapshotType;
// Xmax是当前事务 if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple))) { if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) returntrue; returnfalse; } // Xmax正在被某个后端进程执行 if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple))) returntrue; // Xmax已经被提交 if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple))) { // it must have aborted or crashed SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId); returntrue; } // Xmax被锁定 if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) { SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId); returntrue; }