mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Prevent re-use of a deleted relation's relfilenode until after the next
checkpoint. This guards against an unlikely data-loss scenario in which we re-use the relfilenode, then crash, then replay the deletion and recreation of the file. Even then we'd be OK if all insertions into the new relation had been WAL-logged ... but that's not guaranteed given all the no-WAL-logging optimizations that have recently been added. Patch by Heikki Linnakangas, per a discussion last month.
This commit is contained in:
		@@ -37,7 +37,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * IDENTIFICATION
 | 
			
		||||
 *	  $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.49 2007/08/01 22:45:08 tgl Exp $
 | 
			
		||||
 *	  $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.50 2007/11/15 20:36:40 tgl Exp $
 | 
			
		||||
 *
 | 
			
		||||
 *-------------------------------------------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
@@ -57,6 +57,7 @@
 | 
			
		||||
#include "commands/comment.h"
 | 
			
		||||
#include "commands/tablespace.h"
 | 
			
		||||
#include "miscadmin.h"
 | 
			
		||||
#include "postmaster/bgwriter.h"
 | 
			
		||||
#include "storage/fd.h"
 | 
			
		||||
#include "utils/acl.h"
 | 
			
		||||
#include "utils/builtins.h"
 | 
			
		||||
@@ -460,13 +461,29 @@ DropTableSpace(DropTableSpaceStmt *stmt)
 | 
			
		||||
	LWLockAcquire(TablespaceCreateLock, LW_EXCLUSIVE);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Try to remove the physical infrastructure
 | 
			
		||||
	 * Try to remove the physical infrastructure. 
 | 
			
		||||
	 */
 | 
			
		||||
	if (!remove_tablespace_directories(tablespaceoid, false))
 | 
			
		||||
		ereport(ERROR,
 | 
			
		||||
				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
 | 
			
		||||
				 errmsg("tablespace \"%s\" is not empty",
 | 
			
		||||
						tablespacename)));
 | 
			
		||||
	{
 | 
			
		||||
		/*
 | 
			
		||||
		 * Not all files deleted?  However, there can be lingering empty files
 | 
			
		||||
		 * in the directories, left behind by for example DROP TABLE, that
 | 
			
		||||
		 * have been scheduled for deletion at next checkpoint (see comments
 | 
			
		||||
		 * in mdunlink() for details).  We could just delete them immediately,
 | 
			
		||||
		 * but we can't tell them apart from important data files that we
 | 
			
		||||
		 * mustn't delete.  So instead, we force a checkpoint which will clean
 | 
			
		||||
		 * out any lingering files, and try again.
 | 
			
		||||
		 */
 | 
			
		||||
		RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT);
 | 
			
		||||
		if (!remove_tablespace_directories(tablespaceoid, false))
 | 
			
		||||
		{
 | 
			
		||||
			/* Still not empty, the files must be important then */
 | 
			
		||||
			ereport(ERROR,
 | 
			
		||||
					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
 | 
			
		||||
					 errmsg("tablespace \"%s\" is not empty",
 | 
			
		||||
							tablespacename)));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Record the filesystem change in XLOG */
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user