Skip to content

Commit 9c6b9bd

Browse files
author
Alexander Korotkov
committed
Documentation about 64-bit xids.
1 parent c137785 commit 9c6b9bd

File tree

6 files changed

+100
-126
lines changed

6 files changed

+100
-126
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,8 +1851,8 @@
18511851
<entry>
18521852
All transaction IDs before this one have been replaced with a permanent
18531853
(<quote>frozen</>) transaction ID in this table. This is used to track
1854-
whether the table needs to be vacuumed in order to prevent transaction
1855-
ID wraparound or to allow <literal>pg_clog</> to be shrunk. Zero
1854+
whether the table needs to be vacuumed in order to allow
1855+
<literal>pg_clog</> to be shrunk. Zero
18561856
(<symbol>InvalidTransactionId</symbol>) if the relation is not a table.
18571857
</entry>
18581858
</row>
@@ -1864,8 +1864,8 @@
18641864
<entry>
18651865
All multixact IDs before this one have been replaced by a
18661866
transaction ID in this table. This is used to track
1867-
whether the table needs to be vacuumed in order to prevent multixact ID
1868-
wraparound or to allow <literal>pg_multixact</> to be shrunk. Zero
1867+
whether the table needs to be vacuumed in order to allow
1868+
<literal>pg_multixact</> to be shrunk. Zero
18691869
(<symbol>InvalidMultiXactId</symbol>) if the relation is not a table.
18701870
</entry>
18711871
</row>
@@ -2518,8 +2518,8 @@
25182518
<entry>
25192519
All transaction IDs before this one have been replaced with a permanent
25202520
(<quote>frozen</>) transaction ID in this database. This is used to
2521-
track whether the database needs to be vacuumed in order to prevent
2522-
transaction ID wraparound or to allow <literal>pg_clog</> to be shrunk.
2521+
track whether the database needs to be vacuumed in order to allow
2522+
<literal>pg_clog</> to be shrunk.
25232523
It is the minimum of the per-table
25242524
<structname>pg_class</>.<structfield>relfrozenxid</> values.
25252525
</entry>
@@ -2532,8 +2532,8 @@
25322532
<entry>
25332533
All multixact IDs before this one have been replaced with a
25342534
transaction ID in this database. This is used to
2535-
track whether the database needs to be vacuumed in order to prevent
2536-
multixact ID wraparound or to allow <literal>pg_multixact</> to be shrunk.
2535+
track whether the database needs to be vacuumed in order to allow
2536+
<literal>pg_multixact</> to be shrunk.
25372537
It is the minimum of the per-table
25382538
<structname>pg_class</>.<structfield>relminmxid</> values.
25392539
</entry>

doc/src/sgml/config.sgml

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,7 +2100,8 @@ include_dir 'conf.d'
21002100
<literal>1min</>) are only allowed because they may sometimes be
21012101
useful for testing. While a setting as high as <literal>60d</> is
21022102
allowed, please note that in many workloads extreme bloat or
2103-
transaction ID wraparound may occur in much shorter time frames.
2103+
page-level transaction ID wraparound may occur in much shorter time
2104+
frames.
21042105
</para>
21052106

21062107
<para>
@@ -5667,8 +5668,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
56675668
</para>
56685669
<para>
56695670
Note that even when this parameter is disabled, the system
5670-
will launch autovacuum processes if necessary to
5671-
prevent transaction ID wraparound. See <xref
5671+
will launch autovacuum processes if necessary to shrink
5672+
<literal>pg_clog</> and <literal>pg_multixact</>. See <xref
56725673
linkend="vacuum-for-wraparound"> for more information.
56735674
</para>
56745675
</listitem>
@@ -5822,15 +5823,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
58225823
Specifies the maximum age (in transactions) that a table's
58235824
<structname>pg_class</>.<structfield>relfrozenxid</> field can
58245825
attain before a <command>VACUUM</> operation is forced
5825-
to prevent transaction ID wraparound within the table.
5826-
Note that the system will launch autovacuum processes to
5827-
prevent wraparound even when autovacuum is otherwise disabled.
5826+
to shrink <literal>pg_clog</>.
5827+
Note that the system will launch autovacuum processes for this purpose
5828+
even when autovacuum is otherwise disabled.
58285829
</para>
58295830

