mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Prevent loss of init fork when truncating an unlogged table.
Fixes bug #6635, reported by Akira Kurosawa.
This commit is contained in:
parent
b762e8f50b
commit
1331cc6c1a
@ -1306,24 +1306,10 @@ heap_create_with_catalog(const char *relname,
|
||||
if (oncommit != ONCOMMIT_NOOP)
|
||||
register_on_commit_action(relid, oncommit);
|
||||
|
||||
/*
|
||||
* If this is an unlogged relation, it needs an init fork so that it can
|
||||
* be correctly reinitialized on restart. Since we're going to do an
|
||||
* immediate sync, we only need to xlog this if archiving or streaming is
|
||||
* enabled. And the immediate sync is required, because otherwise there's
|
||||
* no guarantee that this will hit the disk before the next checkpoint
|
||||
* moves the redo pointer.
|
||||
*/
|
||||
if (relpersistence == RELPERSISTENCE_UNLOGGED)
|
||||
{
|
||||
Assert(relkind == RELKIND_RELATION || relkind == RELKIND_TOASTVALUE);
|
||||
|
||||
RelationOpenSmgr(new_rel_desc);
|
||||
smgrcreate(new_rel_desc->rd_smgr, INIT_FORKNUM, false);
|
||||
if (XLogIsNeeded())
|
||||
log_smgrcreate(&new_rel_desc->rd_smgr->smgr_rnode.node,
|
||||
INIT_FORKNUM);
|
||||
smgrimmedsync(new_rel_desc->rd_smgr, INIT_FORKNUM);
|
||||
heap_create_init_fork(new_rel_desc);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1336,6 +1322,22 @@ heap_create_with_catalog(const char *relname,
|
||||
return relid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up an init fork for an unlogged table so that it can be correctly
|
||||
* reinitialized on restart. Since we're going to do an immediate sync, we
|
||||
* only need to xlog this if archiving or streaming is enabled. And the
|
||||
* immediate sync is required, because otherwise there's no guarantee that
|
||||
* this will hit the disk before the next checkpoint moves the redo pointer.
|
||||
*/
|
||||
void
|
||||
heap_create_init_fork(Relation rel)
|
||||
{
|
||||
RelationOpenSmgr(rel);
|
||||
smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
|
||||
if (XLogIsNeeded())
|
||||
log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM);
|
||||
smgrimmedsync(rel->rd_smgr, INIT_FORKNUM);
|
||||
}
|
||||
|
||||
/*
|
||||
* RelationRemoveInheritance
|
||||
|
@ -1155,6 +1155,8 @@ ExecuteTruncate(TruncateStmt *stmt)
|
||||
* deletion at commit.
|
||||
*/
|
||||
RelationSetNewRelfilenode(rel, RecentXmin);
|
||||
if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
|
||||
heap_create_init_fork(rel);
|
||||
|
||||
heap_relid = RelationGetRelid(rel);
|
||||
toast_relid = rel->rd_rel->reltoastrelid;
|
||||
@ -1166,6 +1168,8 @@ ExecuteTruncate(TruncateStmt *stmt)
|
||||
{
|
||||
rel = relation_open(toast_relid, AccessExclusiveLock);
|
||||
RelationSetNewRelfilenode(rel, RecentXmin);
|
||||
if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
|
||||
heap_create_init_fork(rel);
|
||||
heap_close(rel, NoLock);
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,8 @@ extern Oid heap_create_with_catalog(const char *relname,
|
||||
bool use_user_acl,
|
||||
bool allow_system_table_mods);
|
||||
|
||||
extern void heap_create_init_fork(Relation rel);
|
||||
|
||||
extern void heap_drop_with_catalog(Oid relid);
|
||||
|
||||
extern void heap_truncate(List *relids);
|
||||
|
Loading…
Reference in New Issue
Block a user