Commit 6a178266 authored by Tom Lane's avatar Tom Lane

Change hashscan.c to keep its list of active hash index scans in

TopMemoryContext, rather than scattered through executor per-query contexts.
This poses no danger of memory leak since the ResourceOwner mechanism
guarantees release of no-longer-needed items.  It is needed because the
per-query context might already be released by the time we try to clean up
the hash scan list.  Report by ykhuang, diagnosis by Heikki.

Back-patch to 8.0, where the ResourceOwner-based cleanup was introduced.
The given test case does not fail before 8.2, probably because we rearranged
transaction abort processing somehow; but this coding is undoubtedly risky
so I'll patch 8.0 and 8.1 anyway.
parent b2facfd9
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/hash/hashscan.c,v 1.43 2008/01/01 19:45:46 momjian Exp $ * $PostgreSQL: pgsql/src/backend/access/hash/hashscan.c,v 1.44 2008/03/07 15:59:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -16,9 +16,20 @@ ...@@ -16,9 +16,20 @@
#include "postgres.h" #include "postgres.h"
#include "access/hash.h" #include "access/hash.h"
#include "utils/memutils.h"
#include "utils/resowner.h" #include "utils/resowner.h"
/*
* We track all of a backend's active scans on hash indexes using a list
* of HashScanListData structs, which are allocated in TopMemoryContext.
* It's okay to use a long-lived context because we rely on the ResourceOwner
* mechanism to clean up unused entries after transaction or subtransaction
* abort. We can't safely keep the entries in the executor's per-query
* context, because that might be already freed before we get a chance to
* clean up the list. (XXX seems like there should be a better way to
* manage this...)
*/
typedef struct HashScanListData typedef struct HashScanListData
{ {
IndexScanDesc hashsl_scan; IndexScanDesc hashsl_scan;
...@@ -44,6 +55,11 @@ ReleaseResources_hash(void) ...@@ -44,6 +55,11 @@ ReleaseResources_hash(void)
HashScanList next; HashScanList next;
/* /*
* Release all HashScanList items belonging to the current ResourceOwner.
* Note that we do not release the underlying IndexScanDesc; that's in
* executor memory and will go away on its own (in fact quite possibly
* has gone away already, so we mustn't try to touch it here).
*
* Note: this should be a no-op during normal query shutdown. However, in * Note: this should be a no-op during normal query shutdown. However, in
* an abort situation ExecutorEnd is not called and so there may be open * an abort situation ExecutorEnd is not called and so there may be open
* index scans to clean up. * index scans to clean up.
...@@ -69,14 +85,15 @@ ReleaseResources_hash(void) ...@@ -69,14 +85,15 @@ ReleaseResources_hash(void)
} }
/* /*
* _Hash_regscan() -- register a new scan. * _hash_regscan() -- register a new scan.
*/ */
void void
_hash_regscan(IndexScanDesc scan) _hash_regscan(IndexScanDesc scan)
{ {
HashScanList new_el; HashScanList new_el;
new_el = (HashScanList) palloc(sizeof(HashScanListData)); new_el = (HashScanList) MemoryContextAlloc(TopMemoryContext,
sizeof(HashScanListData));
new_el->hashsl_scan = scan; new_el->hashsl_scan = scan;
new_el->hashsl_owner = CurrentResourceOwner; new_el->hashsl_owner = CurrentResourceOwner;
new_el->hashsl_next = HashScans; new_el->hashsl_next = HashScans;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment