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

Commit de93963

Browse files
committed
Revert "Skip WAL for new relfilenodes, under wal_level=minimal."
This reverts commit cb2fd7e. Per numerous buildfarm members, it was incompatible with parallel query, and a test case assumed LP64. Back-patch to 9.5 (all supported versions). Discussion: https://postgr.es/m/20200321224920.GB1763544@rfd.leadboat.com
1 parent d0587f5 commit de93963

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+363
-1439
lines changed

contrib/pg_visibility/expected/pg_visibility.out

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,5 @@
11
CREATE EXTENSION pg_visibility;
22
--
3-
-- recently-dropped table
4-
--
5-
\set VERBOSITY sqlstate
6-
BEGIN;
7-
CREATE TABLE droppedtest (c int);
8-
SELECT 'droppedtest'::regclass::oid AS oid \gset
9-
SAVEPOINT q; DROP TABLE droppedtest; RELEASE q;
10-
SAVEPOINT q; SELECT * FROM pg_visibility_map(:oid); ROLLBACK TO q;
11-
ERROR: XX000
12-
-- ERROR: could not open relation with OID 16xxx
13-
SAVEPOINT q; SELECT 1; ROLLBACK TO q;
14-
?column?
15-
----------
16-
1
17-
(1 row)
18-
19-
SAVEPOINT q; SELECT 1; ROLLBACK TO q;
20-
?column?
21-
----------
22-
1
23-
(1 row)
24-
25-
SELECT pg_relation_size(:oid), pg_relation_filepath(:oid),
26-
has_table_privilege(:oid, 'SELECT');
27-
pg_relation_size | pg_relation_filepath | has_table_privilege
28-
------------------+----------------------+---------------------
29-
| |
30-
(1 row)
31-
32-
SELECT * FROM pg_visibility_map(:oid);
33-
ERROR: XX000
34-
-- ERROR: could not open relation with OID 16xxx
35-
ROLLBACK;
36-
\set VERBOSITY default
37-
--
383
-- check that using the module's functions with unsupported relations will fail
394
--
405
-- partitioned tables (the parent ones) don't have visibility maps

contrib/pg_visibility/sql/pg_visibility.sql

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,5 @@
11
CREATE EXTENSION pg_visibility;
22

3-
--
4-
-- recently-dropped table
5-
--
6-
\set VERBOSITY sqlstate
7-
BEGIN;
8-
CREATE TABLE droppedtest (c int);
9-
SELECT 'droppedtest'::regclass::oid AS oid \gset
10-
SAVEPOINT q; DROP TABLE droppedtest; RELEASE q;
11-
SAVEPOINT q; SELECT * FROM pg_visibility_map(:oid); ROLLBACK TO q;
12-
-- ERROR: could not open relation with OID 16xxx
13-
SAVEPOINT q; SELECT 1; ROLLBACK TO q;
14-
SAVEPOINT q; SELECT 1; ROLLBACK TO q;
15-
SELECT pg_relation_size(:oid), pg_relation_filepath(:oid),
16-
has_table_privilege(:oid, 'SELECT');
17-
SELECT * FROM pg_visibility_map(:oid);
18-
-- ERROR: could not open relation with OID 16xxx
19-
ROLLBACK;
20-
\set VERBOSITY default
21-
223
--
234
-- check that using the module's functions with unsupported relations will fail
245
--

doc/src/sgml/config.sgml

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2501,19 +2501,16 @@ include_dir 'conf.d'
25012501
levels. This parameter can only be set at server start.
25022502
</para>
25032503
<para>
2504-
In <literal>minimal</literal> level, no information is logged for
2505-
permanent relations for the remainder of a transaction that creates or
2506-
rewrites them. This can make operations much faster (see
2507-
<xref linkend="populate-pitr"/>). Operations that initiate this
2508-
optimization include:
2504+
In <literal>minimal</literal> level, WAL-logging of some bulk
2505+
operations can be safely skipped, which can make those
2506+
operations much faster (see <xref linkend="populate-pitr"/>).
2507+
Operations in which this optimization can be applied include:
25092508
<simplelist>
2510-
<member><command>ALTER ... SET TABLESPACE</command></member>
2509+
<member><command>CREATE TABLE AS</command></member>
2510+
<member><command>CREATE INDEX</command></member>
25112511
<member><command>CLUSTER</command></member>
2512-
<member><command>CREATE TABLE</command></member>
2513-
<member><command>REFRESH MATERIALIZED VIEW</command>
2514-
(without <option>CONCURRENTLY</option>)</member>
2515-
<member><command>REINDEX</command></member>
2516-
<member><command>TRUNCATE</command></member>
2512+
<member><command>COPY</command> into tables that were created or truncated in the same
2513+
transaction</member>
25172514
</simplelist>
25182515
But minimal WAL does not contain enough information to reconstruct the
25192516
data from a base backup and the WAL logs, so <literal>replica</literal> or
@@ -2910,26 +2907,6 @@ include_dir 'conf.d'
29102907
</listitem>
29112908
</varlistentry>
29122909

