diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-03-07 15:59:23 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-03-07 15:59:23 +0000 |
commit | 8576a078430289f12fe91bfa595daf34325f62cc (patch) | |
tree | 1eea6ab620e9077f6679bc27f1966151193a160c | |
parent | 712d0eecf825f60258fcfc61f79b7dc4edb7d5fc (diff) | |
download | postgresql-8576a078430289f12fe91bfa595daf34325f62cc.tar.gz postgresql-8576a078430289f12fe91bfa595daf34325f62cc.zip |
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.
-rw-r--r-- | src/backend/access/hash/hashscan.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/backend/access/hash/hashscan.c b/src/backend/access/hash/hashscan.c index 213eaf89fcd..a895d4156f8 100644 --- a/src/backend/access/hash/hashscan.c +++ b/src/backend/access/hash/hashscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/hash/hashscan.c,v 1.39 2005/10/15 02:49:08 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/hash/hashscan.c,v 1.39.2.1 2008/03/07 15:59:23 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,9 +16,20 @@ #include "postgres.h" #include "access/hash.h" +#include "utils/memutils.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 { IndexScanDesc hashsl_scan; @@ -44,6 +55,11 @@ ReleaseResources_hash(void) 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 * an abort situation ExecutorEnd is not called and so there may be open * index scans to clean up. @@ -69,14 +85,15 @@ ReleaseResources_hash(void) } /* - * _Hash_regscan() -- register a new scan. + * _hash_regscan() -- register a new scan. */ void _hash_regscan(IndexScanDesc scan) { HashScanList new_el; - new_el = (HashScanList) palloc(sizeof(HashScanListData)); + new_el = (HashScanList) MemoryContextAlloc(TopMemoryContext, + sizeof(HashScanListData)); new_el->hashsl_scan = scan; new_el->hashsl_owner = CurrentResourceOwner; new_el->hashsl_next = HashScans; |