diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2008-04-18 06:48:38 +0000 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2008-04-18 06:48:38 +0000 |
commit | 9cb91f90c95906347cd4d42fcf24a12a6e6a679e (patch) | |
tree | f8e45cf44544e281bb763aa99dfded044de66964 /src/backend/commands/dbcommands.c | |
parent | 87a2f050a9b53b3effe0a4da9733b5dba784463d (diff) | |
download | postgresql-9cb91f90c95906347cd4d42fcf24a12a6e6a679e.tar.gz postgresql-9cb91f90c95906347cd4d42fcf24a12a6e6a679e.zip |
Fix two race conditions between the pending unlink mechanism that was put in
place to prevent reusing relation OIDs before next checkpoint, and DROP
DATABASE. First, if a database was dropped, bgwriter would still try to unlink
the files that the rmtree() call by the DROP DATABASE command has already
deleted, or is just about to delete. Second, if a database is dropped, and
another database is created with the same OID, bgwriter would in the worst
case delete a relation in the new database that happened to get the same OID
as a dropped relation in the old database.
To fix these race conditions:
- make rmtree() ignore ENOENT errors. This fixes the 1st race condition.
- make ForgetDatabaseFsyncRequests forget unlink requests as well.
- force checkpoint on in dropdb on all platforms
Since ForgetDatabaseFsyncRequests() is asynchronous, the 2nd change isn't
enough on its own to fix the problem of dropping and creating a database with
same OID, but forcing a checkpoint on DROP DATABASE makes it sufficient.
Per Tom Lane's bug report and proposal. Backpatch to 8.3.
Diffstat (limited to 'src/backend/commands/dbcommands.c')
-rw-r--r-- | src/backend/commands/dbcommands.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 857db388a8f..7055b0fe98e 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.206 2008/04/16 23:59:40 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.207 2008/04/18 06:48:38 heikki Exp $ * *------------------------------------------------------------------------- */ @@ -715,18 +715,20 @@ dropdb(const char *dbname, bool missing_ok) pgstat_drop_database(db_id); /* - * Tell bgwriter to forget any pending fsync requests for files in the - * database; else it'll fail at next checkpoint. + * Tell bgwriter to forget any pending fsync and unlink requests for files + * in the database; else the fsyncs will fail at next checkpoint, or worse, + * it will delete files that belong to a newly created database with the + * same OID. */ ForgetDatabaseFsyncRequests(db_id); /* - * On Windows, force a checkpoint so that the bgwriter doesn't hold any - * open files, which would cause rmdir() to fail. + * Force a checkpoint to make sure the bgwriter has received the message + * sent by ForgetDatabaseFsyncRequests. On Windows, this also ensures that + * the bgwriter doesn't hold any open files, which would cause rmdir() to + * fail. */ -#ifdef WIN32 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT); -#endif /* * Remove all tablespace subdirs belonging to the database. |