pgpool2.git / summary / log / commit / refs
commit 2636236af59b90f7e61054518607ca506bb50135
Author: Muhammad Usama <m.usama@gmail.com>
Date: Thu Dec 04 12:12:25 2014 +0000
Fixing [pgpool-general: 3325] Master/Slave (stream) mode - Memory depletion
This memory leak is fixed by adding a new MemoryContext (ProcessQueryContext)
in pool_process_query function that gets reset at every query processing
loop iteration, Some required adjustments are made as part of this new
MemoryContext arrangement and now POOL_QUERY_CONTEXT has its own MemoryContext
which holds the QueryContext and its associated data.
src/context/pool_query_context.c | 13 +++++++++++--
src/context/pool_session_context.c | 2 +-
src/include/context/pool_query_context.h | 1 +
src/protocol/pool_process_query.c | 11 ++++++++++-
src/protocol/pool_proto_modules.c | 20 +++++++++++++-------
src/query_cache/pool_memqcache.c | 14 ++++++++++----
6 files changed, 46 insertions(+), 15 deletions(-)
diff --git a/src/context/pool_query_context.c b/src/context/pool_query_context.c
index 44c42dfc9..b02e04bfe 100644
--- a/src/context/pool_query_context.c
+++ b/src/context/pool_query_context.c
@@ -61,9 +61,16 @@ static char* remove_read_write(int len, const char *contents, int *rewritten_len
*/
POOL_QUERY_CONTEXT *pool_init_query_context(void)
{
+ MemoryContext memory_context = AllocSetContextCreate(QueryContext,
+ "QueryContextMemoryContext",
+ ALLOCSET_SMALL_MINSIZE,
+ ALLOCSET_SMALL_INITSIZE,
+ ALLOCSET_SMALL_MAXSIZE);
+
+ MemoryContext oldcontext = MemoryContextSwitchTo(memory_context);
POOL_QUERY_CONTEXT *qc;
- MemoryContext oldcontext = MemoryContextSwitchTo(QueryContext);
qc = palloc0(sizeof(*qc));
+ qc->memory_context = memory_context;
MemoryContextSwitchTo(oldcontext);
return qc;
}
@@ -77,11 +84,13 @@ void pool_query_context_destroy(POOL_QUERY_CONTEXT *query_context)
if (query_context)
{
+ MemoryContext memory_context = query_context->memory_context;
session_context = pool_get_session_context(false);
pool_unset_query_in_progress();
query_context->original_query = NULL;
session_context->query_context = NULL;
pfree(query_context);
+ MemoryContextDelete(memory_context);
}
}
@@ -96,7 +105,7 @@ void pool_start_query(POOL_QUERY_CONTEXT *query_context, char *query, int len, N
{
MemoryContext old_context;
session_context = pool_get_session_context(false);
- old_context = MemoryContextSwitchTo(QueryContext);
+ old_context = MemoryContextSwitchTo(query_context->memory_context);
query_context->original_length = len;
query_context->rewritten_length = -1;
query_context->original_query = pstrdup(query);
diff --git a/src/context/pool_session_context.c b/src/context/pool_session_context.c
index e98108546..7b10da51f 100644
--- a/src/context/pool_session_context.c
+++ b/src/context/pool_session_context.c
@@ -134,7 +134,6 @@ void pool_session_context_destroy(void)
{
pool_clear_sent_message_list();
pfree(session_context->message_list.sent_messages);
- MemoryContextDelete(session_context->memory_context);
if (pool_config->memory_cache_enabled)
{
pool_discard_query_cache_array(session_context->query_cache_array);
@@ -143,6 +142,7 @@ void pool_session_context_destroy(void)
if (session_context->query_context)
pool_query_context_destroy(session_context->query_context);
+ MemoryContextDelete(session_context->memory_context);
}
/* XXX For now, just zap memory */
memset(&session_context_d, 0, sizeof(session_context_d));
diff --git a/src/include/context/pool_query_context.h b/src/include/context/pool_query_context.h
index 4c20510d1..56220c764 100644
--- a/src/include/context/pool_query_context.h
+++ b/src/include/context/pool_query_context.h
@@ -68,6 +68,7 @@ typedef struct {
* query and parsed node is actually a dummy query.
*/
int num_original_params; /* number of parameters in original query */
+ MemoryContext memory_context; /* memory context for query context */
} POOL_QUERY_CONTEXT;
extern POOL_QUERY_CONTEXT *pool_init_query_context(void);
diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c
index f98469a41..82f9ccae4 100644
--- a/src/protocol/pool_process_query.c
+++ b/src/protocol/pool_process_query.c
@@ -100,6 +100,12 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend,
POOL_STATUS status;
int qcnt;
int i;
+ MemoryContext ProcessQueryContext = AllocSetContextCreate(QueryContext,
+ "pool_process_query",
+ ALLOCSET_DEFAULT_MINSIZE,
+ ALLOCSET_DEFAULT_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
+
/*
* This variable is used while processing reset_request (i.e.:
* reset_request == 1). If state is 0, then we call
@@ -121,6 +127,10 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend,
for (;;)
{
+
+ MemoryContextSwitchTo(ProcessQueryContext);
+ MemoryContextResetAndDeleteChildren(ProcessQueryContext);
+
/* Are we requested to send reset queries? */
if (state == 0 && reset_request)
{
@@ -428,7 +438,6 @@ POOL_STATUS pool_parallel_exec(POOL_CONNECTION *frontend,
static char *sq_processes = "show pool_processes";
static char *sq_nodes = "show pool_nodes";
static char *sq_version = "show pool_version";
- POOL_STATUS status;
struct timeval timeout;
int num_fds;
int used_count = 0;
diff --git a/src/protocol/pool_proto_modules.c b/src/protocol/pool_proto_modules.c
index 438618593..7eef8db52 100644
--- a/src/protocol/pool_proto_modules.c
+++ b/src/protocol/pool_proto_modules.c
@@ -58,6 +58,8 @@
#include "utils/pool_stream.h"
#include "query_cache/pool_memqcache.h"
#include "utils/pool_signal.h"
+#include "utils/palloc.h"
+#include "utils/memutils.h"
char *copy_table = NULL; /* copy table name */
char *copy_schema = NULL; /* copy table name */
@@ -168,6 +170,7 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
/* Create query context */
query_context = pool_init_query_context();
+ MemoryContext old_context = MemoryContextSwitchTo(query_context->memory_context);
/* parse SQL string */
parse_tree_list = raw_parser(contents);
@@ -210,6 +213,7 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
query_context->is_parse_error = true;
}
}
+ MemoryContextSwitchTo(old_context);
if (parse_tree_list != NIL)
{
@@ -642,14 +646,11 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
POOL_STATUS status;
char *search_query = NULL;
int len;
- char *tmp;
#define STR_ALLOC_SIZE 1024
len = strlen(query)+1;
- search_query = (char *)palloc(len);
- strcpy(search_query, query);
-
+ search_query = MemoryContextStrdup(query_context->memory_context,query);
/*
* Add bind message's info to query to search.
*/
@@ -697,10 +698,8 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
*/
if (query_context->temp_cache)
{
- tmp = (char *)palloc(sizeof(char) * strlen(search_query) + 1);
pfree(query_context->temp_cache->query);
- query_context->temp_cache->query = tmp;
- strcpy(query_context->temp_cache->query, search_query);
+ query_context->temp_cache->query = MemoryContextStrdup(session_context->memory_context,search_query);
}
}
@@ -809,6 +808,7 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
stmt = contents + strlen(contents) + 1;
/* parse SQL string */
+ MemoryContext old_context = MemoryContextSwitchTo(query_context->memory_context);
parse_tree_list = raw_parser(stmt);
if (parse_tree_list == NIL)
@@ -849,6 +849,7 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
query_context->is_parse_error = true;
}
}
+ MemoryContextSwitchTo(old_context);
if (parse_tree_list != NIL)
{
@@ -2433,9 +2434,14 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
*/
query_context = pool_init_query_context();
query = "INSERT INTO foo VALUES(1)";
+ MemoryContext old_context = MemoryContextSwitchTo(query_context->memory_context);
+
parse_tree_list = raw_parser(query);
node = (Node *) lfirst(list_head(parse_tree_list));
pool_start_query(query_context, query, strlen(query) + 1, node);
+
+ MemoryContextSwitchTo(old_context);
+
pool_where_to_send(query_context, query_context->original_query,
query_context->parse_tree);
diff --git a/src/query_cache/pool_memqcache.c b/src/query_cache/pool_memqcache.c
index f0f3f4caf..9e6849c19 100644
--- a/src/query_cache/pool_memqcache.c
+++ b/src/query_cache/pool_memqcache.c
@@ -2708,16 +2708,18 @@ POOL_QUERY_CACHE_ARRAY *pool_create_query_cache_array(void)
{
#define POOL_QUERY_CACHE_ARRAY_ALLOCATE_NUM 128
#define POOL_QUERY_CACHE_ARRAY_HEADER_SIZE (sizeof(int)+sizeof(int))
- MemoryContext oldContext = MemoryContextSwitchTo(ProcessLoopContext);
+
size_t size;
POOL_QUERY_CACHE_ARRAY *p;
+ POOL_SESSION_CONTEXT *session_context =pool_get_session_context(false);
+ MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context);
size = POOL_QUERY_CACHE_ARRAY_HEADER_SIZE + POOL_QUERY_CACHE_ARRAY_ALLOCATE_NUM *
sizeof(POOL_TEMP_QUERY_CACHE *);
p = palloc(size);
p->num_caches = 0;
p->array_size = POOL_QUERY_CACHE_ARRAY_ALLOCATE_NUM;
- MemoryContextSwitchTo(oldContext);
+ MemoryContextSwitchTo(old_context);
return p;
}
@@ -2779,8 +2781,9 @@ static POOL_QUERY_CACHE_ARRAY * pool_add_query_cache_array(POOL_QUERY_CACHE_ARRA
*/
POOL_TEMP_QUERY_CACHE *pool_create_temp_query_cache(char *query)
{
+ POOL_SESSION_CONTEXT *session_context =pool_get_session_context(false);
+ MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context);
POOL_TEMP_QUERY_CACHE *p;
- MemoryContext oldContext = MemoryContextSwitchTo(QueryContext);
p = palloc(sizeof(*p));
p->query = pstrdup(query);
@@ -2790,7 +2793,7 @@ POOL_TEMP_QUERY_CACHE *pool_create_temp_query_cache(char *query)
p->is_exceeded = false;
p->is_discarded = false;
- MemoryContextSwitchTo(oldContext);
+ MemoryContextSwitchTo(old_context);
return p;
}
@@ -2932,6 +2935,8 @@ static void pool_add_buffer(POOL_INTERNAL_BUFFER *buffer, void *data, size_t len
/* Sanity check */
if (!buffer || !data || len == 0)
return;
+ POOL_SESSION_CONTEXT *session_context =pool_get_session_context(false);
+ MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context);
/* Check if we need to increase the buffer size */
if ((buffer->buflen + len) > buffer->bufsize)
@@ -2951,6 +2956,7 @@ static void pool_add_buffer(POOL_INTERNAL_BUFFER *buffer, void *data, size_t len
(errmsg("memcache adding data to internal buffer"),
errdetail("len:%zd, total:%zd bufsize:%zd",
len, buffer->buflen, buffer->bufsize)));
+ MemoryContextSwitchTo(old_context);
return;
}
[parent: 4025e5635101]