aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/dbcommands.c
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2022-02-12 10:21:23 +1300
committerThomas Munro <tmunro@postgresql.org>2022-02-12 10:21:23 +1300
commit4eb2176318d0561846c1f9fb3c68bede799d640f (patch)
treeae824847ecc96384f9fbcd7010a854cf50ec3e8c /src/backend/commands/dbcommands.c
parente5691cc9170bcd6c684715c2755d919c5a16fea2 (diff)
downloadpostgresql-4eb2176318d0561846c1f9fb3c68bede799d640f.tar.gz
postgresql-4eb2176318d0561846c1f9fb3c68bede799d640f.zip
Fix DROP {DATABASE,TABLESPACE} on Windows.
Previously, it was possible for DROP DATABASE, DROP TABLESPACE and ALTER DATABASE SET TABLESPACE to fail because other backends still had file handles open for dropped tables. Windows won't allow a directory containing unlinked-but-still-open files to be unlinked. Tackle this problem by forcing all backends to close all smgr fds. No change for Unix systems, which don't suffer from the problem, but the new code path can be tested by Unix-based developers by defining USE_BARRIER_SMGRRELEASE explicitly. It's possible that PROCSIGNAL_BARRIER_SMGRRELEASE will have more bug-fixing applications soon (under discussion). Note that this is the first user of the ProcSignalBarrier mechanism from commit 16a4e4aec. It could in principle be back-patched as far as 14, but since field complaints are rare and ProcSignalBarrier hasn't been battle-tested, that seems like a bad idea. Fix in master only, where these failures have started to show up in automated testing due to new tests. Suggested-by: Andres Freund <andres@anarazel.de> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Daniel Gustafsson <daniel@yesql.se> Reviewed-by: Robert Haas <robertmhaas@gmail.com> Discussion: https://postgr.es/m/CA+hUKGLdemy2gBm80kz20GTe6hNVwoErE8KwcJk6-U56oStjtg@mail.gmail.com
Diffstat (limited to 'src/backend/commands/dbcommands.c')
-rw-r--r--src/backend/commands/dbcommands.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index e673138cbdf..700b1209652 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -997,12 +997,15 @@ dropdb(const char *dbname, bool missing_ok, bool force)
/*
* Force a checkpoint to make sure the checkpointer has received the
- * message sent by ForgetDatabaseSyncRequests. On Windows, this also
- * ensures that background procs don't hold any open files, which would
- * cause rmdir() to fail.
+ * message sent by ForgetDatabaseSyncRequests.
*/
RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT);
+#if defined(USE_BARRIER_SMGRRELEASE)
+ /* Close all smgr fds in all backends. */
+ WaitForProcSignalBarrier(EmitProcSignalBarrier(PROCSIGNAL_BARRIER_SMGRRELEASE));
+#endif
+
/*
* Remove all tablespace subdirs belonging to the database.
*/
@@ -1251,6 +1254,11 @@ movedb(const char *dbname, const char *tblspcname)
RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT
| CHECKPOINT_FLUSH_ALL);
+#if defined(USE_BARRIER_SMGRRELEASE)
+ /* Close all smgr fds in all backends. */
+ WaitForProcSignalBarrier(EmitProcSignalBarrier(PROCSIGNAL_BARRIER_SMGRRELEASE));
+#endif
+
/*
* Now drop all buffers holding data of the target database; they should
* no longer be dirty so DropDatabaseBuffers is safe.
@@ -2258,6 +2266,11 @@ dbase_redo(XLogReaderState *record)
/* Clean out the xlog relcache too */
XLogDropDatabase(xlrec->db_id);
+#if defined(USE_BARRIER_SMGRRELEASE)
+ /* Close all sgmr fds in all backends. */
+ WaitForProcSignalBarrier(EmitProcSignalBarrier(PROCSIGNAL_BARRIER_SMGRRELEASE));
+#endif
+
for (i = 0; i < xlrec->ntablespaces; i++)
{
dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_ids[i]);