Force a checkpoint in CREATE DATABASE before starting to copy the files,
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 9 Oct 2008 10:34:06 +0000 (10:34 +0000)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 9 Oct 2008 10:34:06 +0000 (10:34 +0000)
to process any pending unlinks for the source database.

Before, if you dropped a relation in the template database just before
CREATE DATABASE, and a checkpoint happened during copydir(), the checkpoint
might delete a file that we're just about to copy, causing lstat() in
copydir() to fail with ENOENT.

Backpatch to 8.3, where the pending unlinks were introduced.

Per report by Matthew Wakeling and analysis by Tom Lane.

src/backend/commands/dbcommands.c

index 37c2f45c727b0e19beba8b9465832e8be1aeefd1..1efe0c3777b9c9314a976f4407486360bd863c81 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.213 2008/09/30 10:52:12 heikki Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.214 2008/10/09 10:34:06 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -539,10 +539,15 @@ createdb(const CreatedbStmt *stmt)
        copyTemplateDependencies(src_dboid, dboid);
 
        /*
-        * Force dirty buffers out to disk, to ensure source database is
-        * up-to-date for the copy.
+        * 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.
         */
-       FlushDatabaseBuffers(src_dboid);
+       RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT);
 
        /*
         * Once we start copying subdirectories, we need to be able to clean 'em