@@ -4544,25 +4544,46 @@ xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid, XLogRecPtr lsn)
45444544}
45454545
45464546/* Make sure files supposed to be dropped are dropped */
4547- for ( i = 0 ; i < xlrec -> nrels ; i ++ )
4547+ if ( xlrec -> nrels > 0 )
45484548{
4549- SMgrRelation srel = smgropen (xlrec -> xnodes [i ],InvalidBackendId );
4550- ForkNumber fork ;
4549+ /*
4550+ * First update minimum recovery point to cover this WAL record. Once
4551+ * a relation is deleted, there's no going back. The buffer manager
4552+ * enforces the WAL-first rule for normal updates to relation files,
4553+ * so that the minimum recovery point is always updated before the
4554+ * corresponding change in the data file is flushed to disk, but we
4555+ * have to do the same here since we're bypassing the buffer manager.
4556+ *
4557+ * Doing this before deleting the files means that if a deletion fails
4558+ * for some reason, you cannot start up the system even after restart,
4559+ * until you fix the underlying situation so that the deletion will
4560+ * succeed. Alternatively, we could update the minimum recovery point
4561+ * after deletion, but that would leave a small window where the
4562+ * WAL-first rule would be violated.
4563+ */
4564+ XLogFlush (lsn );
45514565
4552- for (fork = 0 ;fork <= MAX_FORKNUM ; fork ++ )
4566+ for (i = 0 ;i < xlrec -> nrels ; i ++ )
45534567{
4554- XLogDropRelation (xlrec -> xnodes [i ],fork );
4555- smgrdounlink (srel ,fork , true);
4568+ SMgrRelation srel = smgropen (xlrec -> xnodes [i ],InvalidBackendId );
4569+ ForkNumber fork ;
4570+
4571+ for (fork = 0 ;fork <=MAX_FORKNUM ;fork ++ )
4572+ {
4573+ XLogDropRelation (xlrec -> xnodes [i ],fork );
4574+ smgrdounlink (srel ,fork , true);
4575+ }
4576+ smgrclose (srel );
45564577}
4557- smgrclose (srel );
45584578}
45594579
45604580/*
45614581 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
4562- * in normal operation. For example, in DROP DATABASE, we delete all the
4563- * files belonging to the database, and then commit the transaction. If we
4564- * crash after all the files have been deleted but before the commit, you
4565- * have an entry in pg_database without any files. To minimize the window
4582+ * in normal operation. For example, in CREATE DATABASE, we copy all files
4583+ * from the template database, and then commit the transaction. If we
4584+ * crash after all the files have been copied but before the commit, you
4585+ * have files in the data directory without an entry in pg_database. To
4586+ * minimize the window
45664587 * for that, we use ForceSyncCommit() to rush the commit record to disk as
45674588 * quick as possible. We have the same window during recovery, and forcing
45684589 * an XLogFlush() (which updates minRecoveryPoint during recovery) helps