2913-
<varlistentry id="guc-wal-skip-threshold" xreflabel="wal_skip_threshold">
2914-
<term><varname>wal_skip_threshold</varname> (<type>integer</type>)
2915-
<indexterm>
2916-
<primary><varname>wal_skip_threshold</varname> configuration parameter</primary>
2917-
</indexterm>
2918-
</term>
2919-
<listitem>
2920-
<para>
2921-
When <varname>wal_level</varname> is <literal>minimal</literal> and a
2922-
transaction commits after creating or rewriting a permanent relation,
2923-
this setting determines how to persist the new data. If the data is
2924-
smaller than this setting, write it to the WAL log; otherwise, use an
2925-
fsync of affected files. Depending on the properties of your storage,
2926-
raising or lowering this value might help if such commits are slowing
2927-
concurrent transactions. The default is two megabytes
2928-
(<literal>2MB</literal>).
2929-
</para>
2930-
</listitem>
2931-
</varlistentry>
2932-
29332910
<varlistentry id="guc-commit-delay" xreflabel="commit_delay">
29342911
<term><varname>commit_delay</varname> (<type>integer</type>)
29352912
<indexterm>

doc/src/sgml/perform.sgml

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,8 +1607,8 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
16071607
needs to be written, because in case of an error, the files
16081608
containing the newly loaded data will be removed anyway.
16091609
However, this consideration only applies when
1610-
<xref linkend="guc-wal-level"/> is <literal>minimal</literal>
1611-
as all commands must write WAL otherwise.
1610+
<xref linkend="guc-wal-level"/> is <literal>minimal</literal> for
1611+
non-partitioned tables as all commands must write WAL otherwise.
16121612
</para>
16131613

16141614
</sect2>
@@ -1708,13 +1708,42 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
17081708
</para>
17091709

17101710
<para>
1711-
Aside from avoiding the time for the archiver or WAL sender to process the
1712-
WAL data, doing this will actually make certain commands faster, because
1713-
they do not to write WAL at all if <varname>wal_level</varname>
1714-
is <literal>minimal</literal> and the current subtransaction (or top-level
1715-
transaction) created or truncated the table or index they change. (They
1716-
can guarantee crash safety more cheaply by doing
1717-
an <function>fsync</function> at the end than by writing WAL.)
1711+
Aside from avoiding the time for the archiver or WAL sender to
1712+
process the WAL data,
1713+
doing this will actually make certain commands faster, because they
1714+
are designed not to write WAL at all if <varname>wal_level</varname>
1715+
is <literal>minimal</literal>. (They can guarantee crash safety more cheaply
1716+
by doing an <function>fsync</function> at the end than by writing WAL.)
1717+
This applies to the following commands:
1718+
<itemizedlist>
1719+
<listitem>
1720+
<para>
1721+
<command>CREATE TABLE AS SELECT</command>
1722+
</para>
1723+
</listitem>
1724+
<listitem>
1725+
<para>
1726+
<command>CREATE INDEX</command> (and variants such as
1727+
<command>ALTER TABLE ADD PRIMARY KEY</command>)
1728+
</para>
1729+
</listitem>
1730+
<listitem>
1731+
<para>
1732+
<command>ALTER TABLE SET TABLESPACE</command>
1733+
</para>
1734+
</listitem>
1735+
<listitem>
1736+
<para>
1737+
<command>CLUSTER</command>
1738+
</para>
1739+
</listitem>
1740+
<listitem>
1741+
<para>
1742+
<command>COPY FROM</command>, when the target table has been
1743+
created or truncated earlier in the same transaction
1744+
</para>
1745+
</listitem>
1746+
</itemizedlist>
17181747
</para>
17191748
</sect2>
17201749

src/backend/access/gist/gistutil.c

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,44 +1004,23 @@ gistproperty(Oid index_oid, int attno,
10041004
}
10051005

