mirror of
https://github.com/postgres/postgres.git
synced 2025-09-03 15:22:11 +03:00
Revise large-object access routines to avoid running with CurrentMemoryContext
set to the large object context ("fscxt"), as this is inevitably a source of transaction-duration memory leaks. Not sure why we'd not noticed it before; maybe people weren't touching a whole lot of LOs in the same transaction before the 8.1 pg_dump changes. Per report from Wayne Conrad. Backpatched as far as 8.1, but the problem doubtless goes all the way back. I'm disinclined to spend the time to try to verify that the older branches would still work if patched, seeing that this code was significantly modified for 8.0 and again for 8.1, and that we don't have any trouble reports before 8.1. (Maybe the leaks were smaller before?)
This commit is contained in:
@@ -4,12 +4,20 @@
|
||||
* routines for manipulating inversion fs large objects. This file
|
||||
* contains the user-level large object application interface routines.
|
||||
*
|
||||
*
|
||||
* Note: many of these routines leak memory in CurrentMemoryContext, as indeed
|
||||
* does most of the backend code. We expect that CurrentMemoryContext will
|
||||
* be a short-lived context. Data that must persist across function calls
|
||||
* is kept either in CacheMemoryContext (the Relation structs) or in the
|
||||
* memory context given to inv_open (for LargeObjectDesc structs).
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.115 2006/03/05 15:58:38 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.116 2006/04/26 00:34:57 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -205,14 +213,17 @@ inv_create(Oid lobjId)
|
||||
* inv_open -- access an existing large object.
|
||||
*
|
||||
* Returns:
|
||||
* large object descriptor, appropriately filled in.
|
||||
* Large object descriptor, appropriately filled in. The descriptor
|
||||
* and subsidiary data are allocated in the specified memory context,
|
||||
* which must be suitably long-lived for the caller's purposes.
|
||||
*/
|
||||
LargeObjectDesc *
|
||||
inv_open(Oid lobjId, int flags)
|
||||
inv_open(Oid lobjId, int flags, MemoryContext mcxt)
|
||||
{
|
||||
LargeObjectDesc *retval;
|
||||
|
||||
retval = (LargeObjectDesc *) palloc(sizeof(LargeObjectDesc));
|
||||
retval = (LargeObjectDesc *) MemoryContextAlloc(mcxt,
|
||||
sizeof(LargeObjectDesc));
|
||||
|
||||
retval->id = lobjId;
|
||||
retval->subid = GetCurrentSubTransactionId();
|
||||
@@ -225,9 +236,12 @@ inv_open(Oid lobjId, int flags)
|
||||
}
|
||||
else if (flags & INV_READ)
|
||||
{
|
||||
/* be sure to copy snap into fscxt */
|
||||
/* be sure to copy snap into mcxt */
|
||||
MemoryContext oldContext = MemoryContextSwitchTo(mcxt);
|
||||
|
||||
retval->snapshot = CopySnapshot(ActiveSnapshot);
|
||||
retval->flags = IFS_RDLOCK;
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
}
|
||||
else
|
||||
elog(ERROR, "invalid flags: %d", flags);
|
||||
@@ -242,7 +256,8 @@ inv_open(Oid lobjId, int flags)
|
||||
}
|
||||
|
||||
/*
|
||||
* Closes an existing large object descriptor.
|
||||
* Closes a large object descriptor previously made by inv_open(), and
|
||||
* releases the long-term memory used by it.
|
||||
*/
|
||||
void
|
||||
inv_close(LargeObjectDesc *obj_desc)
|
||||
|
Reference in New Issue
Block a user