diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 15ca5ec956..d61b58315e 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -42,6 +42,7 @@ #include "catalog/pg_type.h" #include "catalog/pg_type_fn.h" #include "catalog/storage.h" +#include "catalog/storage_xlog.h" #include "catalog/toasting.h" #include "commands/cluster.h" #include "commands/comment.h" @@ -9635,6 +9636,15 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) if (smgrexists(rel->rd_smgr, forkNum)) { smgrcreate(dstrel, forkNum, false); + + /* + * WAL log creation if the relation is persistent, or this is the + * init fork of an unlogged relation. + */ + if (rel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT || + (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED && + forkNum == INIT_FORKNUM)) + log_smgrcreate(&newrnode, forkNum); copy_relation_data(rel->rd_smgr, dstrel, forkNum, rel->rd_rel->relpersistence); } @@ -9854,6 +9864,7 @@ copy_relation_data(SMgrRelation src, SMgrRelation dst, char *buf; Page page; bool use_wal; + bool copying_initfork; BlockNumber nblocks; BlockNumber blkno; @@ -9866,11 +9877,20 @@ copy_relation_data(SMgrRelation src, SMgrRelation dst, buf = (char *) palloc(BLCKSZ); page = (Page) buf; + /* + * The init fork for an unlogged relation in many respects has to be + * treated the same as normal relation, changes need to be WAL logged and + * it needs to be synced to disk. + */ + copying_initfork = relpersistence == RELPERSISTENCE_UNLOGGED && + forkNum == INIT_FORKNUM; + /* * We need to log the copied data in WAL iff WAL archiving/streaming is * enabled AND it's a permanent relation. */ - use_wal = XLogIsNeeded() && relpersistence == RELPERSISTENCE_PERMANENT; + use_wal = XLogIsNeeded() && + (relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork); nblocks = smgrnblocks(src, forkNum); @@ -9925,7 +9945,7 @@ copy_relation_data(SMgrRelation src, SMgrRelation dst, * wouldn't replay our earlier WAL entries. If we do not fsync those pages * here, they might still not be on disk when the crash occurs. */ - if (relpersistence == RELPERSISTENCE_PERMANENT) + if (relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork) smgrimmedsync(dst, forkNum); }