- Multixacts> are used to implement row locking by
- multiple transactions: since there is limited space in the tuple
- header to store lock information, that information is stored as a
- multixact separately in the pg_multixact> subdirectory,
- and only its ID is in the xmax> field
- in the tuple header.
- Similar to transaction IDs, multixact IDs are implemented as a
+ Multixact IDs> are used to support row locking by
+ multiple transactions. Since there is only limited space in a tuple
+ header to store lock information, that information is encoded as
+ a multiple transaction ID>, or multixact ID for short,
+ whenever there is more than one transaction concurrently locking a
+ row. Information about which transaction IDs are included in any
+ particular multixact ID is stored separately in
+ the pg_multixact> subdirectory, and only the multixact ID
+ appears in the xmax> field in the tuple header.
+ Like transaction IDs, multixact IDs are implemented as a
32-bit counter and corresponding storage, all of which requires
careful aging management, storage cleanup, and wraparound handling.
is replaced by a different value, which can be the zero value, a single
transaction ID, or a newer multixact ID. For each table,
pg_class>.relminmxid> stores the oldest
- possible value still stored in any tuple of that table. Every time this
- value is older than
+ possible multixact ID still appearing in any tuple of that table.
+ If this value is older than
, a whole-table
scan is forced. Whole-table VACUUM> scans, regardless of
what causes them, enable advancing the value for that table.
- The method for tuple freezing was unable to handle some cases
- involving freezing of multixact> IDs, with the practical
- effect that shared row-level locks might be forgotten once old enough.
+ The logic for tuple freezing was unable to handle some cases involving
+ freezing of
+ multixact>
+ IDs, with the practical effect that shared row-level locks
+ might be forgotten once old enough.