--On Freitag, Mai 25, 2007 00:02:06 +0000 Jaime Casanova <[EMAIL PROTECTED]> wrote:

the original patch is from Albert Cervera =)

Ah, missed that, thanks ;)




sounds good. can we see the new patch?

Attached tablespace.c.diff shows my current changes to use an OID lookup list.


the reason for those messages is that the tablespace can get full or
can be dropped before use, so we throw the message for the dba to take
actions. if no one thinks is a good idea the message can be removed.


I could imagine that this could irritate DBA's (at least, that is what happened to me during testing). It's okay that someone could drop a tablespace concurrently to other transactions, but i have concerns that with temp_tablespaces this could happen during _queries_. Do queries delete/recreate temp files during execution, maybe within sorts so that the used temp tablespace looks empty for a certain period of time?

The silent
mechanism to drop a tablespace during temporary usage makes me a little
bit uncomfortable about its robustness.


maybe using the list you put in TopMemoryContext we can deny the
ability to drop the tablespace until it's removed from the list of
temp tablespaces.

That would mean we have to share this information between backends. This looks complicated since every user could have its own temp_tablespaces GUC....


--
 Thanks

                   Bernd
Index: tablespace.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablespace.c,v
retrieving revision 1.45
diff -c -B -r1.45 tablespace.c
*** tablespace.c	22 Mar 2007 19:51:44 -0000	1.45
--- tablespace.c	25 May 2007 15:27:23 -0000
***************
*** 63,73 ****
  #include "utils/fmgroids.h"
  #include "utils/guc.h"
  #include "utils/lsyscache.h"
  
  
! /* GUC variable */
  char	   *default_tablespace = NULL;
  
  
  static bool remove_tablespace_directories(Oid tablespaceoid, bool redo);
  static void set_short_version(const char *path);
--- 63,80 ----
  #include "utils/fmgroids.h"
  #include "utils/guc.h"
  #include "utils/lsyscache.h"
+ #include "utils/memutils.h"
  
  
! /* GUC variables */
  char	   *default_tablespace = NULL;
+ char       *temp_tablespaces = NULL;
  
+ static int	   next_temp_tablespace;
+ static int	   num_temp_tablespaces;
+ 
+ /* OID list of current temp tablespaces */
+ static List *tmp_tblspc_lookup = NIL;
  
  static bool remove_tablespace_directories(Oid tablespaceoid, bool redo);
  static void set_short_version(const char *path);
***************
*** 935,940 ****
--- 942,1080 ----
  	return result;
  }
  
+ /*
+  * Routines for handling the GUC variable 'temp_tablespaces'.
+  */
+ 
+ /* assign_hook: validate new temp_tablespaces, do extra actions as needed */
+ const char *
+ assign_temp_tablespaces(const char *newval, bool doit, GucSource source)
+ {
+ 	char	   *rawname;
+ 	ListCell   *l;
+ 	MemoryContext cur_cntxt;
+ 	List	   *namelist = NIL;
+ 	List       *oidlist = NIL;
+ 
+ 	/* Need a modifiable copy of string */
+ 	rawname = pstrdup(newval);
+ 
+ 	/* Parse string into list of identifiers */
+ 	if (!SplitIdentifierString(rawname, ',', &namelist))
+ 	{
+ 		/* syntax error in name list */
+ 		pfree(rawname);
+ 		list_free(namelist);
+ 		return NULL;
+ 	}
+
+ 	num_temp_tablespaces = 0;
+
+ 	foreach(l, namelist)
+ 	{
+ 		char	   *curname = (char *) lfirst(l);
+ 		if (curname[0] == '\0')
+ 			continue;
+ 
+ 		/*
+ 		 * If we aren't inside a transaction, we cannot do database access so
+ 		 * cannot verify the individual names.	Must accept the list on faith.
+ 		 */
+ 		if (source >= PGC_S_INTERACTIVE && IsTransactionState())
+ 		{
+ 			/*
+ 			 * Verify that all the names are valid tablespace names 
+ 			 * We do not check for USAGE rights should we?
+ 			 */
+ 			Oid cur_tblspc = get_tablespace_oid(curname);
+ 			if (cur_tblspc == InvalidOid)
+ 			{
+ 				ereport((source == PGC_S_TEST) ? NOTICE : ERROR,
+ 						(errcode(ERRCODE_UNDEFINED_OBJECT),
+ 						 errmsg("tablespace \"%s\" does not exist", curname)));
+ 			}
+ 			else
+ 			{
+ 				/* 
+ 				 * Append new OID to temporary list. We can't
+ 				 * use the lookup table directly, because there could
+ 				 * be an ereport() in subsequent loops. 
+ 				 */
+ 				oidlist = lappend_oid(oidlist, cur_tblspc);
+ 			}
+ 		}
+ 		num_temp_tablespaces++;
+ 	}
+ 
+ 	/*
+ 	 * Select the first tablespace to use
+ 	 */
+ 	Assert(num_temp_tablespaces >= 0);
+ 	if (num_temp_tablespaces != 0)
+ 		next_temp_tablespace = MyProcPid % num_temp_tablespaces;
+ 
+ 	/* Looks good for now, free any old lookup table and copy new OID
+ 	   list to our lookup table in permanent storage */
+ 	cur_cntxt = MemoryContextSwitchTo(TopMemoryContext);
+
+ 	if (tmp_tblspc_lookup != NIL)
+ 	{
+ 		list_free(tmp_tblspc_lookup);
+ 	}
+ 
+ 	tmp_tblspc_lookup = list_copy(oidlist);
+ 	MemoryContextSwitchTo(cur_cntxt);
+
+ 	pfree(rawname);
+ 	list_free(namelist);
+ 	return newval;
+ }
+ 
+ /*
+  * GetTempTablespace -- get the OID of the tablespace for temporary objects
+  *
+  * May return InvalidOid to indicate "use the database's default tablespace"
+  */
+ Oid
+ GetTempTablespace(void)
+ {
+ 	Oid	     result;
+ 	char     *curname;
+
+ 	if ( temp_tablespaces == NULL )
+ 		return InvalidOid;
+
+ 	/* OID lookup cache not available */
+ 	if ( tmp_tblspc_lookup == NIL)
+ 		return InvalidOid;
+ 
+ 	/* get next OID */
+ 	result = list_nth_oid(tmp_tblspc_lookup, next_temp_tablespace);
+ 
+ 	/* validate cached OID, if still available ... */
+ 	curname = get_tablespace_name(result);
+ 
+ 	/* Prepare for the next time the function is called */
+ 	next_temp_tablespace++;
+ 	if (next_temp_tablespace == num_temp_tablespaces)
+ 		next_temp_tablespace = 0;
+ 
+ 	/* If the cached OID is invalid, return InvalidOid immediately.
+ 	   We don't care to try any remaining tablespaces now */
+ 
+ 	if ( curname == NULL || curname[0] == '\0') {
+ 		return InvalidOid;
+ 	}
+ 
+ 	/*
+ 	 * Allow explicit specification of database's default tablespace in
+ 	 * default_tablespace without triggering permissions checks.
+ 	 */
+ 	if (result == MyDatabaseTableSpace)
+ 		result = InvalidOid;
+ 
+ 	return result;
+ }
  
  /*
   * get_tablespace_oid - given a tablespace name, look up the OID
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

               http://archives.postgresql.org

Reply via email to