4
Row Version Visibility
Row version visibility is defined by xmin and xmax fields
A tuple is included in a snapshot if:
changes of xmin transaction are visible to the snapshot,
changes of xmax transaction are not visible to the snapshot
Transaction’s changes are visible if:
it is the same transaction that created the snapshot or
it committed before the snapshot was created
Transaction’s own changes
based on the operation sequence (cmin/cmax) of the transaction
A snapshot is not a physical copy of tuples. Instead, certain visibility rules
determine whether a tuple belongs to a snapshot.
Whether a given tuple is visible to a snapshot is defined by xmin and xmax
fields of the tuple header, i.e., transaction IDs that perform insertion and
deletion. Since xmin–xmax intervals do not intersect, each row is
represented in any snapshot by one of its versions at most.
The exact visibility rules are quite complex, as they take into account a
variety of different scenarios and corner cases. In general, we can describe
them as follows: a tuple is visible in a snapshot if it sees the changes made
by transaction xmin and does not see the changes made by transaction
xmax. In other words, the tuple has already been created and has not been
deleted yet (if deletion occurred).
In turn, transaction changes are visible to the snapshot if it is the transaction
that created the snapshot (it sees its own changes), or if the transaction has
been committed before the snapshot was created.
The visibility rules for a transaction’s own changes are more complex: in
some cases, only part of such changes must be visible. For example, a
cursor that was opened at a particular point in time must not see any
changes that happened later, regardless of the isolation level. For this
purpose, tuple headers contain a special field (cmin and cmax
pseudocolumns) that indicates the sequence number of the operation within
the transaction, and this number is also taken into account.