3737 *
3838 *
3939 * IDENTIFICATION
40- * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.28 2005/10/15 02:49:15 momjian Exp $
40+ * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.29 2006/01/19 04:45:38 tgl Exp $
4141 *
4242 *-------------------------------------------------------------------------
4343 */
@@ -83,12 +83,9 @@ static void set_short_version(const char *path);
8383 * If tablespaces are not supported, this is just a no-op; CREATE DATABASE
8484 * is expected to create the default subdirectory for the database.
8585 *
86- * isRedo indicates that we are creating an object during WAL replay;
87- * we can skip doing locking in that case (and should do so to avoid
88- * any possible problems with pg_tablespace not being valid).
89- *
90- * Also, when isRedo is true, we will cope with the possibility of the
91- * tablespace not being there either --- this could happen if we are
86+ * isRedo indicates that we are creating an object during WAL replay.
87+ * In this case we will cope with the possibility of the tablespace
88+ * directory not being there either --- this could happen if we are
9289 * replaying an operation on a table in a subsequently-dropped tablespace.
9390 * We handle this by making a directory in the place where the tablespace
9491 * symlink would normally be. This isn't an exact replay of course, but
@@ -118,16 +115,10 @@ TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo)
118115if (errno == ENOENT )
119116{
120117/*
121- * Acquire ExclusiveLock on pg_tablespace to ensure that no DROP
122- * TABLESPACE or TablespaceCreateDbspace is running concurrently.
123- * Simple reads from pg_tablespace are OK.
118+ * Acquire TablespaceCreateLock to ensure that no DROP TABLESPACE
119+ * or TablespaceCreateDbspace is running concurrently.
124120 */
125- Relation rel ;
126-
127- if (!isRedo )
128- rel = heap_open (TableSpaceRelationId ,ExclusiveLock );
129- else
130- rel = NULL ;
121+ LWLockAcquire (TablespaceCreateLock ,LW_EXCLUSIVE );
131122
132123/*
133124 * Recheck to see if someone created the directory while we were
@@ -166,9 +157,7 @@ TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo)
166157}
167158}
168159
169- /* OK to drop the exclusive lock */
170- if (!isRedo )
171- heap_close (rel ,ExclusiveLock );
160+ LWLockRelease (TablespaceCreateLock );
172161}
173162else
174163{
@@ -401,15 +390,11 @@ DropTableSpace(DropTableSpaceStmt *stmt)
401390/* don't call this in a transaction block */
402391PreventTransactionChain ((void * )stmt ,"DROP TABLESPACE" );
403392
404- /*
405- * Acquire ExclusiveLock on pg_tablespace to ensure that no one else is
406- * trying to do DROP TABLESPACE or TablespaceCreateDbspace concurrently.
407- */
408- rel = heap_open (TableSpaceRelationId ,ExclusiveLock );
409-
410393/*
411394 * Find the target tuple
412395 */
396+ rel = heap_open (TableSpaceRelationId ,RowExclusiveLock );
397+
413398ScanKeyInit (& entry [0 ],
414399Anum_pg_tablespace_spcname ,
415400BTEqualStrategyNumber ,F_NAMEEQ ,
@@ -448,6 +433,12 @@ DropTableSpace(DropTableSpaceStmt *stmt)
448433 */
449434deleteSharedDependencyRecordsFor (TableSpaceRelationId ,tablespaceoid );
450435
436+ /*
437+ * Acquire TablespaceCreateLock to ensure that no TablespaceCreateDbspace
438+ * is running concurrently.
439+ */
440+ LWLockAcquire (TablespaceCreateLock ,LW_EXCLUSIVE );
441+
451442/*
452443 * Try to remove the physical infrastructure
453444 */
@@ -471,6 +462,11 @@ DropTableSpace(DropTableSpaceStmt *stmt)
471462(void )XLogInsert (RM_TBLSPC_ID ,XLOG_TBLSPC_DROP ,rdata );
472463}
473464
465+ /*
466+ * Allow TablespaceCreateDbspace again.
467+ */
468+ LWLockRelease (TablespaceCreateLock );
469+
474470/* We keep the lock on pg_tablespace until commit */
475471heap_close (rel ,NoLock );
476472#else /* !HAVE_SYMLINK */
@@ -507,10 +503,10 @@ remove_tablespace_directories(Oid tablespaceoid, bool redo)
507503 * use the tablespace from that database will simply recreate the
508504 * subdirectory via TablespaceCreateDbspace.)
509505 *
510- * Since we holdexclusive lock , no one else should be creating any fresh
511- * subdirectories in parallel. It is possible that new files are being
512- * created within subdirectories, though, so the rmdir call could fail.
513- * Worst consequence is a less friendly error message.
506+ * Since we holdTablespaceCreateLock , no one else should be creating any
507+ *fresh subdirectories in parallel. It is possible that new files are
508+ *being created within subdirectories, though, so the rmdir call could
509+ *fail. Worst consequence is a less friendly error message.
514510 */
515511dirdesc = AllocateDir (location );
516512if (dirdesc == NULL )