10061006
/*
1007-
* Some indexes are not WAL-logged, but we need LSNs to detect concurrent page
1008-
* splits anyway. This function provides a fake sequence of LSNs for that
1009-
* purpose.
1007+
* Temporary and unlogged GiST indexes are not WAL-logged, but we need LSNs
1008+
* to detect concurrent page splits anyway. This function provides a fake
1009+
* sequence of LSNs for that purpose.
10101010
*/
10111011
XLogRecPtr
10121012
gistGetFakeLSN(Relation rel)
10131013
{
1014+
static XLogRecPtr counter = FirstNormalUnloggedLSN;
1015+
10141016
if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
10151017
{
10161018
/*
10171019
* Temporary relations are only accessible in our session, so a simple
10181020
* backend-local counter will do.
10191021
*/
1020-
static XLogRecPtr counter = FirstNormalUnloggedLSN;
1021-
10221022
return counter++;
10231023
}
1024-
else if (rel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
1025-
{
1026-
/*
1027-
* WAL-logging on this relation will start after commit, so its LSNs
1028-
* must be distinct numbers smaller than the LSN at the next commit.
1029-
* Emit a dummy WAL record if insert-LSN hasn't advanced after the
1030-
* last call.
1031-
*/
1032-
static XLogRecPtr lastlsn = InvalidXLogRecPtr;
1033-
XLogRecPtr currlsn = GetXLogInsertRecPtr();
1034-
1035-
/* Shouldn't be called for WAL-logging relations */
1036-
Assert(!RelationNeedsWAL(rel));
1037-
1038-
/* No need for an actual record if we already have a distinct LSN */
1039-
if (!XLogRecPtrIsInvalid(lastlsn) && lastlsn == currlsn)
1040-
currlsn = gistXLogAssignLSN();
1041-
1042-
lastlsn = currlsn;
1043-
return currlsn;
1044-
}
10451024
else
10461025
{
10471026
/*

src/backend/access/gist/gistxlog.c

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,6 @@ gist_redo(XLogReaderState *record)
449449
case XLOG_GIST_PAGE_DELETE:
450450
gistRedoPageDelete(record);
451451
break;
452-
case XLOG_GIST_ASSIGN_LSN:
453-
/* nop. See gistGetFakeLSN(). */
454-
break;
455452
default:
456453
elog(PANIC, "gist_redo: unknown op code %u", info);
457454
}
@@ -595,24 +592,6 @@ gistXLogPageDelete(Buffer buffer, FullTransactionId xid,
595592
return recptr;
596593
}
597594

598-
/*
599-
* Write an empty XLOG record to assign a distinct LSN.
600-
*/
601-
XLogRecPtr
602-
gistXLogAssignLSN(void)
603-
{
604-
int dummy = 0;
605-
606-
/*
607-
* Records other than SWITCH_WAL must have content. We use an integer 0 to
608-
* follow the restriction.
609-
*/
610-
XLogBeginInsert();
611-
XLogSetRecordFlags(XLOG_MARK_UNIMPORTANT);
612-
XLogRegisterData((char *) &dummy, sizeof(dummy));
613-
return XLogInsert(RM_GIST_ID, XLOG_GIST_ASSIGN_LSN);
614-
}
615-
616595
/*
617596
* Write XLOG record about reuse of a deleted page.
618597
*/

src/backend/access/heap/heapam.c

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
* heap_multi_insert - insert multiple tuples into a relation
2222
* heap_delete - delete a tuple from a relation
2323
* heap_update - replace a tuple in a relation with another tuple
24+
* heap_sync - sync heap, for when no WAL has been written
2425
*
2526
* NOTES
2627
* This file contains the heap_ routines which implement
@@ -1938,7 +1939,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
19381939
MarkBufferDirty(buffer);
19391940

19401941
/* XLOG stuff */
1941-
if (RelationNeedsWAL(relation))
1942+
if (!(options & HEAP_INSERT_SKIP_WAL) && RelationNeedsWAL(relation))
19421943
{
19431944
xl_heap_insert xlrec;
19441945
xl_heap_header xlhdr;
@@ -2121,7 +2122,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
21212122
/* currently not needed (thus unsupported) for heap_multi_insert() */
21222123
AssertArg(!(options & HEAP_INSERT_NO_LOGICAL));
21232124

2124-
needwal = RelationNeedsWAL(relation);
2125+
needwal = !(options & HEAP_INSERT_SKIP_WAL) && RelationNeedsWAL(relation);
21252126
saveFreeSpace = RelationGetTargetPageFreeSpace(relation,
21262127
HEAP_DEFAULT_FILLFACTOR);
21272128

@@ -8919,6 +8920,46 @@ heap2_redo(XLogReaderState *record)
89198920
}
89208921
}
89218922

8923+
/*
8924+
* heap_sync - sync a heap, for use when no WAL has been written
8925+
*
8926+
* This forces the heap contents (including TOAST heap if any) down to disk.
8927+
* If we skipped using WAL, and WAL is otherwise needed, we must force the
8928+
* relation down to disk before it's safe to commit the transaction. This
8929+
* requires writing out any dirty buffers and then doing a forced fsync.
8930+
*
8931+
* Indexes are not touched. (Currently, index operations associated with
8932+
* the commands that use this are WAL-logged and so do not need fsync.
8933+
* That behavior might change someday, but in any case it's likely that
8934+
* any fsync decisions required would be per-index and hence not appropriate
8935+
* to be done here.)
8936+
*/
8937+
void
8938+
heap_sync(Relation rel)
8939+
{
8940+
/* non-WAL-logged tables never need fsync */
8941+
if (!RelationNeedsWAL(rel))
8942+
return;
8943+
8944+
/* main heap */
8945+
FlushRelationBuffers(rel);
8946+
/* FlushRelationBuffers will have opened rd_smgr */
8947+
smgrimmedsync(rel->rd_smgr, MAIN_FORKNUM);
8948+
8949+
/* FSM is not critical, don't bother syncing it */
8950+
8951+
/* toast heap, if any */
8952+
if (OidIsValid(rel->rd_rel->reltoastrelid))
8953+
{
8954+
Relation toastrel;
8955+
8956+
toastrel = table_open(rel->rd_rel->reltoastrelid, AccessShareLock);
8957+
FlushRelationBuffers(toastrel);
8958+
smgrimmedsync(toastrel->rd_smgr, MAIN_FORKNUM);
8959+
table_close(toastrel, AccessShareLock);
8960+
}
8961+
}
8962+
89228963
/*
89238964
* Mask a heap page before performing consistency checks on it.
89248965
*/

src/backend/access/heap/heapam_handler.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,17 @@ heapam_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot,
555555
return result;
556556
}
557557