58305831
<para>
5831-
Vacuum also allows removal of old files from the
5832-
<filename>pg_clog</> subdirectory, which is why the default
5833-
is a relatively low 200 million transactions.
58345832
This parameter can only be set at server start, but the setting
58355833
can be reduced for individual tables by
58365834
changing table storage parameters.
@@ -5849,17 +5847,13 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
58495847
<para>
58505848
Specifies the maximum age (in multixacts) that a table's
58515849
<structname>pg_class</>.<structfield>relminmxid</> field can
5852-
attain before a <command>VACUUM</> operation is forced to
5853-
prevent multixact ID wraparound within the table.
5854-
Note that the system will launch autovacuum processes to
5855-
prevent wraparound even when autovacuum is otherwise disabled.
5850+
attain before a <command>VACUUM</> operation is forced
5851+
to shrink <literal>pg_multixact</>.
5852+
Note that the system will launch autovacuum processes for this
5853+
purpose even when autovacuum is otherwise disabled.
58565854
</para>
58575855

58585856
<para>
5859-
Vacuuming multixacts also allows removal of old files from the
5860-
<filename>pg_multixact/members</> and <filename>pg_multixact/offsets</>
5861-
subdirectories, which is why the default is a relatively low
5862-
400 million multixacts.
58635857
This parameter can only be set at server start, but the setting can
58645858
be reduced for individual tables by changing table storage parameters.
58655859
For more information see <xref linkend="vacuum-for-multixact-wraparound">.
@@ -6361,8 +6355,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
63616355
will silently limit the effective value to 95% of
63626356
<xref linkend="guc-autovacuum-freeze-max-age">, so that a
63636357
periodical manual <command>VACUUM</> has a chance to run before an
6364-
anti-wraparound autovacuum is launched for the table. For more
6365-
information see
6358+
autovacuum to shrink <literal>pg_clog</> and <literal>pg_multixact</>
6359+
is launched for the table. For more information see
63666360
<xref linkend="vacuum-for-wraparound">.
63676361
</para>
63686362
</listitem>
@@ -6408,7 +6402,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
64086402
<command>VACUUM</> will silently limit the effective value to 95% of
64096403
<xref linkend="guc-autovacuum-multixact-freeze-max-age">, so that a
64106404
periodical manual <command>VACUUM</> has a chance to run before an
6411-
anti-wraparound is launched for the table.
6405+
autovacuum to shrink <literal>pg_clog</> and <literal>pg_multixact</>
6406+
is launched for the table.
64126407
For more information see <xref linkend="vacuum-for-multixact-wraparound">.
64136408
</para>
64146409
</listitem>

doc/src/sgml/maintenance.sgml

Lines changed: 49 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,8 @@
108108
</listitem>
109109

110110
<listitem>
111-
<simpara>To protect against loss of very old data due to
112-
<firstterm>transaction ID wraparound</> or
113-
<firstterm>multixact ID wraparound</>.</simpara>
111+
<simpara>To shrink <literal>pg_clog</> and
112+
<literal>pg_multixact</>.</simpara>
114113
</listitem>
115114
</orderedlist>
116115

@@ -376,7 +375,7 @@
376375
</sect2>
377376

378377
<sect2 id="vacuum-for-wraparound">
379-
<title>Preventing Transaction ID Wraparound Failures</title>
378+
<title>Forced shrinking <literal>pg_clog</> and <literal>pg_multixact</></title>
380379

