How does Postgres decide which transactions are visible to a given transaction according to the isolation level?
I know that Postgres uses xmin
and xmax
and compares it to xid
, but I haven't found the articles with proper details.
Do you know the process under hood?
This depends on the current snapshot.
READ COMMITTED
transactions take a new snapshot for every query, while REPEATABLE READ
and SERIALIZABLE
transactions take a snapshot when the first query is run and keep it for the whole duration of the transaction.
The snapshot is defined as struct SnapshotData
in include/utils/snapshot.h
and essentially contains the following:
a minimal transaction ID xmin
: all older transactions are visible to this snapshot.
a maximal transaction ID xmax
: all later transactions are not visible to this snapshot.
an array of transaction IDs xid
that contains all in-between transactions that are not visible to this snapshot.
To determine if a tuple is visible to a snapshot, its xmin
must be a committed transaction ID that is visible and its xmax
must not be a committed transaction ID that is visible.
To determine if a transaction is committed or not, the commit log has to be consulted unless the hint bits of the tuple (which cache that information) have already been set.