diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 3f8508060d9..a80ed029ba3 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -9187,7 +9187,8 @@ SCRAM-SHA-256$<iteration count>:&l Virtual ID of the transaction targeted by the lock, - or null if the target is not a virtual transaction ID + or null if the target is not a virtual transaction ID; see + @@ -9195,8 +9196,8 @@ SCRAM-SHA-256$<iteration count>:&l xid - ID of the transaction targeted by the lock, - or null if the target is not a transaction ID + ID of the transaction targeted by the lock, or null if the target + is not a transaction ID; diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 46b044de903..94484c3bca4 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -6566,12 +6566,14 @@ local0.* /var/log/postgresql %v - Virtual transaction ID (backendID/localXID) + Virtual transaction ID (backendID/localXID); see + no %x - Transaction ID (0 if none is assigned) + Transaction ID (0 if none is assigned); see + no diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml index a58494720f8..d752c48dda2 100644 --- a/doc/src/sgml/filelist.sgml +++ b/doc/src/sgml/filelist.sgml @@ -101,6 +101,7 @@ + diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index b2a27c8c7fc..dd72c16bebf 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -817,7 +817,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xid xid - Top-level transaction identifier of this backend, if any. + Top-level transaction identifier of this backend, if any; see + . backend_xmin diff --git a/doc/src/sgml/pgrowlocks.sgml b/doc/src/sgml/pgrowlocks.sgml index 392d5f1f9a7..02f31601b06 100644 --- a/doc/src/sgml/pgrowlocks.sgml +++ b/doc/src/sgml/pgrowlocks.sgml @@ -57,7 +57,8 @@ pgrowlocks(text) returns setof record locker xid - Transaction ID of locker, or multixact ID if multitransaction + Transaction ID of locker, or multixact ID if + multitransaction; see multi diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml index 405e1c7b085..61811457167 100644 --- a/doc/src/sgml/postgres.sgml +++ b/doc/src/sgml/postgres.sgml @@ -260,6 +260,7 @@ &brin; &hash; &storage; + &transaction; &bki; &planstats; diff --git a/doc/src/sgml/ref/release_savepoint.sgml b/doc/src/sgml/ref/release_savepoint.sgml index daf8eb9a436..e9fc6e5d1c8 100644 --- a/doc/src/sgml/ref/release_savepoint.sgml +++ b/doc/src/sgml/ref/release_savepoint.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation RELEASE SAVEPOINT - destroy a previously defined savepoint + release a previously defined savepoint @@ -34,23 +34,13 @@ RELEASE [ SAVEPOINT ] savepoint_name Description - RELEASE SAVEPOINT destroys a savepoint previously defined - in the current transaction. - - - - Destroying a savepoint makes it unavailable as a rollback point, - but it has no other user visible behavior. It does not undo the - effects of commands executed after the savepoint was established. - (To do that, see .) - Destroying a savepoint when - it is no longer needed allows the system to reclaim some resources - earlier than transaction end. - - - - RELEASE SAVEPOINT also destroys all savepoints that were - established after the named savepoint was established. + RELEASE SAVEPOINT releases the named savepoint and + all active savepoints that were created after the named savepoint, + and frees their resources. All changes made since the creation of + the savepoint that didn't already get rolled back are merged into + the transaction or savepoint that was active when the named savepoint + was created. Changes made after RELEASE SAVEPOINT + will also be part of this active transaction or savepoint. @@ -62,7 +52,7 @@ RELEASE [ SAVEPOINT ] savepoint_name savepoint_name - The name of the savepoint to destroy. + The name of the savepoint to release. @@ -78,7 +68,7 @@ RELEASE [ SAVEPOINT ] savepoint_name It is not possible to release a savepoint when the transaction is in - an aborted state. + an aborted state; to do that, use . @@ -93,7 +83,7 @@ RELEASE [ SAVEPOINT ] savepoint_name Examples - To establish and later destroy a savepoint: + To establish and later release a savepoint: BEGIN; INSERT INTO table1 VALUES (3); @@ -104,6 +94,36 @@ COMMIT; The above transaction will insert both 3 and 4. + + + A more complex example with multiple nested subtransactions: + +BEGIN; + INSERT INTO table1 VALUES (1); + SAVEPOINT sp1; + INSERT INTO table1 VALUES (2); + SAVEPOINT sp2; + INSERT INTO table1 VALUES (3); + RELEASE SAVEPOINT sp2; + INSERT INTO table1 VALUES (4))); -- generates an error + + In this example, the application requests the release of the savepoint + sp2, which inserted 3. This changes the insert's + transaction context to sp1. When the statement + attempting to insert value 4 generates an error, the insertion of 2 and + 4 are lost because they are in the same, now-rolled back savepoint, + and value 3 is in the same transaction context. The application can + now only choose one of these two commands, since all other commands + will be ignored: + + ROLLBACK; + ROLLBACK TO SAVEPOINT sp1; + + Choosing ROLLBACK will abort everything, including + value 1, whereas ROLLBACK TO SAVEPOINT sp1 will retain + value 1 and allow the transaction to continue. + + diff --git a/doc/src/sgml/ref/rollback.sgml b/doc/src/sgml/ref/rollback.sgml index 1357eaa8323..7f8a088c7fe 100644 --- a/doc/src/sgml/ref/rollback.sgml +++ b/doc/src/sgml/ref/rollback.sgml @@ -56,10 +56,10 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] AND CHAIN - If AND CHAIN is specified, a new transaction is - immediately started with the same transaction characteristics (see ) as the just finished one. Otherwise, - no new transaction is started. + If AND CHAIN is specified, a new (not aborted) + transaction is immediately started with the same transaction + characteristics (see ) as the + just finished one. Otherwise, no new transaction is started. diff --git a/doc/src/sgml/ref/rollback_to.sgml b/doc/src/sgml/ref/rollback_to.sgml index 4d5647a302e..827235eec29 100644 --- a/doc/src/sgml/ref/rollback_to.sgml +++ b/doc/src/sgml/ref/rollback_to.sgml @@ -35,8 +35,9 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name Roll back all commands that were executed after the savepoint was - established. The savepoint remains valid and can be rolled back to - again later, if needed. + established and then start a new subtransaction at the same transaction level. + The savepoint remains valid and can be rolled back to again later, + if needed. diff --git a/doc/src/sgml/wal.sgml b/doc/src/sgml/wal.sgml index a94edf4d8b6..bd7886187df 100644 --- a/doc/src/sgml/wal.sgml +++ b/doc/src/sgml/wal.sgml @@ -4,8 +4,9 @@ Reliability and the Write-Ahead Log - This chapter explains how the Write-Ahead Log is used to obtain - efficient, reliable operation. + This chapter explains how to control the reliability of + PostgreSQL, including details about the + Write-Ahead Log. @@ -811,4 +812,5 @@ seem to be a problem in practice. + diff --git a/doc/src/sgml/xact.sgml b/doc/src/sgml/xact.sgml new file mode 100644 index 00000000000..da3ab662870 --- /dev/null +++ b/doc/src/sgml/xact.sgml @@ -0,0 +1,200 @@ + + + + + Transaction Processing + + + This chapter provides an overview of the internals of + PostgreSQL's transaction management system. + The word transaction is often abbreviated as xact. + + + + + 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 ID (or backendID) + and a sequentially-assigned number local to each backend, known as + localXID. For example, the virtual transaction + ID 4/12532 has a backendID + 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 PostgreSQL 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. + + + + The internal transaction ID type xid is 32 bits wide + and wraps around every + 4 billion transactions. A 32-bit epoch is incremented during each + wraparound. Xids are used as the basis for + PostgreSQL'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 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. + + + + + + Transactions and Locking + + + The transaction IDs of currently executing transactions are shown in + pg_locks + in columns virtualxid and + transactionid. Read-only transactions + will have virtualxids but NULL + transactionids, while both columns will be + set in read-write transactions. + + + + Some lock types wait on virtualxid, + while other types wait on transactionid. + Row-level read and write locks are recorded directly in the locked + rows and can be inspected using the + extension. Row-level read locks might also require the assignment + of multixact IDs (mxid; see ). + + + + + + Subtransactions + + + Subtransactions are started inside transactions, allowing large + transactions to be broken into smaller units. Subtransactions can + commit or abort without affecting their parent transactions, allowing + parent transactions to continue. This allows errors to be handled + more easily, which is a common application development pattern. + The word subtransaction is often abbreviated as + subxact. + + + + Subtransactions can be started explicitly using the + SAVEPOINT command, but can also be started in + other ways, such as PL/pgSQL's EXCEPTION clause. + PL/Python and PL/TCL also support explicit subtransactions. + Subtransactions can also be started from other subtransactions. + The top-level transaction and its child subtransactions form a + hierarchy or tree, which is why we refer to the main transaction as + the top-level transaction. + + + + If a subtransaction is assigned a non-virtual transaction ID, + its transaction ID is referred to as a subxid. + Read-only subtransactions are not assigned subxids, but once they + attempt to write, they will be assigned one. This also causes all of + a subxid's parents, up to and including the top-level transaction, + to be assigned non-virtual transaction ids. We ensure that a parent + xid is always lower than any of its child subxids. + + + + The immediate parent xid of each subxid is recorded in the + pg_subtrans directory. No entry is made for + top-level xids since they do not have a parent, nor is an entry made + for read-only subtransactions. + + + + When a subtransaction commits, all of its committed child + subtransactions with subxids will also be considered subcommitted + in that transaction. When a subtransaction aborts, all of its child + subtransactions will also be considered aborted. + + + + When a top-level transaction with an xid commits, all of its + subcommitted child subtransactions are also persistently recorded + as committed in the pg_xact directory. If the + top-level transaction aborts, all its subtransactions are also aborted, + even if they were subcommitted. + + + + The more subtransactions each transaction keeps open (not + rolled back or released), the greater the transaction management + overhead. Up to 64 open subxids are cached in shared memory for + each backend; after that point, the storage I/O overhead increases + significantly due to additional lookups of subxid entries in + pg_subtrans. + + + + + + Two-Phase Transactions + + + PostgreSQL supports a two-phase commit (2PC) + protocol that allows multiple distributed systems to work together + in a transactional manner. The commands are PREPARE + TRANSACTION, COMMIT PREPARED and + ROLLBACK PREPARED. Two-phase transactions + are intended for use by external transaction management systems. + PostgreSQL follows the features and model + proposed by the X/Open XA standard, but does not implement some less + often used aspects. + + + + When the user executes PREPARE TRANSACTION, the + only possible next commands are COMMIT PREPARED + or ROLLBACK PREPARED. In general, this prepared + state is intended to be of very short duration, but external + availability issues might mean transactions stay in this state + for an extended interval. Short-lived prepared + transactions are stored only in shared memory and WAL. + Transactions that span checkpoints are recorded in the + pg_twophase directory. Transactions + that are currently prepared can be inspected using pg_prepared_xacts. + + + +