pgpool2.git / summary / log / commit / refs

commit    eb724d9b54fd26fda87486e3cd47e2e3b3554d92
Author:   Tatsuo Ishii <ishii@postgresql.org>
Date:     Wed Jan 18 09:58:34 2012 +0000

    Fix failure when internal query cache buffer is overflowed.
    In this case we should not half baked commit cache.


pool_memqcache.c | 46 +++++++++++++++++++++++++++----------------- pool_process_query.c | 4 ++-- pool_proto_modules.c | 2 +- pool_query_context.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++- pool_query_context.h | 5 ++++- 5 files changed, 89 insertions(+), 22 deletions(-) diff --git a/pool_memqcache.c b/pool_memqcache.c index 58a0a6f66..df206a0e4 100644 --- a/pool_memqcache.c +++ b/pool_memqcache.c @@ -3,7 +3,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2011 PgPool Global Development Group + * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -139,9 +139,9 @@ int memcached_connect (void) #ifdef USE_MEMCACHED memc = memcached_create(NULL); servers = memcached_server_list_append(NULL, - memqcache_memcached_host, - memqcache_memcached_port, - &rc); + memqcache_memcached_host, + memqcache_memcached_port, + &rc); rc = memcached_server_push(memc, servers); if (rc != MEMCACHED_SUCCESS) @@ -1159,7 +1159,7 @@ static void pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool if (pool_is_shmem_cache()) { pool_debug("pool_invalidate_query_cache: deleting cacheid:%d itemid:%d", - buf.cacheid.blockid, buf.cacheid.itemid); + buf.cacheid.blockid, buf.cacheid.itemid); pool_delete_item_shmem_cache(&buf.cacheid); } #ifdef USE_MEMCACHED @@ -2240,6 +2240,8 @@ static void pool_add_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache, char ki send_len = htonl(data_len + sizeof(int)); pool_add_buffer(buffer, (char *)&send_len, sizeof(int)); pool_add_buffer(buffer, data, data_len); + + return; } /* @@ -2473,22 +2475,28 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n if (state == 'I') /* Not inside a transaction? */ { /* - * If we are not inside a transaction, we can - * immediately register to cache storage. + * Make sure that temporary cache is not exceeded. */ - /* Register to memcached or shmem */ - pool_shmem_lock(); - - cache_buffer = pool_get_current_cache_buffer(&len); - if (cache_buffer) + if (!pool_is_cache_exceeded()) { - if (pool_commit_cache(backend, query, cache_buffer, len, num_oids, oids) != 0) + /* + * If we are not inside a transaction, we can + * immediately register to cache storage. + */ + /* Register to memcached or shmem */ + pool_shmem_lock(); + + cache_buffer = pool_get_current_cache_buffer(&len); + if (cache_buffer) { - pool_error("ReadyForQuery: pool_commit_cache failed"); + if (pool_commit_cache(backend, query, cache_buffer, len, num_oids, oids) != 0) + { + pool_error("ReadyForQuery: pool_commit_cache failed"); + } + free(cache_buffer); } - free(cache_buffer); + pool_shmem_unlock(); } - pool_shmem_unlock(); /* Count up SELECT stats */ pool_stats_count_up_num_selects(1); @@ -2502,7 +2510,11 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n /* In transaction. Keep to temp query cache array */ pool_add_oids_temp_query_cache(cache, num_oids, oids); - pool_add_query_cache_array(session_context->query_cache_array, cache); + + if (!pool_is_cache_exceeded()) + { + pool_add_query_cache_array(session_context->query_cache_array, cache); + } /* Count up temporary SELECT stats */ pool_tmp_stats_count_up_num_selects(); diff --git a/pool_process_query.c b/pool_process_query.c index aeb5d9abb..dd23c0bc0 100644 --- a/pool_process_query.c +++ b/pool_process_query.c @@ -5,7 +5,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2011 PgPool Global Development Group + * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -1094,7 +1094,7 @@ POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, /* save the received result to buffer for each kind */ if (pool_config->memory_cache_enabled) { - if (pool_is_cache_safe()) + if (pool_is_cache_safe() && !pool_is_cache_exceeded()) { memqcache_register(kind, frontend, p1, len1); } diff --git a/pool_proto_modules.c b/pool_proto_modules.c index f641a6c9e..23f353255 100644 --- a/pool_proto_modules.c +++ b/pool_proto_modules.c @@ -1895,7 +1895,7 @@ POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac /* Save the received result to buffer for each kind */ if (pool_config->memory_cache_enabled) { - if (pool_is_cache_safe()) + if (pool_is_cache_safe() && !pool_is_cache_exceeded()) { memqcache_register('C', frontend, p1, len1); } diff --git a/pool_query_context.c b/pool_query_context.c index 98bf873a3..9f5cac7b6 100644 --- a/pool_query_context.c +++ b/pool_query_context.c @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2011 PgPool Global Development Group + * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -1525,3 +1525,55 @@ void pool_unset_cache_safe(void) sc->query_context->is_cache_safe = false; } } + +/* + * Return true if current temporary query cache is exceeded + */ +bool pool_is_cache_exceeded(void) +{ + POOL_SESSION_CONTEXT *sc; + + sc = pool_get_session_context(); + if (!sc) + return false; + + if (pool_is_query_in_progress() && sc->query_context) + { + return sc->query_context->temp_cache->is_exceeded; + } + return false; +} + +/* + * Set current temporary query cache is exceeded + */ +void pool_set_cache_exceeded(void) +{ + POOL_SESSION_CONTEXT *sc; + + sc = pool_get_session_context(); + if (!sc) + return; + + if (sc->query_context) + { + sc->query_context->temp_cache->is_exceeded = true; + } +} + +/* + * Unset current temporary query cache is exceeded + */ +void pool_unset_cache_exceeded(void) +{ + POOL_SESSION_CONTEXT *sc; + + sc = pool_get_session_context(); + if (!sc) + return; + + if (sc->query_context) + { + sc->query_context->temp_cache->is_exceeded = false; + } +} diff --git a/pool_query_context.h b/pool_query_context.h index 6457884c6..5fb0940e4 100644 --- a/pool_query_context.h +++ b/pool_query_context.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2011 PgPool Global Development Group + * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -85,5 +85,8 @@ extern int statecmp(POOL_QUERY_STATE s1, POOL_QUERY_STATE s2); extern bool pool_is_cache_safe(void); extern void pool_set_cache_safe(void); extern void pool_unset_cache_safe(void); +extern bool pool_is_cache_exceeded(void); +extern void pool_set_cache_exceeded(void); +extern void pool_unset_cache_exceeded(void); #endif /* POOL_QUERY_CONTEXT_H */ [parent: 9756d5670703]