mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-23 19:39:53 +08:00
Fix memory leak coming from simple lists built in reindexdb
When building a list of relations for a parallel processing of a schema
or a database (or just a single-entry list for the non-parallel case
with the database name), the list is allocated and built on-the-fly for
each database processed, leaking after one database-level reindex is
done. This accumulates leaks when processing all databases, and could
become a visible issue with thousands of relations.
This is fixed by introducing a new routine in simple_list.c to free all
the elements in a simple list made of strings or OIDs. The header of
the list may be using a variable declaration or an allocated pointer,
so we don't have a routine to free this part to keep the interface
simple.
Per report from coverity for an issue introduced by 5ab892c
, and
valgrind complains about the leak as well. The idea to introduce a new
routine in simple_list.c is from Tom Lane.
Author: Michael Paquier
Reviewed-by: Tom Lane
This commit is contained in:
parent
3420851a2c
commit
04cf0bfc90
@ -473,6 +473,12 @@ reindex_one_database(const char *dbname, ReindexType type,
|
||||
failed = true;
|
||||
|
||||
finish:
|
||||
if (process_list != user_list)
|
||||
{
|
||||
simple_string_list_destroy(process_list);
|
||||
pg_free(process_list);
|
||||
}
|
||||
|
||||
ParallelSlotsTerminate(slots, concurrentCons);
|
||||
pfree(slots);
|
||||
|
||||
|
@ -99,6 +99,44 @@ simple_string_list_member(SimpleStringList *list, const char *val)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy an OID list
|
||||
*/
|
||||
void
|
||||
simple_oid_list_destroy(SimpleOidList *list)
|
||||
{
|
||||
SimpleOidListCell *cell;
|
||||
|
||||
cell = list->head;
|
||||
while (cell != NULL)
|
||||
{
|
||||
SimpleOidListCell *next;
|
||||
|
||||
next = cell->next;
|
||||
pg_free(cell);
|
||||
cell = next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a string list
|
||||
*/
|
||||
void
|
||||
simple_string_list_destroy(SimpleStringList *list)
|
||||
{
|
||||
SimpleStringListCell *cell;
|
||||
|
||||
cell = list->head;
|
||||
while (cell != NULL)
|
||||
{
|
||||
SimpleStringListCell *next;
|
||||
|
||||
next = cell->next;
|
||||
pg_free(cell);
|
||||
cell = next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find first not-touched list entry, if there is one.
|
||||
*/
|
||||
|
@ -46,9 +46,11 @@ typedef struct SimpleStringList
|
||||
|
||||
extern void simple_oid_list_append(SimpleOidList *list, Oid val);
|
||||
extern bool simple_oid_list_member(SimpleOidList *list, Oid val);
|
||||
extern void simple_oid_list_destroy(SimpleOidList *list);
|
||||
|
||||
extern void simple_string_list_append(SimpleStringList *list, const char *val);
|
||||
extern bool simple_string_list_member(SimpleStringList *list, const char *val);
|
||||
extern void simple_string_list_destroy(SimpleStringList *list);
|
||||
|
||||
extern const char *simple_string_list_not_touched(SimpleStringList *list);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user