revert: add transaction processing chapter with internals info
This doc patch (master hash 66bc9d2d3e
) was decided to be too
significant for backpatching, so reverted in all but master. Also fix
SGML file header comment in master.
Reported-by: Peter Eisentraut
Discussion: https://postgr.es/m/c6304b19-6ff7-f3af-0148-cf7aa7e2fbfd@enterprisedb.com
Backpatch-through: 11
This commit is contained in:
parent
ae9939020d
commit
312061cbc7
|
@ -10321,8 +10321,7 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Virtual ID of the transaction targeted by the lock,
|
Virtual ID of the transaction targeted by the lock,
|
||||||
or null if the target is not a virtual transaction ID; see
|
or null if the target is not a virtual transaction ID
|
||||||
<xref linkend="transactions"/>
|
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
@ -10331,8 +10330,8 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
|
||||||
<structfield>transactionid</structfield> <type>xid</type>
|
<structfield>transactionid</structfield> <type>xid</type>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
ID of the transaction targeted by the lock, or null if the target
|
ID of the transaction targeted by the lock,
|
||||||
is not a transaction ID; <xref linkend="transactions"/>
|
or null if the target is not a transaction ID
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
|
|
@ -6834,14 +6834,12 @@ local0.* /var/log/postgresql
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>%v</literal></entry>
|
<entry><literal>%v</literal></entry>
|
||||||
<entry>Virtual transaction ID (backendID/localXID); see
|
<entry>Virtual transaction ID (backendID/localXID)</entry>
|
||||||
<xref linkend="transaction-id"/></entry>
|
|
||||||
<entry>no</entry>
|
<entry>no</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>%x</literal></entry>
|
<entry><literal>%x</literal></entry>
|
||||||
<entry>Transaction ID (0 if none is assigned); see
|
<entry>Transaction ID (0 if none is assigned)</entry>
|
||||||
<xref linkend="transaction-id"/></entry>
|
|
||||||
<entry>no</entry>
|
<entry>no</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
|
|
|
@ -4811,8 +4811,7 @@ SELECT * FROM pg_attribute
|
||||||
<structfield>xmin</structfield> and <structfield>xmax</structfield>. Transaction identifiers are 32-bit quantities.
|
<structfield>xmin</structfield> and <structfield>xmax</structfield>. Transaction identifiers are 32-bit quantities.
|
||||||
In some contexts, a 64-bit variant <type>xid8</type> is used. Unlike
|
In some contexts, a 64-bit variant <type>xid8</type> is used. Unlike
|
||||||
<type>xid</type> values, <type>xid8</type> values increase strictly
|
<type>xid</type> values, <type>xid8</type> values increase strictly
|
||||||
monotonically and cannot be reused in the lifetime of a database
|
monotonically and cannot be reused in the lifetime of a database cluster.
|
||||||
cluster. See <xref linkend="transaction-id"/> for more details.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
|
|
@ -101,7 +101,6 @@
|
||||||
<!ENTITY protocol SYSTEM "protocol.sgml">
|
<!ENTITY protocol SYSTEM "protocol.sgml">
|
||||||
<!ENTITY sources SYSTEM "sources.sgml">
|
<!ENTITY sources SYSTEM "sources.sgml">
|
||||||
<!ENTITY storage SYSTEM "storage.sgml">
|
<!ENTITY storage SYSTEM "storage.sgml">
|
||||||
<!ENTITY transaction SYSTEM "xact.sgml">
|
|
||||||
<!ENTITY tablesample-method SYSTEM "tablesample-method.sgml">
|
<!ENTITY tablesample-method SYSTEM "tablesample-method.sgml">
|
||||||
<!ENTITY generic-wal SYSTEM "generic-wal.sgml">
|
<!ENTITY generic-wal SYSTEM "generic-wal.sgml">
|
||||||
<!ENTITY backup-manifest SYSTEM "backup-manifest.sgml">
|
<!ENTITY backup-manifest SYSTEM "backup-manifest.sgml">
|
||||||
|
|
|
@ -23223,10 +23223,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
|
||||||
<para>
|
<para>
|
||||||
Returns the current transaction's ID. It will assign a new one if the
|
Returns the current transaction's ID. It will assign a new one if the
|
||||||
current transaction does not have one already (because it has not
|
current transaction does not have one already (because it has not
|
||||||
performed any database updates); see <xref
|
performed any database updates).
|
||||||
linkend="transaction-id"/> for details. If executed in a
|
|
||||||
subtransaction, this will return the top-level transaction ID;
|
|
||||||
see <xref linkend="subxacts"/> for details.
|
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
@ -23243,8 +23240,6 @@ SELECT collation for ('foo' COLLATE "de_DE");
|
||||||
ID is assigned yet. (It's best to use this variant if the transaction
|
ID is assigned yet. (It's best to use this variant if the transaction
|
||||||
might otherwise be read-only, to avoid unnecessary consumption of an
|
might otherwise be read-only, to avoid unnecessary consumption of an
|
||||||
XID.)
|
XID.)
|
||||||
If executed in a subtransaction, this will return the top-level
|
|
||||||
transaction ID.
|
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
@ -23288,9 +23283,6 @@ SELECT collation for ('foo' COLLATE "de_DE");
|
||||||
<para>
|
<para>
|
||||||
Returns a current <firstterm>snapshot</firstterm>, a data structure
|
Returns a current <firstterm>snapshot</firstterm>, a data structure
|
||||||
showing which transaction IDs are now in-progress.
|
showing which transaction IDs are now in-progress.
|
||||||
Only top-level transaction IDs are included in the snapshot;
|
|
||||||
subtransaction IDs are not shown; see <xref linkend="subxacts"/>
|
|
||||||
for details.
|
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
@ -23345,8 +23337,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
|
||||||
Is the given transaction ID <firstterm>visible</firstterm> according
|
Is the given transaction ID <firstterm>visible</firstterm> according
|
||||||
to this snapshot (that is, was it completed before the snapshot was
|
to this snapshot (that is, was it completed before the snapshot was
|
||||||
taken)? Note that this function will not give the correct answer for
|
taken)? Note that this function will not give the correct answer for
|
||||||
a subtransaction ID (subxid); see <xref linkend="subxacts"/> for
|
a subtransaction ID.
|
||||||
details.
|
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -23358,9 +23349,8 @@ SELECT collation for ('foo' COLLATE "de_DE");
|
||||||
wraps around every 4 billion transactions. However,
|
wraps around every 4 billion transactions. However,
|
||||||
the functions shown in <xref linkend="functions-pg-snapshot"/> use a
|
the functions shown in <xref linkend="functions-pg-snapshot"/> use a
|
||||||
64-bit type <type>xid8</type> that does not wrap around during the life
|
64-bit type <type>xid8</type> that does not wrap around during the life
|
||||||
of an installation and can be converted to <type>xid</type> by casting if
|
of an installation, and can be converted to <type>xid</type> by casting if
|
||||||
required; see <xref linkend="transaction-id"/> for details.
|
required. The data type <type>pg_snapshot</type> stores information about
|
||||||
The data type <type>pg_snapshot</type> stores information about
|
|
||||||
transaction ID visibility at a particular moment in time. Its components
|
transaction ID visibility at a particular moment in time. Its components
|
||||||
are described in <xref linkend="functions-pg-snapshot-parts"/>.
|
are described in <xref linkend="functions-pg-snapshot-parts"/>.
|
||||||
<type>pg_snapshot</type>'s textual representation is
|
<type>pg_snapshot</type>'s textual representation is
|
||||||
|
@ -23406,7 +23396,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
|
||||||
xmax</literal> and not in this list was already completed at the time
|
xmax</literal> and not in this list was already completed at the time
|
||||||
of the snapshot, and thus is either visible or dead according to its
|
of the snapshot, and thus is either visible or dead according to its
|
||||||
commit status. This list does not include the transaction IDs of
|
commit status. This list does not include the transaction IDs of
|
||||||
subtransactions (subxids).
|
subtransactions.
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -1631,8 +1631,7 @@
|
||||||
<literal>3</literal> (values under that are reserved) and the
|
<literal>3</literal> (values under that are reserved) and the
|
||||||
epoch value is incremented by one.
|
epoch value is incremented by one.
|
||||||
In some contexts, the epoch and xid values are
|
In some contexts, the epoch and xid values are
|
||||||
considered together as a single 64-bit value; see <xref
|
considered together as a single 64-bit value.
|
||||||
linkend="transaction-id"/> for more details.
|
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
For more information, see
|
For more information, see
|
||||||
|
|
|
@ -869,8 +869,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
|
||||||
<structfield>backend_xid</structfield> <type>xid</type>
|
<structfield>backend_xid</structfield> <type>xid</type>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Top-level transaction identifier of this backend, if any; see
|
Top-level transaction identifier of this backend, if any.
|
||||||
<xref linkend="transaction-id"/>.
|
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
@ -1775,8 +1774,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>virtualxid</literal></entry>
|
<entry><literal>virtualxid</literal></entry>
|
||||||
<entry>Waiting to acquire a virtual transaction ID lock; see
|
<entry>Waiting to acquire a virtual transaction ID lock.</entry>
|
||||||
<xref linkend="transaction-id"/>.</entry>
|
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
|
|
|
@ -57,8 +57,7 @@ pgrowlocks(text) returns setof record
|
||||||
<row>
|
<row>
|
||||||
<entry><structfield>locker</structfield></entry>
|
<entry><structfield>locker</structfield></entry>
|
||||||
<entry><type>xid</type></entry>
|
<entry><type>xid</type></entry>
|
||||||
<entry>Transaction ID of locker, or multixact ID if
|
<entry>Transaction ID of locker, or multixact ID if multitransaction</entry>
|
||||||
multitransaction; see <xref linkend="transaction-id"/></entry>
|
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><structfield>multi</structfield></entry>
|
<entry><structfield>multi</structfield></entry>
|
||||||
|
|
|
@ -267,7 +267,6 @@ break is not needed in a wider output rendering.
|
||||||
&brin;
|
&brin;
|
||||||
&hash;
|
&hash;
|
||||||
&storage;
|
&storage;
|
||||||
&transaction;
|
|
||||||
&bki;
|
&bki;
|
||||||
&planstats;
|
&planstats;
|
||||||
&backup-manifest;
|
&backup-manifest;
|
||||||
|
|
|
@ -21,7 +21,7 @@ PostgreSQL documentation
|
||||||
|
|
||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>RELEASE SAVEPOINT</refname>
|
<refname>RELEASE SAVEPOINT</refname>
|
||||||
<refpurpose>release a previously defined savepoint</refpurpose>
|
<refpurpose>destroy a previously defined savepoint</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
|
@ -34,13 +34,23 @@ RELEASE [ SAVEPOINT ] <replaceable>savepoint_name</replaceable>
|
||||||
<title>Description</title>
|
<title>Description</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<command>RELEASE SAVEPOINT</command> releases the named savepoint and
|
<command>RELEASE SAVEPOINT</command> destroys a savepoint previously defined
|
||||||
all active savepoints that were created after the named savepoint,
|
in the current transaction.
|
||||||
and frees their resources. All changes made since the creation of
|
</para>
|
||||||
the savepoint that didn't already get rolled back are merged into
|
|
||||||
the transaction or savepoint that was active when the named savepoint
|
<para>
|
||||||
was created. Changes made after <command>RELEASE SAVEPOINT</command>
|
Destroying a savepoint makes it unavailable as a rollback point,
|
||||||
will also be part of this active transaction or savepoint.
|
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 <xref linkend="sql-rollback-to"/>.)
|
||||||
|
Destroying a savepoint when
|
||||||
|
it is no longer needed allows the system to reclaim some resources
|
||||||
|
earlier than transaction end.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<command>RELEASE SAVEPOINT</command> also destroys all savepoints that were
|
||||||
|
established after the named savepoint was established.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -52,7 +62,7 @@ RELEASE [ SAVEPOINT ] <replaceable>savepoint_name</replaceable>
|
||||||
<term><replaceable>savepoint_name</replaceable></term>
|
<term><replaceable>savepoint_name</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The name of the savepoint to release.
|
The name of the savepoint to destroy.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -68,7 +78,7 @@ RELEASE [ SAVEPOINT ] <replaceable>savepoint_name</replaceable>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
It is not possible to release a savepoint when the transaction is in
|
It is not possible to release a savepoint when the transaction is in
|
||||||
an aborted state; to do that, use <xref linkend="sql-rollback-to"/>.
|
an aborted state.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -83,7 +93,7 @@ RELEASE [ SAVEPOINT ] <replaceable>savepoint_name</replaceable>
|
||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To establish and later release a savepoint:
|
To establish and later destroy a savepoint:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO table1 VALUES (3);
|
INSERT INTO table1 VALUES (3);
|
||||||
|
@ -94,36 +104,6 @@ COMMIT;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
The above transaction will insert both 3 and 4.
|
The above transaction will insert both 3 and 4.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
A more complex example with multiple nested subtransactions:
|
|
||||||
<programlisting>
|
|
||||||
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
|
|
||||||
</programlisting>
|
|
||||||
In this example, the application requests the release of the savepoint
|
|
||||||
<literal>sp2</literal>, which inserted 3. This changes the insert's
|
|
||||||
transaction context to <literal>sp1</literal>. 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:
|
|
||||||
<programlisting>
|
|
||||||
ROLLBACK;
|
|
||||||
ROLLBACK TO SAVEPOINT sp1;
|
|
||||||
</programlisting>
|
|
||||||
Choosing <command>ROLLBACK</command> will abort everything, including
|
|
||||||
value 1, whereas <command>ROLLBACK TO SAVEPOINT sp1</command> will retain
|
|
||||||
value 1 and allow the transaction to continue.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
|
|
@ -56,10 +56,10 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
|
||||||
<term><literal>AND CHAIN</literal></term>
|
<term><literal>AND CHAIN</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
If <literal>AND CHAIN</literal> is specified, a new (not aborted)
|
If <literal>AND CHAIN</literal> is specified, a new transaction is
|
||||||
transaction is immediately started with the same transaction
|
immediately started with the same transaction characteristics (see <xref
|
||||||
characteristics (see <xref linkend="sql-set-transaction"/>) as the
|
linkend="sql-set-transaction"/>) as the just finished one. Otherwise,
|
||||||
just finished one. Otherwise, no new transaction is started.
|
no new transaction is started.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
|
@ -35,9 +35,8 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] <replaceable>savepoint_name</re
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Roll back all commands that were executed after the savepoint was
|
Roll back all commands that were executed after the savepoint was
|
||||||
established and then start a new subtransaction at the same transaction level.
|
established. The savepoint remains valid and can be rolled back to
|
||||||
The savepoint remains valid and can be rolled back to again later,
|
again later, if needed.
|
||||||
if needed.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
<title>Reliability and the Write-Ahead Log</title>
|
<title>Reliability and the Write-Ahead Log</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This chapter explains how to control the reliability of
|
This chapter explains how the Write-Ahead Log is used to obtain
|
||||||
<productname>PostgreSQL</productname>, including details about the
|
efficient, reliable operation.
|
||||||
Write-Ahead Log.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect1 id="wal-reliability">
|
<sect1 id="wal-reliability">
|
||||||
|
@ -813,5 +812,4 @@
|
||||||
seem to be a problem in practice.
|
seem to be a problem in practice.
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
|
@ -1,205 +0,0 @@
|
||||||
<!-- doc/src/sgml/mvcc.sgml -->
|
|
||||||
|
|
||||||
<chapter id="transactions">
|
|
||||||
|
|
||||||
<title>Transaction Processing</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This chapter provides an overview of the internals of
|
|
||||||
<productname>PostgreSQL</productname>'s transaction management system.
|
|
||||||
The word transaction is often abbreviated as <firstterm>xact</firstterm>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<sect1 id="transaction-id">
|
|
||||||
|
|
||||||
<title>Transactions and Identifiers</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Transactions can be created explicitly using <command>BEGIN</command>
|
|
||||||
or <command>START TRANSACTION</command> and ended using
|
|
||||||
<command>COMMIT</command> or <command>ROLLBACK</command>. SQL
|
|
||||||
statements outside of explicit transactions automatically use
|
|
||||||
single-statement transactions.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Every transaction is identified by a unique
|
|
||||||
<literal>VirtualTransactionId</literal> (also called
|
|
||||||
<literal>virtualXID</literal> or <literal>vxid</literal>), which
|
|
||||||
is comprised of a backend ID (or <literal>backendID</literal>)
|
|
||||||
and a sequentially-assigned number local to each backend, known as
|
|
||||||
<literal>localXID</literal>. For example, the virtual transaction
|
|
||||||
ID <literal>4/12532</literal> has a <literal>backendID</literal>
|
|
||||||
of <literal>4</literal> and a <literal>localXID</literal> of
|
|
||||||
<literal>12532</literal>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Non-virtual <literal>TransactionId</literal>s (or <type>xid</type>),
|
|
||||||
e.g., <literal>278394</literal>, are assigned sequentially to
|
|
||||||
transactions from a global counter used by all databases within
|
|
||||||
the <productname>PostgreSQL</productname> 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.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The internal transaction ID type <type>xid</type> is 32 bits wide
|
|
||||||
and <link linkend="vacuum-for-wraparound">wraps around</link> every
|
|
||||||
4 billion transactions. A 32-bit epoch is incremented during each
|
|
||||||
wraparound. There is also a 64-bit type <type>xid8</type> which
|
|
||||||
includes this epoch and therefore does not wrap around during the
|
|
||||||
life of an installation; it can be converted to xid by casting.
|
|
||||||
The functions in <xref linkend="functions-pg-snapshot"/>
|
|
||||||
return <type>xid8</type> values. Xids are used as the
|
|
||||||
basis for <productname>PostgreSQL</productname>'s <link
|
|
||||||
linkend="mvcc">MVCC</link> concurrency mechanism and streaming
|
|
||||||
replication.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
When a top-level transaction with a (non-virtual) xid commits,
|
|
||||||
it is marked as committed in the <filename>pg_xact</filename>
|
|
||||||
directory. Additional information is recorded in the
|
|
||||||
<filename>pg_commit_ts</filename> directory if <xref
|
|
||||||
linkend="guc-track-commit-timestamp"/> is enabled.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In addition to <literal>vxid</literal> and <type>xid</type>,
|
|
||||||
prepared transactions are also assigned Global Transaction
|
|
||||||
Identifiers (<acronym>GID</acronym>). 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 <link
|
|
||||||
linkend="view-pg-prepared-xacts"><structname>pg_prepared_xacts</structname></link>.
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="xact-locking">
|
|
||||||
|
|
||||||
<title>Transactions and Locking</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The transaction IDs of currently executing transactions are shown in
|
|
||||||
<link linkend="view-pg-locks"><structname>pg_locks</structname></link>
|
|
||||||
in columns <structfield>virtualxid</structfield> and
|
|
||||||
<structfield>transactionid</structfield>. Read-only transactions
|
|
||||||
will have <structfield>virtualxid</structfield>s but NULL
|
|
||||||
<structfield>transactionid</structfield>s, while both columns will be
|
|
||||||
set in read-write transactions.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Some lock types wait on <structfield>virtualxid</structfield>,
|
|
||||||
while other types wait on <structfield>transactionid</structfield>.
|
|
||||||
Row-level read and write locks are recorded directly in the locked
|
|
||||||
rows and can be inspected using the <xref linkend="pgrowlocks"/>
|
|
||||||
extension. Row-level read locks might also require the assignment
|
|
||||||
of multixact IDs (<literal>mxid</literal>; see <xref
|
|
||||||
linkend="vacuum-for-multixact-wraparound"/>).
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="subxacts">
|
|
||||||
|
|
||||||
<title>Subtransactions</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
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
|
|
||||||
<firstterm>subxact</firstterm>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Subtransactions can be started explicitly using the
|
|
||||||
<command>SAVEPOINT</command> command, but can also be started in
|
|
||||||
other ways, such as PL/pgSQL's <command>EXCEPTION</command> 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.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
If a subtransaction is assigned a non-virtual transaction ID,
|
|
||||||
its transaction ID is referred to as a <quote>subxid</quote>.
|
|
||||||
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.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The immediate parent xid of each subxid is recorded in the
|
|
||||||
<filename>pg_subtrans</filename> 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.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
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.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
When a top-level transaction with an xid commits, all of its
|
|
||||||
subcommitted child subtransactions are also persistently recorded
|
|
||||||
as committed in the <filename>pg_xact</filename> directory. If the
|
|
||||||
top-level transaction aborts, all its subtransactions are also aborted,
|
|
||||||
even if they were subcommitted.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
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
|
|
||||||
<filename>pg_subtrans</filename>.
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="two-phase">
|
|
||||||
|
|
||||||
<title>Two-Phase Transactions</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
<productname>PostgreSQL</productname> supports a two-phase commit (2PC)
|
|
||||||
protocol that allows multiple distributed systems to work together
|
|
||||||
in a transactional manner. The commands are <command>PREPARE
|
|
||||||
TRANSACTION</command>, <command>COMMIT PREPARED</command> and
|
|
||||||
<command>ROLLBACK PREPARED</command>. Two-phase transactions
|
|
||||||
are intended for use by external transaction management systems.
|
|
||||||
<productname>PostgreSQL</productname> follows the features and model
|
|
||||||
proposed by the X/Open XA standard, but does not implement some less
|
|
||||||
often used aspects.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
When the user executes <command>PREPARE TRANSACTION</command>, the
|
|
||||||
only possible next commands are <command>COMMIT PREPARED</command>
|
|
||||||
or <command>ROLLBACK PREPARED</command>. 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
|
|
||||||
<filename>pg_twophase</filename> directory. Transactions
|
|
||||||
that are currently prepared can be inspected using <link
|
|
||||||
linkend="view-pg-prepared-xacts"><structname>pg_prepared_xacts</structname></link>.
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
</chapter>
|
|
Loading…
Reference in New Issue