Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5869cbf

Browse files
committed
Improve documentation about MVCC-unsafe utility commands.
The table-rewriting forms of ALTER TABLE are MVCC-unsafe, in much the same way as TRUNCATE, because they replace all rows of the table with newly-made rows with a new xmin. (Ideally, concurrent transactions with old snapshots would continue to see the old table contents, but the data is not there anymore --- and if it were there, it would be inconsistent with the table's updated rowtype, so there would be serious implementation problems to fix.) This was nowhere documented though, and the problem was only documented for TRUNCATE in a note in the TRUNCATE reference page. Create a new "Caveats" section in the MVCC chapter that can be home to this and other limitations on serializable consistency. In passing, fix a mistaken statement that VACUUM and CLUSTER would reclaim space occupied by a dropped column. They don't reconstruct existing tuples so they couldn't do that. Back-patch to all supported branches.
1 parent 83604cc commit 5869cbf

File tree

3 files changed

+52
-38
lines changed

3 files changed

+52
-38
lines changed

doc/src/sgml/mvcc.sgml

+32-14
Original file line numberDiff line numberDiff line change
@@ -757,20 +757,6 @@ ERROR: could not serialize access due to read/write dependencies among transact
757757
</listitem>
758758
</itemizedlist>
759759
</para>
760-
761-
<warning>
762-
<para>
763-
Support for the Serializable transaction isolation level has not yet
764-
been added to Hot Standby replication targets (described in
765-
<xref linkend="hot-standby">). The strictest isolation level currently
766-
supported in hot standby mode is Repeatable Read. While performing all
767-
permanent database writes within Serializable transactions on the
768-
master will ensure that all standbys will eventually reach a consistent
769-
state, a Repeatable Read transaction run on the standby can sometimes
770-
see a transient state which is inconsistent with any serial execution
771-
of serializable transactions on the master.
772-
</para>
773-
</warning>
774760
</sect2>
775761
</sect1>
776762

@@ -1667,6 +1653,38 @@ SELECT pg_advisory_lock(q.id) FROM
16671653
</sect2>
16681654
</sect1>
16691655

1656+
<sect1 id="mvcc-caveats">
1657+
<title>Caveats</title>
1658+
1659+
<para>
1660+
Some DDL commands, currently only <xref linkend="sql-truncate"> and the
1661+
table-rewriting forms of <xref linkend="sql-altertable">, are not
1662+
MVCC-safe. This means that after the truncation or rewrite commits, the
1663+
table will appear empty to concurrent transactions, if they are using a
1664+
snapshot taken before the DDL command committed. This will only be an
1665+
issue for a transaction that did not access the table in question
1666+
before the DDL command started &mdash; any transaction that has done so
1667+
would hold at least an <literal>ACCESS SHARE</literal> table lock,
1668+
which would block the DDL command until that transaction completes.
1669+
So these commands will not cause any apparent inconsistency in the
1670+
table contents for successive queries on the target table, but they
1671+
could cause visible inconsistency between the contents of the target
1672+
table and other tables in the database.
1673+
</para>
1674+
1675+
<para>
1676+
Support for the Serializable transaction isolation level has not yet
1677+
been added to Hot Standby replication targets (described in
1678+
<xref linkend="hot-standby">). The strictest isolation level currently
1679+
supported in hot standby mode is Repeatable Read. While performing all
1680+
permanent database writes within Serializable transactions on the
1681+
master will ensure that all standbys will eventually reach a consistent
1682+
state, a Repeatable Read transaction run on the standby can sometimes
1683+
see a transient state that is inconsistent with any serial execution
1684+
of the transactions on the master.
1685+
</para>
1686+
</sect1>
1687+
16701688
<sect1 id="locking-indexes">
16711689
<title>Locking and Indexes</title>
16721690

doc/src/sgml/ref/alter_table.sgml

+14-7
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable>
652652
This form changes the information which is written to the write-ahead log
653653
to identify rows which are updated or deleted. This option has no effect
654654
except when logical replication is in use. <literal>DEFAULT</>
655-
(the default for non-system tables) records the
655+
(the default for non-system tables) records the
656656
old values of the columns of the primary key, if any. <literal>USING INDEX</>
657657
records the old values of the columns covered by the named index, which
658658
must be unique, not partial, not deferrable, and include only columns marked
@@ -954,7 +954,8 @@ ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable>
954954

955955
<para>
956956
Adding a <literal>CHECK</> or <literal>NOT NULL</> constraint requires
957-
scanning the table to verify that existing rows meet the constraint.
957+
scanning the table to verify that existing rows meet the constraint,
958+
but does not require a table rewrite.
958959
</para>
959960

960961
<para>
@@ -976,11 +977,17 @@ ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable>
976977
</para>
977978

978979
<para>
979-
To force an immediate rewrite of the table, you can use
980-
<link linkend="SQL-VACUUM">VACUUM FULL</>, <xref linkend="SQL-CLUSTER">
981-
or one of the forms of ALTER TABLE that forces a rewrite. This results in
982-
no semantically-visible change in the table, but gets rid of
983-
no-longer-useful data.
980+
To force immediate reclamation of space occupied by a dropped column,
981+
you can execute one of the forms of <command>ALTER TABLE</> that
982+
performs a rewrite of the whole table. This results in reconstructing
983+
each row with the dropped column replaced by a null value.
984+
</para>
985+
986+
<para>
987+
The rewriting forms of <command>ALTER TABLE</> are not MVCC-safe.
988+
After a table rewrite, the table will appear empty to concurrent
989+
transactions, if they are using a snapshot taken before the rewrite
990+
occurred. See <xref linkend="mvcc-caveats"> for more details.
984991
</para>
985992

986993
<para>

doc/src/sgml/ref/truncate.sgml

+6-17
Original file line numberDiff line numberDiff line change
@@ -140,23 +140,12 @@ TRUNCATE [ TABLE ] [ ONLY ] <replaceable class="PARAMETER">name</replaceable> [
140140
that were added due to cascading).
141141
</para>
142142

143-
<warning>
144-
<para>
145-
<command>TRUNCATE</> is not MVCC-safe (see <xref linkend="mvcc">
146-
for general information about MVCC). After truncation, the table
147-
will appear empty to all concurrent transactions, even if they
148-
are using a snapshot taken before the truncation occurred. This
149-
will only be an issue for a transaction that did not access the
150-
truncated table before the truncation happened &mdash; any
151-
transaction that has done so would hold at least an
152-
<literal>ACCESS SHARE</literal> lock, which would block
153-
<command>TRUNCATE</> until that transaction completes. So
154-
truncation will not cause any apparent inconsistency in the table
155-
contents for successive queries on the same table, but it could
156-
cause visible inconsistency between the contents of the truncated
157-
table and other tables in the database.
158-
</para>
159-
</warning>
143+
<para>
144+
<command>TRUNCATE</> is not MVCC-safe. After truncation, the table will
145+
appear empty to concurrent transactions, if they are using a snapshot
146+
taken before the truncation occurred.
147+
See <xref linkend="mvcc-caveats"> for more details.
148+
</para>
160149

161150
<para>
162151
<command>TRUNCATE</> is transaction-safe with respect to the data

0 commit comments

Comments
 (0)