mirror of
https://github.com/postgres/postgres.git
synced 2025-09-03 15:22:11 +03:00
Prevent memory leaks associated with relcache rd_partcheck structures.
The original coding of generate_partition_qual() just copied the list of predicate expressions into the global CacheMemoryContext, making it effectively impossible to clean up when the owning relcache entry is destroyed --- the relevant code in RelationDestroyRelation() only managed to free the topmost List header :-(. This resulted in a session-lifespan memory leak whenever a table partition's relcache entry is rebuilt. Fortunately, that's not normally a large data structure, and rebuilds shouldn't occur all that often in production situations; but this is still a bug worth fixing back to v10 where the code was introduced. To fix, put the cached expression tree into its own small memory context, as we do with other complicated substructures of relcache entries. Also, deal more honestly with the case that a partition has an empty partcheck list; while that probably isn't a case that's very interesting for production use, it's legal. In passing, clarify comments about how partitioning-related relcache data structures are managed, and add some Asserts that we're not leaking old copies when we overwrite these data fields. Amit Langote and Tom Lane Discussion: https://postgr.es/m/7961.1552498252@sss.pgh.pa.us
This commit is contained in:
@@ -95,9 +95,9 @@ typedef struct RelationData
|
||||
List *rd_fkeylist; /* list of ForeignKeyCacheInfo (see below) */
|
||||
bool rd_fkeyvalid; /* true if list has been computed */
|
||||
|
||||
MemoryContext rd_partkeycxt; /* private memory cxt for the below */
|
||||
MemoryContext rd_partkeycxt; /* private context for rd_partkey, if any */
|
||||
struct PartitionKeyData *rd_partkey; /* partition key, or NULL */
|
||||
MemoryContext rd_pdcxt; /* private context for partdesc */
|
||||
MemoryContext rd_pdcxt; /* private context for rd_partdesc, if any */
|
||||
struct PartitionDescData *rd_partdesc; /* partitions, or NULL */
|
||||
List *rd_partcheck; /* partition CHECK quals */
|
||||
|
||||
@@ -188,6 +188,10 @@ typedef struct RelationData
|
||||
|
||||
/* use "struct" here to avoid needing to include pgstat.h: */
|
||||
struct PgStat_TableStatus *pgstat_info; /* statistics collection area */
|
||||
|
||||
/* placed here to avoid ABI break before v12: */
|
||||
bool rd_partcheckvalid; /* true if list has been computed */
|
||||
MemoryContext rd_partcheckcxt; /* private cxt for rd_partcheck, if any */
|
||||
} RelationData;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user