558+
static void
559+
heapam_finish_bulk_insert(Relation relation, int options)
560+
{
561+
/*
562+
* If we skipped writing WAL, then we need to sync the heap (but not
563+
* indexes since those use WAL anyway / don't go through tableam)
564+
*/
565+
if (options & HEAP_INSERT_SKIP_WAL)
566+
heap_sync(relation);
567+
}
568+
558569

559570
/* ------------------------------------------------------------------------
560571
* DDL related callbacks for heap AM.
@@ -687,6 +698,7 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
687698
IndexScanDesc indexScan;
688699
TableScanDesc tableScan;
689700
HeapScanDesc heapScan;
701+
bool use_wal;
690702
bool is_system_catalog;
691703
Tuplesortstate *tuplesort;
692704
TupleDesc oldTupDesc = RelationGetDescr(OldHeap);
@@ -701,9 +713,12 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
701713
is_system_catalog = IsSystemRelation(OldHeap);
702714

703715
/*
704-
* Valid smgr_targblock implies something already wrote to the relation.
705-
* This may be harmless, but this function hasn't planned for it.
716+
* We need to log the copied data in WAL iff WAL archiving/streaming is
717+
* enabled AND it's a WAL-logged rel.
706718
*/
719+
use_wal = XLogIsNeeded() && RelationNeedsWAL(NewHeap);
720+
721+
/* use_wal off requires smgr_targblock be initially invalid */
707722
Assert(RelationGetTargetBlock(NewHeap) == InvalidBlockNumber);
708723

709724
/* Preallocate values/isnull arrays */
@@ -713,7 +728,7 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
713728

714729
/* Initialize the rewrite operation */
715730
rwstate = begin_heap_rewrite(OldHeap, NewHeap, OldestXmin, *xid_cutoff,
716-
*multi_cutoff);
731+
*multi_cutoff, use_wal);
717732

718733

719734
/* Set up sorting if wanted */
@@ -2510,6 +2525,7 @@ static const TableAmRoutine heapam_methods = {
25102525
.tuple_delete = heapam_tuple_delete,
25112526
.tuple_update = heapam_tuple_update,
25122527
.tuple_lock = heapam_tuple_lock,
2528+
.finish_bulk_insert = heapam_finish_bulk_insert,
25132529

25142530
.tuple_fetch_row_version = heapam_fetch_row_version,
25152531
.tuple_get_latest_tid = heap_get_latest_tid,

0 commit comments

Comments
 (0)