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_xidxid
- 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
lockerxid
- 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_nameDescription
- 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_namesavepoint_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_nameExamples
- 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.
+
+
+
+