381380
<indexterm zone="vacuum-for-wraparound">
382381
<primary>transaction ID</primary>
@@ -394,15 +393,30 @@
394393
depend on being able to compare transaction ID (<acronym>XID</>)
395394
numbers: a row version with an insertion XID greater than the current
396395
transaction's XID is <quote>in the future</> and should not be visible
397-
to the current transaction. But since transaction IDs have limited size
398-
(32 bits) a cluster that runs for a long time (more
396+
to the current transaction. In older versions transaction IDs have
397+
limited size (32 bits), and a cluster that runs for a long time (more
399398
than 4 billion transactions) would suffer <firstterm>transaction ID
400399
wraparound</>: the XID counter wraps around to zero, and all of a sudden
401400
transactions that were in the past appear to be in the future &mdash; which
402-
means their output become invisible. In short, catastrophic data loss.
403-
(Actually the data is still there, but that's cold comfort if you cannot
404-
get at it.) To avoid this, it is necessary to vacuum every table
405-
in every database at least once every two billion transactions.
401+
means data loss as their output become invisible.
402+
</para>
403+
404+
<para>
405+
<productname>Postgres Pro Enterprise 9.6</productname> introduced
406+
64-bit transaction IDs, which are not subject to wraparound and
407+
do not need modulo-2<superscript>32</> arithmetic to be compared.
408+
Each tuple header contain two XIDs, so extending them would lead to
409+
high overhead. For that reason on-page XIDs are still 32-bit, but
410+
each page's header contains an offset, called <firstterm>epoch</>,
411+
to which they are added before comparing with each other.
412+
</para>
413+
414+
<para>
415+
When new xid can't fit existing page according to its <firstterm>epoch</>,
416+
those <firstterm>epoch</> is shifted. Single page freeze takes place if
417+
needed. Both actions are performed "on the fly". Page-level wraparound
418+
can happen only when someone holds snapshot which is more than 4 billions
419+
transaction oid.
406420
</para>
407421

408422
<para>
@@ -411,25 +425,21 @@
411425
they were inserted by a transaction that committed sufficiently far in
412426
the past that the effects of the inserting transaction are certain to be
413427
visible to all current and future transactions.
414-
Normal XIDs are
415-
compared using modulo-2<superscript>32</> arithmetic. This means
416-
that for every normal XID, there are two billion XIDs that are
417-
<quote>older</> and two billion that are <quote>newer</>; another
418-
way to say it is that the normal XID space is circular with no
419-
endpoint. Therefore, once a row version has been created with a particular
420-
normal XID, the row version will appear to be <quote>in the past</> for
421-
the next two billion transactions, no matter which normal XID we are
422-
talking about. If the row version still exists after more than two billion
423-
transactions, it will suddenly appear to be in the future. To
424-
prevent this, <productname>PostgreSQL</> reserves a special XID,
425-
<literal>FrozenTransactionId</>, which does not follow the normal XID
426-
comparison rules and is always considered older
428+
<productname>&productname;</> reserves a special XID,
429+
<literal>FrozenTransactionId</>, which is always considered older
427430
than every normal XID.
428431
Frozen row versions are treated as if the inserting XID were
429432
<literal>FrozenTransactionId</>, so that they will appear to be
430-
<quote>in the past</> to all normal transactions regardless of wraparound
431-
issues, and so such row versions will be valid until deleted, no matter
432-
how long that is.
433+
<quote>in the past</> to all normal transactions.
434+
</para>
435+
436+
<para>
437+
Freezing data by <command>VACUUM</> is not needed anymore for preventing
438+
wraparound, since page-level freeze happens "on the fly". However,
439+
freezing data by <command>VACUUM</> is still needed for shrink
440+
<literal>pg_clog</> and <literal>pg_multixact</>. For historical reasons,
441+
wording "autovacuum to prevent wraparound" is preserved for forced
442+
atuvacuum for shrink <literal>pg_clog</> and <literal>pg_multixact</>.
433443
</para>
434444

435445
<note>
@@ -481,12 +491,7 @@
481491
</para>
482492

483493
<para>
484-
The maximum time that a table can go unvacuumed is two billion
485-
transactions minus the <varname>vacuum_freeze_min_age</> value at
486-
the time of the last aggressive vacuum. If it were to go
487-
unvacuumed for longer than
488-
that, data loss could result. To ensure that this does not happen,
489-
autovacuum is invoked on any table that might contain unfrozen rows with
494+
Autovacuum is invoked on any table that might contain unfrozen rows with
490495
XIDs older than the age specified by the configuration parameter <xref
491496
linkend="guc-autovacuum-freeze-max-age">. (This will happen even if
492497
autovacuum is disabled.)
@@ -512,14 +517,16 @@
512517
<varname>autovacuum_freeze_max_age</>; a setting higher than that will be
513518
capped to the maximum. A value higher than
514519
<varname>autovacuum_freeze_max_age</> wouldn't make sense because an
515-
anti-wraparound autovacuum would be triggered at that point anyway, and
520+
autovacuum to shrink <literal>pg_clog</> and <literal>pg_multixact</>
521+
would be triggered at that point anyway, and
516522
the 0.95 multiplier leaves some breathing room to run a manual
517523
<command>VACUUM</> before that happens. As a rule of thumb,
518524
<command>vacuum_freeze_table_age</> should be set to a value somewhat
519525
below <varname>autovacuum_freeze_max_age</>, leaving enough gap so that
520526
a regularly scheduled <command>VACUUM</> or an autovacuum triggered by
521527
normal delete and update activity is run in that window. Setting it too
522-
close could lead to anti-wraparound autovacuums, even though the table
528+
close could lead to autovacuums to to shrink <literal>pg_clog</> and
529+
<literal>pg_multixact</>, even though the table
523530
was recently vacuumed to reclaim space, whereas lower values lead to more
524531
frequent aggressive vacuuming.
525532
</para>
@@ -601,43 +608,8 @@ SELECT datname, age(datfrozenxid) FROM pg_database;
601608
be forced for the table.
602609
</para>
603610

604-
<para>
605-
If for some reason autovacuum fails to clear old XIDs from a table,
606-
the system will begin to emit warning messages like this when the
607-
database's oldest XIDs reach ten million transactions from the wraparound
608-
point:
609-
610-
<programlisting>
611-
WARNING: database "mydb" must be vacuumed within 177009986 transactions
612-
HINT: To avoid a database shutdown, execute a database-wide VACUUM in "mydb".
613-
</programlisting>
614-
615-
(A manual <command>VACUUM</> should fix the problem, as suggested by the
616-
hint; but note that the <command>VACUUM</> must be performed by a
617-
superuser, else it will fail to process system catalogs and thus not
618-
be able to advance the database's <structfield>datfrozenxid</>.)
619-
If these warnings are
620-
ignored, the system will shut down and refuse to start any new
621-
transactions once there are fewer than 1 million transactions left
622-
until wraparound:
623-
624-
<programlisting>
625-
ERROR: database is not accepting commands to avoid wraparound data loss in database "mydb"
626-
HINT: Stop the postmaster and vacuum that database in single-user mode.
627-
</programlisting>
628-
629-
The 1-million-transaction safety margin exists to let the
630-
administrator recover without data loss, by manually executing the
631-
required <command>VACUUM</> commands. However, since the system will not
632-
execute commands once it has gone into the safety shutdown mode,
633-
the only way to do this is to stop the server and start the server in single-user
634-
mode to execute <command>VACUUM</>. The shutdown mode is not enforced
635-
in single-user mode. See the <xref linkend="app-postgres"> reference
636-
page for details about using single-user mode.
637-
</para>
638-
639611
<sect3 id="vacuum-for-multixact-wraparound">
640-
<title>Multixacts and Wraparound</title>
612+
<title>Shrinking <literal>pg_multixact</></title>
641613

642614
<indexterm>
643615
<primary>MultiXactId</primary>
@@ -658,12 +630,12 @@ HINT: Stop the postmaster and vacuum that database in single-user mode.
658630
particular multixact ID is stored separately in
659631
the <filename>pg_multixact</> subdirectory, and only the multixact ID
660632
appears in the <structfield>xmax</> field in the tuple header.
661-
Like transaction IDs, multixact IDs are implemented as a
662-
32-bit counter and corresponding storage, all of which requires
663-
careful aging management, storage cleanup, and wraparound handling.
633+
Like transaction IDs, multixact IDs are implemented on disk page as a
634+
64-bit counter with an offset relative to epoch, and corresponding storage,
635+
which requires
636+
careful aging management, and storage cleanup.
664637
There is a separate storage area which holds the list of members in
665-
each multixact, which also uses a 32-bit counter and which must also
666-
be managed.
638+
each multixact, which uses a 64-bit counter.
667639
</para>
668640

669641
<para>
@@ -691,14 +663,9 @@ HINT: Stop the postmaster and vacuum that database in single-user mode.
691663
</para>
692664

693665
<para>
694-
As a safety device, an aggressive vacuum scan will occur for any table
666+
An aggressive vacuum scan will occur for any table
695667
whose multixact-age is greater than
696-
<xref linkend="guc-autovacuum-multixact-freeze-max-age">. Aggressive
697-
vacuum scans will also occur progressively for all tables, starting with
698-
those that have the oldest multixact-age, if the amount of used member
699-
storage space exceeds the amount 50% of the addressable storage space.
700-
Both of these kinds of aggressive scans will occur even if autovacuum is
701-
nominally disabled.
668+
<xref linkend="guc-autovacuum-multixact-freeze-max-age">.
702669
</para>
703670
</sect3>
704671
</sect2>

doc/src/sgml/ref/create_table.sgml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -987,11 +987,12 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED | CONSTANT ] TABLE [
987987
If true, the autovacuum daemon will perform automatic <command>VACUUM</>
988988
and/or <command>ANALYZE</> operations on this table following the rules
989989
discussed in <xref linkend="autovacuum">.
990-
If false, this table will not be autovacuumed, except to prevent
991-
transaction ID wraparound. See <xref linkend="vacuum-for-wraparound"> for
992-
more about wraparound prevention.
993-
Note that the autovacuum daemon does not run at all (except to prevent
994-
transaction ID wraparound) if the <xref linkend="guc-autovacuum">
990+
If false, this table will not be autovacuumed, except to shrink
991+
<literal>pg_clog</> and <literal>pg_multixact</>.
992+
See <xref linkend="vacuum-for-wraparound"> for more about that.
993+
Note that the autovacuum daemon does not run at all (except to shrink
994+
<literal>pg_clog</> and <literal>pg_multixact</>) if the
995+
<xref linkend="guc-autovacuum">
995996
parameter is false; setting individual tables' storage parameters does
996997
not override that. Therefore there is seldom much point in explicitly
997998
setting this storage parameter to <literal>true</>, only

doc/src/sgml/ref/prepare_transaction.sgml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,7 @@ PREPARE TRANSACTION <replaceable class="PARAMETER">transaction_id</replaceable>
125125
<para>
126126
It is unwise to leave transactions in the prepared state for a long time.
127127
This will interfere with the ability of <command>VACUUM</> to reclaim
128-
storage, and in extreme cases could cause the database to shut down
129-
to prevent transaction ID wraparound (see <xref
130-
linkend="vacuum-for-wraparound">). Keep in mind also that the transaction
128+
storage. Keep in mind also that the transaction
131129
continues to hold whatever locks it held. The intended usage of the
132130
feature is that a prepared transaction will normally be committed or
133131
rolled back as soon as an external transaction manager has verified that

0 commit comments

Comments
 (0)