diff --git a/doc/src/sgml/backup.sgml b/doc/src/sgml/backup.sgml index ba55eb634ae9dd3cc6e3fbb04591c77ffca74dc2..01cdae83d69f3a6352bf0eaed03ad0000b8adad8 100644 --- a/doc/src/sgml/backup.sgml +++ b/doc/src/sgml/backup.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.68 2005/06/21 20:45:43 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.69 2005/06/25 22:47:28 tgl Exp $ --> <chapter id="backup"> <title>Backup and Restore</title> @@ -1119,6 +1119,18 @@ restore_command = 'copy /mnt/server/archivedir/%f "%p"' # Windows </para> </listitem> + <listitem> + <para> + If a <command>CREATE DATABASE</> command is executed while a base + backup is being taken, and then the template database that the + <command>CREATE DATABASE</> copied is modified while the base backup + is still in progress, it is possible that recovery will cause those + modifications to be propagated into the created database as well. + This is of course undesirable. To avoid this risk, it is best not to + modify any template databases while taking a base backup. + </para> + </listitem> + <listitem> <para> <command>CREATE TABLESPACE</> commands are WAL-logged with the literal diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 135c8a73f531412ad7f5237bf7209c8ea1cbc897..6fa6aa5b44bacc07063b7772b7ae73952c7a70bd 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.160 2005/06/21 04:02:31 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.161 2005/06/25 22:47:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -514,6 +514,36 @@ createdb(const CreatedbStmt *stmt) /* Close pg_database, but keep exclusive lock till commit */ heap_close(pg_database_rel, NoLock); + /* + * We force a checkpoint before committing. This effectively means + * that committed XLOG_DBASE_CREATE operations will never need to be + * replayed (at least not in ordinary crash recovery; we still have + * to make the XLOG entry for the benefit of PITR operations). + * This avoids two nasty scenarios: + * + * #1: When PITR is off, we don't XLOG the contents of newly created + * indexes; therefore the drop-and-recreate-whole-directory behavior + * of DBASE_CREATE replay would lose such indexes. + * + * #2: Since we have to recopy the source database during DBASE_CREATE + * replay, we run the risk of copying changes in it that were committed + * after the original CREATE DATABASE command but before the system + * crash that led to the replay. This is at least unexpected and at + * worst could lead to inconsistencies, eg duplicate table names. + * + * (Both of these were real bugs in releases 8.0 through 8.0.3.) + * + * In PITR replay, the first of these isn't an issue, and the second + * is only a risk if the CREATE DATABASE and subsequent template + * database change both occur while a base backup is being taken. + * There doesn't seem to be much we can do about that except document + * it as a limitation. + * + * Perhaps if we ever implement CREATE DATABASE in a less cheesy + * way, we can avoid this. + */ + RequestCheckpoint(true); + /* * Set flag to update flat database file at commit. */