diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index abc5682..ce079cf 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7783,7 +7783,8 @@ LogCheckpointStart(int flags, bool restartpoint) (flags & CHECKPOINT_FORCE) ? " force" : "", (flags & CHECKPOINT_WAIT) ? " wait" : "", (flags & CHECKPOINT_CAUSE_XLOG) ? " xlog" : "", - (flags & CHECKPOINT_CAUSE_TIME) ? " time" : ""); + (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "", + (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" :""); } /* diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 5705889..3e2afee 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -1122,8 +1122,13 @@ movedb(const char *dbname, const char *tblspcname) * that the copy might fail due to source files getting deleted under it. * On Windows, this also ensures that background procs don't hold any open * files, which would cause rmdir() to fail. + * + * We must also force all dirty buffers belonging to unlogged relations out + * to the disk before making any file system changes. Otherwise a backend + * may fail if the buffer is chosen for eviction or at shutdown checkpoint + * which writes all dirty buffers to the disk. */ - RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT); + RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT | CHECKPOINT_FLUSH_ALL); /* * Check for existence of files in the target directory, i.e., objects of diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 07ea665..c66b27d 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -1205,9 +1205,10 @@ UnpinBuffer(volatile BufferDesc *buf, bool fixOwner) * * This is called at checkpoint time to write out all dirty shared buffers. * The checkpoint request flags should be passed in. If CHECKPOINT_IMMEDIATE - * is set, we disable delays between writes; if CHECKPOINT_IS_SHUTDOWN is - * set, we write even unlogged buffers, which are otherwise skipped. The - * remaining flags currently have no effect here. + * is set, we disable delays between writes; if CHECKPOINT_IS_SHUTDOWN, + * CHECKPOINT_END_OF_RECOVERY or CHECKPOINT_FLUSH_ALL is set, we write even + * unlogged buffers, which are otherwise skipped. The remaining flags + * currently have no effect here. */ static void BufferSync(int flags) @@ -1222,11 +1223,13 @@ BufferSync(int flags) ResourceOwnerEnlargeBuffers(CurrentResourceOwner); /* - * Unless this is a shutdown checkpoint, we write only permanent, dirty - * buffers. But at shutdown or end of recovery, we write all dirty - * buffers. + * Unless this is a shutdown checkpoint or we have been explicitly told, + * we write only permanent, dirty buffers. But at shutdown or end of + * recovery, we write all dirty buffers. */ - if (!((flags & CHECKPOINT_IS_SHUTDOWN) || (flags & CHECKPOINT_END_OF_RECOVERY))) + if (!((flags & CHECKPOINT_IS_SHUTDOWN) || + (flags & CHECKPOINT_END_OF_RECOVERY) || + (flags & CHECKPOINT_FLUSH_ALL))) mask |= BM_PERMANENT; /* diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 85f9cb7..c5ac599 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -247,12 +247,13 @@ extern bool XLOG_DEBUG; * recovery */ #define CHECKPOINT_IMMEDIATE 0x0004 /* Do it without delays */ #define CHECKPOINT_FORCE 0x0008 /* Force even if no activity */ +#define CHECKPOINT_FLUSH_ALL 0x0010 /* Flush all pages, including those + * belonging to unlogged tables */ /* These are important to RequestCheckpoint */ -#define CHECKPOINT_WAIT 0x0010 /* Wait for completion */ +#define CHECKPOINT_WAIT 0x0020 /* Wait for completion */ /* These indicate the cause of a checkpoint request */ -#define CHECKPOINT_CAUSE_XLOG 0x0020 /* XLOG consumption */ -#define CHECKPOINT_CAUSE_TIME 0x0040 /* Elapsed time */ - +#define CHECKPOINT_CAUSE_XLOG 0x0040 /* XLOG consumption */ +#define CHECKPOINT_CAUSE_TIME 0x0080 /* Elapsed time */ /* Checkpoint statistics */ typedef struct CheckpointStatsData {