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]