diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c
index cc42946..db7c2c5 100644
--- a/src/backend/executor/execParallel.c
+++ b/src/backend/executor/execParallel.c
@@ -486,7 +486,7 @@ ExecInitParallelPlan(PlanState *planstate, EState *estate, int nworkers)
 		shm_toc_insert(pcxt->toc, PARALLEL_KEY_DSA, area_space);
 		pei->area = dsa_create_in_place(area_space, dsa_minsize,
 										LWTRANCHE_PARALLEL_QUERY_DSA,
-										"parallel_query_dsa",
+										NULL,
 										pcxt->seg);
 	}
 
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index cf6ae88..6c377c2 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -508,6 +508,7 @@ RegisterLWLockTranches(void)
 	LWLockRegisterTranche(LWTRANCHE_LOCK_MANAGER, "lock_manager");
 	LWLockRegisterTranche(LWTRANCHE_PREDICATE_LOCK_MANAGER,
 						  "predicate_lock_manager");
+	LWLockRegisterTranche(LWTRANCHE_PARALLEL_QUERY_DSA, "parallel_query_dsa");
 
 	/* Register named tranches. */
 	for (i = 0; i < NamedLWLockTrancheRequests; i++)
@@ -583,7 +584,8 @@ LWLockNewTrancheId(void)
  * Register a tranche ID in the lookup table for the current process.  This
  * routine will save a pointer to the tranche name passed as an argument,
  * so the name should be allocated in a backend-lifetime context
- * (TopMemoryContext, static variable, or similar).
+ * (TopMemoryContext, static variable, or similar), unless it is explicitly
+ * deregistered at an appropriate time.
  */
 void
 LWLockRegisterTranche(int tranche_id, char *tranche_name)
@@ -609,6 +611,20 @@ LWLockRegisterTranche(int tranche_id, char *tranche_name)
 }
 
 /*
+ * Deregister a tranche ID that was previously registered with
+ * LWLockRegisterTranche.
+ */
+void
+LWLockDeregisterTranche(int tranche_id)
+{
+	Assert(LWLockTrancheArray != NULL);
+	Assert(tranche_id < LWLockTranchesAllocated);
+	Assert(LWLockTrancheArray[tranche_id] != NULL);
+	
+	LWLockTrancheArray[tranche_id] = NULL;
+}
+
+/*
  * RequestNamedLWLockTranche
  *		Request that extra LWLocks be allocated during postmaster
  *		startup.
diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c
index 988a297..b5a2449 100644
--- a/src/backend/utils/mmgr/dsa.c
+++ b/src/backend/utils/mmgr/dsa.c
@@ -421,7 +421,10 @@ static void check_for_freed_segments(dsa_area *area);
  * when possible matters, and we have no provision for recycling them.  So,
  * we require the caller to provide one.  The caller must also provide the
  * tranche name, so that we can distinguish LWLocks belonging to different
- * DSAs.
+ * DSAs.  The exception is that if the tranche has already been registered by
+ * the caller, a NULL pointer should be passed in; in that case, DSA will not
+ * register and deregister the tranche.  If it is non-NULL, tranche_name must
+ * not be a zero-length string.
  */
 dsa_area *
 dsa_create(int tranche_id, const char *tranche_name)
@@ -626,6 +629,16 @@ dsa_release_in_place(void *place)
 				dsm_unpin_segment(handle);
 		}
 	}
+
+	/*
+	 * If a tranche name was passed in to 'create', then this process has
+	 * registered it.  In that case we had better deregister it, or the
+	 * tranche name table will finish up pointing to memory that is about to
+	 * go away.
+	 */
+	if (control->lwlock_tranche_name[0] != '\0')
+		LWLockDeregisterTranche(control->lwlock_tranche_id);
+
 	LWLockRelease(&control->lock);
 }
 
@@ -1151,6 +1164,9 @@ create_internal(void *place, size_t size,
 	Size		metadata_bytes;
 	int			i;
 
+	/* Empty string not permitted as we use it as a sentinel value. */
+	Assert(tranche_name == NULL || tranche_name[0] != '\0');
+
 	/* Sanity check on the space we have to work in. */
 	if (size < dsa_minimum_size())
 		elog(ERROR, "dsa_area space must be at least %zu, but %zu provided",
@@ -1192,7 +1208,10 @@ create_internal(void *place, size_t size,
 	control->refcnt = 1;
 	control->freed_segment_counter = 0;
 	control->lwlock_tranche_id = tranche_id;
-	strlcpy(control->lwlock_tranche_name, tranche_name, DSA_MAXLEN);
+	if (tranche_name != NULL)
+		strlcpy(control->lwlock_tranche_name, tranche_name, DSA_MAXLEN);
+	else
+		control->lwlock_tranche_name[0] = '\0';
 
 	/*
 	 * Create the dsa_area object that this backend will use to access the
@@ -1204,8 +1223,9 @@ create_internal(void *place, size_t size,
 	area->mapping_pinned = false;
 	memset(area->segment_maps, 0, sizeof(dsa_segment_map) * DSA_MAX_SEGMENTS);
 	area->high_segment_index = 0;
-	LWLockRegisterTranche(control->lwlock_tranche_id,
-						  control->lwlock_tranche_name);
+	if (control->lwlock_tranche_name[0] != '\0')
+		LWLockRegisterTranche(control->lwlock_tranche_id,
+							  control->lwlock_tranche_name);
 	LWLockInitialize(&control->lock, control->lwlock_tranche_id);
 	for (i = 0; i < DSA_NUM_SIZE_CLASSES; ++i)
 		LWLockInitialize(DSA_SCLASS_LOCK(area, i),
@@ -1262,8 +1282,9 @@ attach_internal(void *place, dsm_segment *segment, dsa_handle handle)
 	memset(&area->segment_maps[0], 0,
 		   sizeof(dsa_segment_map) * DSA_MAX_SEGMENTS);
 	area->high_segment_index = 0;
-	LWLockRegisterTranche(control->lwlock_tranche_id,
-						  control->lwlock_tranche_name);
+	if (control->lwlock_tranche_name[0] != '\0')
+		LWLockRegisterTranche(control->lwlock_tranche_id,
+							  control->lwlock_tranche_name);
 
 	/* Set up the segment map for this process's mapping. */
 	segment_map = &area->segment_maps[0];
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 3ca4db0..2b20b8f 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -184,6 +184,7 @@ extern LWLockPadded *GetNamedLWLockTranche(const char *tranche_name);
  */
 extern int	LWLockNewTrancheId(void);
 extern void LWLockRegisterTranche(int tranche_id, char *tranche_name);
+extern void LWLockDeregisterTranche(int tranche_id);
 extern void LWLockInitialize(LWLock *lock, int tranche_id);
 
 /*
