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

Commit 1331cc6

Browse files
committed
Prevent loss of init fork when truncating an unlogged table.
Fixes bug #6635, reported by Akira Kurosawa.
1 parent b762e8f commit 1331cc6

File tree

3 files changed

+23
-15
lines changed

3 files changed

+23
-15
lines changed

src/backend/catalog/heap.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,24 +1306,10 @@ heap_create_with_catalog(const char *relname,
13061306
if (oncommit != ONCOMMIT_NOOP)
13071307
register_on_commit_action(relid, oncommit);
13081308

1309-
/*
1310-
* If this is an unlogged relation, it needs an init fork so that it can
1311-
* be correctly reinitialized on restart. Since we're going to do an
1312-
* immediate sync, we only need to xlog this if archiving or streaming is
1313-
* enabled. And the immediate sync is required, because otherwise there's
1314-
* no guarantee that this will hit the disk before the next checkpoint
1315-
* moves the redo pointer.
1316-
*/
13171309
if (relpersistence == RELPERSISTENCE_UNLOGGED)
13181310
{
13191311
Assert(relkind == RELKIND_RELATION || relkind == RELKIND_TOASTVALUE);
1320-
1321-
RelationOpenSmgr(new_rel_desc);
1322-
smgrcreate(new_rel_desc->rd_smgr, INIT_FORKNUM, false);
1323-
if (XLogIsNeeded())
1324-
log_smgrcreate(&new_rel_desc->rd_smgr->smgr_rnode.node,
1325-
INIT_FORKNUM);
1326-
smgrimmedsync(new_rel_desc->rd_smgr, INIT_FORKNUM);
1312+
heap_create_init_fork(new_rel_desc);
13271313
}
13281314

13291315
/*
@@ -1336,6 +1322,22 @@ heap_create_with_catalog(const char *relname,
13361322
return relid;
13371323
}
13381324

1325+
/*
1326+
* Set up an init fork for an unlogged table so that it can be correctly
1327+
* reinitialized on restart. Since we're going to do an immediate sync, we
1328+
* only need to xlog this if archiving or streaming is enabled. And the
1329+
* immediate sync is required, because otherwise there's no guarantee that
1330+
* this will hit the disk before the next checkpoint moves the redo pointer.
1331+
*/
1332+
void
1333+
heap_create_init_fork(Relation rel)
1334+
{
1335+
RelationOpenSmgr(rel);
1336+
smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
1337+
if (XLogIsNeeded())
1338+
log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM);
1339+
smgrimmedsync(rel->rd_smgr, INIT_FORKNUM);
1340+
}
13391341

13401342
/*
13411343
* RelationRemoveInheritance

src/backend/commands/tablecmds.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,8 @@ ExecuteTruncate(TruncateStmt *stmt)
11551155
* deletion at commit.
11561156
*/
11571157
RelationSetNewRelfilenode(rel, RecentXmin);
1158+
if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
1159+
heap_create_init_fork(rel);
11581160

11591161
heap_relid = RelationGetRelid(rel);
11601162
toast_relid = rel->rd_rel->reltoastrelid;
@@ -1166,6 +1168,8 @@ ExecuteTruncate(TruncateStmt *stmt)
11661168
{
11671169
rel = relation_open(toast_relid, AccessExclusiveLock);
11681170
RelationSetNewRelfilenode(rel, RecentXmin);
1171+
if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
1172+
heap_create_init_fork(rel);
11691173
heap_close(rel, NoLock);
11701174
}
11711175

src/include/catalog/heap.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ extern Oid heap_create_with_catalog(const char *relname,
6969
bool use_user_acl,
7070
bool allow_system_table_mods);
7171

72+
extern void heap_create_init_fork(Relation rel);
73+
7274
extern void heap_drop_with_catalog(Oid relid);
7375

7476
extern void heap_truncate(List *relids);

0 commit comments

Comments
 (0)