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]