67.1. Транзакции и идентификаторы #
Транзакции могут создаваться явным образом командой BEGIN или START TRANSACTION и завершаться командой COMMIT или ROLLBACK. SQL-операторы вне явного блока транзакций автоматически обрабатываются в виде транзакций, состоящих из одного оператора.
Каждой транзакции присваивается уникальный идентификатор VirtualTransactionId (также именуемый virtualXID или vxid), который состоит из идентификатора обслуживающего процесса (или procNumber) и последовательно назначаемого номера — внутреннего для такого обслуживающего процесса (или localXID). Например, виртуальный идентификатор 4/12532 состоит из следующих компонентов: procNumber со значением 4 и localXID со значением 12532.
Невиртуальные идентификаторы TransactionId (или xid), например 278394, последовательно выбираются для транзакций из глобального счётчика, который используется всеми базами данных в рамках кластера Postgres Pro Shardman. Значение присваивается при первой операции записи транзакции в базу данных. Это означает, что транзакции с меньшими xid начинают запись раньше транзакций с большими xid. Обратите внимание, что порядок, в котором транзакции выполняют запись в базу данных впервые, может отличаться от порядка, в котором они запускаются, особенно если транзакции начинаются с операторов, выполняющих только операции чтения.
В Postgres Pro Shardman используется 64-битный тип xid внутреннего идентификатора (ID) транзакции, чтобы предотвратить зацикливание идентификатора транзакции. Каждый заголовок кортежа содержит два XID, поэтому их увеличение приводило бы к большим издержкам. По этой причине при сохранении на диске XID кортежей являются 32-битными, но каждая специальная область страницы содержит смещение, называемое базовый XID. Когда кортеж считывается в память, базовый XID добавляется к его 32-битным XID, и оба XID в кортеже становятся 64-битными, поэтому кортеж становится так называемым «кортежем в памяти». Полные 64-битные XID, полученные после добавления базового XID, используются при сравнении и в других арифметических операциях. В некоторых контекстах также используется xid8. Функции в Таблица 9.81 возвращают значения xid8. XID используются в качестве основы для механизма параллельного выполнения MVCC Postgres Pro Shardman и потоковой репликации.
Когда транзакция верхнего уровня с (невиртуальным) xid фиксируется, она помечается как зафиксированная в каталоге pg_xact. Дополнительная информация записывается в каталог pg_commit_ts при включённом параметре track_commit_timestamp.
Помимо того, что с подготовленными транзакциями сопоставляются определённые значения vxid и xid, им также назначаются глобальные идентификаторы транзакций (GID). GID представляет собой строковый литерал длиной до 200 байт, который должен иметь уникальное значение среди других существующих подготовленных транзакций. Сопоставление GID с идентификаторами транзакций представлено в pg_prepared_xacts.
67.1. Transactions and Identifiers #
Transactions can be created explicitly using BEGIN or START TRANSACTION and ended using COMMIT or ROLLBACK. SQL statements outside of explicit transactions automatically use single-statement transactions.
Every transaction is identified by a unique VirtualTransactionId (also called virtualXID or vxid), which is comprised of a backend's process number (or procNumber) and a sequentially-assigned number local to each backend, known as localXID. For example, the virtual transaction ID 4/12532 has a procNumber of 4 and a localXID of 12532.
Non-virtual TransactionIds (or xid), e.g., 278394, are assigned sequentially to transactions from a global counter used by all databases within the Postgres Pro Shardman cluster. This assignment happens when a transaction first writes to the database. This means lower-numbered xids started writing before higher-numbered xids. Note that the order in which transactions perform their first database write might be different from the order in which the transactions started, particularly if the transaction started with statements that only performed database reads.
In Postgres Pro Shardman, the internal transaction ID type xid is 64 bits wide to prevent transaction ID wraparound. Each tuple header contains two XIDs, so extending them would lead to high overhead. For that reason, when saved on disk on-tuple XIDs are 32-bit, but each page special area contains an offset, called base XID. When a tuple is read into memory, the base XID is added to its 32-bit XIDs, and both XIDs in the tuple become full 64 bits wide so the tuple becomes the so-called in-memory tuple. Full 64-bit XIDs acquired after adding the base XID are used in comparison and other arithmetic operations. In some contexts, xid8 is also used. The functions in Table 9.81 return xid8 values. Xids are used as the basis for Postgres Pro Shardman's MVCC concurrency mechanism and streaming replication.
When a top-level transaction with a (non-virtual) xid commits, it is marked as committed in the pg_xact directory. Additional information is recorded in the pg_commit_ts directory if track_commit_timestamp is enabled.
In addition to vxid and xid, prepared transactions are also assigned Global Transaction Identifiers (GID). GIDs are string literals up to 200 bytes long, which must be unique amongst other currently prepared transactions. The mapping of GID to xid is shown in pg_prepared_xacts.