diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 235b4422969133dcf7f25091158f190f3159f3cc..a9df3a5806d867712dcb9ddf76522fddbf861c83 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7771,9 +7771,9 @@ LogCheckpointStart(int flags, bool restartpoint) * the main message, but what about all the flags? */ if (restartpoint) - msg = "restartpoint starting:%s%s%s%s%s%s%s"; + msg = "restartpoint starting:%s%s%s%s%s%s%s%s"; else - msg = "checkpoint starting:%s%s%s%s%s%s%s"; + msg = "checkpoint starting:%s%s%s%s%s%s%s%s"; elog(LOG, msg, (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "", @@ -7782,7 +7782,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 b52e6b9bc07c004b966df7e80f9555dc4fe635ef..1c56b4de0d2228ca56f9e222e90f69e45e6657de 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -549,15 +549,17 @@ createdb(const CreatedbStmt *stmt) InvokeObjectPostCreateHook(DatabaseRelationId, dboid, 0); /* - * Force a checkpoint before starting the copy. This will force dirty - * buffers out to disk, to ensure source database is up-to-date on disk - * for the copy. FlushDatabaseBuffers() would suffice for that, but we - * also want to process any pending unlink requests. Otherwise, if a - * checkpoint happened while we're copying files, a file might be deleted - * just when we're about to copy it, causing the lstat() call in copydir() - * to fail with ENOENT. + * Force a checkpoint before starting the copy. This will force all dirty + * buffers, including those of unlogged tables, out to disk, to ensure + * source database is up-to-date on disk for the copy. + * FlushDatabaseBuffers() would suffice for that, but we also want + * to process any pending unlink requests. Otherwise, if a checkpoint + * happened while we're copying files, a file might be deleted just when + * we're about to copy it, causing the lstat() call in copydir() to fail + * with ENOENT. */ - RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT); + RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT + | CHECKPOINT_FLUSH_ALL); /* * Once we start copying subdirectories, we need to be able to clean 'em @@ -1138,8 +1140,9 @@ movedb(const char *dbname, const char *tblspcname) dst_dbpath = GetDatabasePath(db_id, dst_tblspcoid); /* - * Force a checkpoint before proceeding. This will force dirty buffers out - * to disk, to ensure source database is up-to-date on disk for the copy. + * Force a checkpoint before proceeding. This will force all dirty + * buffers, including those of unlogged tables, out to disk, to ensure + * source database is up-to-date on disk for the copy. * FlushDatabaseBuffers() would suffice for that, but we also want to * process any pending unlink requests. Otherwise, the check for existing * files in the target directory might fail unnecessarily, not to mention @@ -1147,7 +1150,8 @@ movedb(const char *dbname, const char *tblspcname) * On Windows, this also ensures that background procs don't hold any open * files, which would cause rmdir() to fail. */ - 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 45d1d61d95dc303a9621834289962aca80be7fc0..57067ef57a6009663049c138858bc19ed876139d 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -1493,9 +1493,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) @@ -1510,11 +1511,12 @@ 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 | CHECKPOINT_END_OF_RECOVERY | + CHECKPOINT_FLUSH_ALL)))) mask |= BM_PERMANENT; /* diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 0f068d91f387a92b620159440bdf086b74942616..ca35f3e65f795561766095420cb4dc8eeb6734e8 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -253,6 +253,8 @@ extern bool XLOG_DEBUG; /* These indicate the cause of a checkpoint request */ #define CHECKPOINT_CAUSE_XLOG 0x0020 /* XLOG consumption */ #define CHECKPOINT_CAUSE_TIME 0x0040 /* Elapsed time */ +#define CHECKPOINT_FLUSH_ALL 0x0080 /* Flush all pages, including those + * belonging to unlogged tables */ /* Checkpoint statistics */ typedef struct CheckpointStatsData