Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit53dbc27

Browse files
committed
Support unlogged tables.
The contents of an unlogged table are WAL-logged; thus, they are notavailable on standby servers and are truncated whenever the databasesystem enters recovery. Indexes on unlogged tables are also unlogged.Unlogged GiST indexes are not currently supported.
1 parent9b8aff8 commit53dbc27

Some content is hidden

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

49 files changed

+916
-104
lines changed

‎doc/src/sgml/catalogs.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1644,7 +1644,8 @@
16441644
<entry><type>bool</type></entry>
16451645
<entry></entry>
16461646
<entry>
1647-
<literal>p</> = permanent table, <literal>t</> = temporary table
1647+
<literal>p</> = permanent table, <literal>u</> = unlogged table,
1648+
<literal>t</> = temporary table
16481649
</entry>
16491650
</row>
16501651

‎doc/src/sgml/indexam.sgml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,17 @@ ambuild (Relation heapRelation,
167167

168168
<para>
169169
<programlisting>
170+
void
171+
ambuildempty (Relation indexRelation);
172+
</programlisting>
173+
Build an empty index, and write it to the initialization fork (INIT_FORKNUM)
174+
of the given relation. This method is called only for unlogged tables; the
175+
empty index written to the initialization fork will be copied over the main
176+
relation fork on each server restart.
177+
</para>
178+
179+
<para>
180+
<programlisting>
170181
bool
171182
aminsert (Relation indexRelation,
172183
Datum *values,

‎doc/src/sgml/ref/create_table.sgml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ PostgreSQL documentation
2121

2222
<refsynopsisdiv>
2323
<synopsis>
24-
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable> ( [
24+
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP }| UNLOGGED] TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable> ( [
2525
{ <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
2626
| <replaceable>table_constraint</replaceable>
2727
| LIKE <replaceable>parent_table</replaceable> [ <replaceable>like_option</replaceable> ... ] }
@@ -32,7 +32,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE [ IF NOT EXISTS ] <repl
3232
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
3333
[ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ]
3434

35-
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable>
35+
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP }| UNLOGGED] TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable>
3636
OF <replaceable class="PARAMETER">type_name</replaceable> [ (
3737
{ <replaceable class="PARAMETER">column_name</replaceable> WITH OPTIONS [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
3838
| <replaceable>table_constraint</replaceable> }
@@ -164,6 +164,23 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE [ IF NOT EXISTS ] <repl
164164
</listitem>
165165
</varlistentry>
166166

167+
<varlistentry>
168+
<term><literal>UNLOGGED</></term>
169+
<listitem>
170+
<para>
171+
If specified, the table is created as an unlogged table. Data written
172+
to unlogged tables is not written to the write-ahead log (see <xref
173+
linkend="wal">), which makes them considerably faster than ordinary
174+
tables. However, they are not crash-safe: an unlogged table is
175+
automatically truncated after a crash or unclean shutdown. The contents
176+
of an unlogged table are also not replicated to standby servers.
177+
Any indexes created on an unlogged table are automatically unlogged as
178+
well; however, unlogged <link linkend="GiST">GiST indexes</link> are
179+
currently not supported and cannot be created on an unlogged table.
180+
</para>
181+
</listitem>
182+
</varlistentry>
183+
167184
<varlistentry>
168185
<term><literal>IF NOT EXISTS</></term>
169186
<listitem>

‎doc/src/sgml/ref/create_table_as.sgml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ PostgreSQL documentation
2121

2222
<refsynopsisdiv>
2323
<synopsis>
24-
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name</replaceable>
24+
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP }| UNLOGGED] TABLE <replaceable>table_name</replaceable>
2525
[ (<replaceable>column_name</replaceable> [, ...] ) ]
2626
[ WITH ( <replaceable class="PARAMETER">storage_parameter</replaceable> [= <replaceable class="PARAMETER">value</replaceable>] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
2727
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
@@ -81,6 +81,16 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name
8181
</listitem>
8282
</varlistentry>
8383

84+
<varlistentry>
85+
<term><literal>UNLOGGED</></term>
86+
<listitem>
87+
<para>
88+
If specified, the table is created as an unlogged table.
89+
Refer to <xref linkend="sql-createtable"> for details.
90+
</para>
91+
</listitem>
92+
</varlistentry>
93+
8494
<varlistentry>
8595
<term><replaceable>table_name</replaceable></term>
8696
<listitem>

‎doc/src/sgml/ref/pg_dump.sgml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,17 @@ PostgreSQL documentation
669669
</listitem>
670670
</varlistentry>
671671

672+
<varlistentry>
673+
<term><option>--no-unlogged-table-data</option></term>
674+
<listitem>
675+
<para>
676+
Do not dump the contents of unlogged tables. This option has no
677+
effect on whether or not the table definitions (schema) are dumped;
678+
it only suppresses dumping the table data.
679+
</para>
680+
</listitem>
681+
</varlistentry>
682+
672683
<varlistentry>
673684
<term><option>--quote-all-identifiers</></term>
674685
<listitem>

‎doc/src/sgml/ref/pg_dumpall.sgml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,17 @@ PostgreSQL documentation
201201
</listitem>
202202
</varlistentry>
203203

204+
<varlistentry>
205+
<term><option>--no-unlogged-table-data</option></term>
206+
<listitem>
207+
<para>
208+
Do not dump the contents of unlogged tables. This option has no
209+
effect on whether or not the table definitions (schema) are dumped;
210+
it only suppresses dumping the table data.
211+
</para>
212+
</listitem>
213+
</varlistentry>
214+
204215
<varlistentry>
205216
<term><option>-r</option></term>
206217
<term><option>--roles-only</option></term>

‎doc/src/sgml/storage.sgml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ the relation. The free space map is stored in a file named with the filenode
147147
number plus the suffix <literal>_fsm</>. Tables also have a
148148
<firstterm>visibility map</>, stored in a fork with the suffix <literal>_vm</>,
149149
to track which pages are known to have no dead tuples. The visibility map is
150-
described further in <xref linkend="storage-vm">.
150+
described further in <xref linkend="storage-vm">. Unlogged tables and indexes
151+
have a third fork, known as the initialization fork, which is stored in a fork
152+
with the suffix <literal>_init</literal> (see <xref linkend="storage-init">).
151153
</para>
152154

153155
<caution>
@@ -485,6 +487,24 @@ a bit is not set, it might or might not be true.
485487

486488
</sect1>
487489

490+
<sect1 id="storage-init">
491+
492+
<title>The Initialization Fork</title>
493+
494+
<indexterm>
495+
<primary>Initialization Fork</primary>
496+
</indexterm>
497+
498+
<para>
499+
Each unlogged table, and each index on an unlogged table, has an initialization
500+
fork. The initialization fork is an empty table or index of the appropriate
501+
type. When an unlogged table must be reset to empty due to a crash, the
502+
initialization fork is copied over the main fork, and any other forks are
503+
erased (they will be recreated automatically as needed).
504+
</para>
505+
506+
</sect1>
507+
488508
<sect1 id="storage-page-layout">
489509

490510
<title>Database Page Layout</title>

‎src/backend/access/gin/gininsert.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include"catalog/index.h"
2020
#include"miscadmin.h"
2121
#include"storage/bufmgr.h"
22+
#include"storage/smgr.h"
2223
#include"storage/indexfsm.h"
2324
#include"utils/memutils.h"
2425

@@ -411,6 +412,47 @@ ginbuild(PG_FUNCTION_ARGS)
411412
PG_RETURN_POINTER(result);
412413
}
413414

415+
/*
416+
*ginbuildempty() -- build an empty gin index in the initialization fork
417+
*/
418+
Datum
419+
ginbuildempty(PG_FUNCTION_ARGS)
420+
{
421+
Relationindex= (Relation)PG_GETARG_POINTER(0);
422+
BufferRootBuffer,
423+
MetaBuffer;
424+
425+
/* An empty GIN index has two pages. */
426+
MetaBuffer=
427+
ReadBufferExtended(index,INIT_FORKNUM,P_NEW,RBM_NORMAL,NULL);
428+
LockBuffer(MetaBuffer,BUFFER_LOCK_EXCLUSIVE);
429+
RootBuffer=
430+
ReadBufferExtended(index,INIT_FORKNUM,P_NEW,RBM_NORMAL,NULL);
431+
LockBuffer(RootBuffer,BUFFER_LOCK_EXCLUSIVE);
432+
433+
/* Initialize both pages, mark them dirty, unlock and release buffer. */
434+
START_CRIT_SECTION();
435+
GinInitMetabuffer(MetaBuffer);
436+
MarkBufferDirty(MetaBuffer);
437+
GinInitBuffer(RootBuffer,GIN_LEAF);
438+
MarkBufferDirty(RootBuffer);
439+
440+
/* XLOG the new pages */
441+
log_newpage(&index->rd_smgr->smgr_rnode.node,INIT_FORKNUM,
442+
BufferGetBlockNumber(MetaBuffer),
443+
BufferGetPage(MetaBuffer));
444+
log_newpage(&index->rd_smgr->smgr_rnode.node,INIT_FORKNUM,
445+
BufferGetBlockNumber(RootBuffer),
446+
BufferGetPage(RootBuffer));
447+
END_CRIT_SECTION();
448+
449+
/* Unlock and release the buffers. */
450+
UnlockReleaseBuffer(MetaBuffer);
451+
UnlockReleaseBuffer(RootBuffer);
452+
453+
PG_RETURN_VOID();
454+
}
455+
414456
/*
415457
* Inserts value during normal insertion
416458
*/

‎src/backend/access/gist/gist.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,19 @@ gistbuildCallback(Relation index,
218218
MemoryContextReset(buildstate->tmpCtx);
219219
}
220220

221+
/*
222+
*gistbuildempty() -- build an empty gist index in the initialization fork
223+
*/
224+
Datum
225+
gistbuildempty(PG_FUNCTION_ARGS)
226+
{
227+
ereport(ERROR,
228+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
229+
errmsg("unlogged GIST indexes are not supported")));
230+
231+
PG_RETURN_VOID();
232+
}
233+
221234
/*
222235
*gistinsert -- wrapper for GiST tuple insertion.
223236
*

‎src/backend/access/hash/hash.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ hashbuild(PG_FUNCTION_ARGS)
6969
estimate_rel_size(heap,NULL,&relpages,&reltuples);
7070

7171
/* Initialize the hash index metadata page and initial buckets */
72-
num_buckets=_hash_metapinit(index,reltuples);
72+
num_buckets=_hash_metapinit(index,reltuples,MAIN_FORKNUM);
7373

7474
/*
7575
* If we just insert the tuples into the index in scan order, then
@@ -113,6 +113,19 @@ hashbuild(PG_FUNCTION_ARGS)
113113
PG_RETURN_POINTER(result);
114114
}
115115

116+
/*
117+
*hashbuildempty() -- build an empty hash index in the initialization fork
118+
*/
119+
Datum
120+
hashbuildempty(PG_FUNCTION_ARGS)
121+
{
122+
Relationindex= (Relation)PG_GETARG_POINTER(0);
123+
124+
_hash_metapinit(index,0,INIT_FORKNUM);
125+
126+
PG_RETURN_VOID();
127+
}
128+
116129
/*
117130
* Per-tuple callback from IndexBuildHeapScan
118131
*/

‎src/backend/access/hash/hashovfl.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ _hash_getovflpage(Relation rel, Buffer metabuf)
259259
* convenient to pre-mark them as "in use" too.
260260
*/
261261
bit=metap->hashm_spares[splitnum];
262-
_hash_initbitmap(rel,metap,bitno_to_blkno(metap,bit));
262+
_hash_initbitmap(rel,metap,bitno_to_blkno(metap,bit),MAIN_FORKNUM);
263263
metap->hashm_spares[splitnum]++;
264264
}
265265
else
@@ -280,7 +280,7 @@ _hash_getovflpage(Relation rel, Buffer metabuf)
280280
* with metapage write lock held; would be better to use a lock that
281281
* doesn't block incoming searches.
282282
*/
283-
newbuf=_hash_getnewbuf(rel,blkno);
283+
newbuf=_hash_getnewbuf(rel,blkno,MAIN_FORKNUM);
284284

285285
metap->hashm_spares[splitnum]++;
286286

@@ -503,7 +503,8 @@ _hash_freeovflpage(Relation rel, Buffer ovflbuf,
503503
* All bits in the new bitmap page are set to "1", indicating "in use".
504504
*/
505505
void
506-
_hash_initbitmap(Relationrel,HashMetaPagemetap,BlockNumberblkno)
506+
_hash_initbitmap(Relationrel,HashMetaPagemetap,BlockNumberblkno,
507+
ForkNumberforkNum)
507508
{
508509
Bufferbuf;
509510
Pagepg;
@@ -520,7 +521,7 @@ _hash_initbitmap(Relation rel, HashMetaPage metap, BlockNumber blkno)
520521
* page while holding the metapage lock, but this path is taken so seldom
521522
* that it's not worth worrying about.
522523
*/
523-
buf=_hash_getnewbuf(rel,blkno);
524+
buf=_hash_getnewbuf(rel,blkno,forkNum);
524525
pg=BufferGetPage(buf);
525526

526527
/* initialize the page's special space */

‎src/backend/access/hash/hashpage.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ _hash_getinitbuf(Relation rel, BlockNumber blkno)
183183
*extend the index at a time.
184184
*/
185185
Buffer
186-
_hash_getnewbuf(Relationrel,BlockNumberblkno)
186+
_hash_getnewbuf(Relationrel,BlockNumberblkno,ForkNumberforkNum)
187187
{
188-
BlockNumbernblocks=RelationGetNumberOfBlocks(rel);
188+
BlockNumbernblocks=RelationGetNumberOfBlocksInFork(rel,forkNum);
189189
Bufferbuf;
190190

191191
if (blkno==P_NEW)
@@ -197,13 +197,13 @@ _hash_getnewbuf(Relation rel, BlockNumber blkno)
197197
/* smgr insists we use P_NEW to extend the relation */
198198
if (blkno==nblocks)
199199
{
200-
buf=ReadBuffer(rel,P_NEW);
200+
buf=ReadBufferExtended(rel,forkNum,P_NEW,RBM_NORMAL,NULL);
201201
if (BufferGetBlockNumber(buf)!=blkno)
202202
elog(ERROR,"unexpected hash relation size: %u, should be %u",
203203
BufferGetBlockNumber(buf),blkno);
204204
}
205205
else
206-
buf=ReadBufferExtended(rel,MAIN_FORKNUM,blkno,RBM_ZERO,NULL);
206+
buf=ReadBufferExtended(rel,forkNum,blkno,RBM_ZERO,NULL);
207207

208208
LockBuffer(buf,HASH_WRITE);
209209

@@ -324,7 +324,7 @@ _hash_chgbufaccess(Relation rel,
324324
* multiple buffer locks is ignored.
325325
*/
326326
uint32
327-
_hash_metapinit(Relationrel,doublenum_tuples)
327+
_hash_metapinit(Relationrel,doublenum_tuples,ForkNumberforkNum)
328328
{
329329
HashMetaPagemetap;
330330
HashPageOpaquepageopaque;
@@ -340,7 +340,7 @@ _hash_metapinit(Relation rel, double num_tuples)
340340
uint32i;
341341

342342
/* safety check */
343-
if (RelationGetNumberOfBlocks(rel)!=0)
343+
if (RelationGetNumberOfBlocksInFork(rel,forkNum)!=0)
344344
elog(ERROR,"cannot initialize non-empty hash index \"%s\"",
345345
RelationGetRelationName(rel));
346346

@@ -383,7 +383,7 @@ _hash_metapinit(Relation rel, double num_tuples)
383383
* calls to occur.This ensures that the smgr level has the right idea of
384384
* the physical index length.
385385
*/
386-
metabuf=_hash_getnewbuf(rel,HASH_METAPAGE);
386+
metabuf=_hash_getnewbuf(rel,HASH_METAPAGE,forkNum);
387387
pg=BufferGetPage(metabuf);
388388

389389
pageopaque= (HashPageOpaque)PageGetSpecialPointer(pg);
@@ -451,7 +451,7 @@ _hash_metapinit(Relation rel, double num_tuples)
451451
/* Allow interrupts, in case N is huge */
452452
CHECK_FOR_INTERRUPTS();
453453

454-
buf=_hash_getnewbuf(rel,BUCKET_TO_BLKNO(metap,i));
454+
buf=_hash_getnewbuf(rel,BUCKET_TO_BLKNO(metap,i),forkNum);
455455
pg=BufferGetPage(buf);
456456
pageopaque= (HashPageOpaque)PageGetSpecialPointer(pg);
457457
pageopaque->hasho_prevblkno=InvalidBlockNumber;
@@ -468,7 +468,7 @@ _hash_metapinit(Relation rel, double num_tuples)
468468
/*
469469
* Initialize first bitmap page
470470
*/
471-
_hash_initbitmap(rel,metap,num_buckets+1);
471+
_hash_initbitmap(rel,metap,num_buckets+1,forkNum);
472472

473473
/* all done */
474474
_hash_wrtbuf(rel,metabuf);
@@ -785,7 +785,7 @@ _hash_splitbucket(Relation rel,
785785
oopaque= (HashPageOpaque)PageGetSpecialPointer(opage);
786786

787787
nblkno=start_nblkno;
788-
nbuf=_hash_getnewbuf(rel,nblkno);
788+
nbuf=_hash_getnewbuf(rel,nblkno,MAIN_FORKNUM);
789789
npage=BufferGetPage(nbuf);
790790

791791
/* initialize the new bucket's primary page */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp