pgpool2.git / summary / log / commit / refs
commit 69ff3352deb465dc718cbe0042ed03074f62ab5d
Author: Tatsuo Ishii <ishii at sraoss.co.jp>
Date: Wed Jun 02 08:51:19 2010 +0000
Add session context module.
Makefile.am | 3 +-
Makefile.in | 7 ++-
child.c | 142 ++++++++++++++++++++++++++-----------------------
pool.h | 1 +
pool_connection_pool.c | 2 +
pool_process_context.c | 20 ++++++-
pool_process_context.h | 6 ++-
pool_session_context.c | 85 +++++++++++++++++++++++++++++
pool_session_context.h | 57 ++++++++++++++++++++
9 files changed, 251 insertions(+), 72 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 5fa9fe73b..620aa3b23 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,7 +14,8 @@ pgpool_SOURCES = pool.h pool_type.h version.h pgpool.conf.sample \
pool_ssl.c pool_timestamp.c pool_timestamp.h \
pool_proto_modules.c pool_proto_modules.h \
pool_lobj.c pool_lobj.h \
- pool_process_context.c pool_process_context.h
+ pool_process_context.c pool_process_context.h \
+ pool_session_context.c pool_session_context.h
pg_md5_SOURCES = pg_md5.c md5.c md5.h
diff --git a/Makefile.in b/Makefile.in
index 618fa5c6b..3677854fe 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -75,7 +75,8 @@ am_pgpool_OBJECTS = main.$(OBJEXT) child.$(OBJEXT) pool_auth.$(OBJEXT) \
strlcpy.$(OBJEXT) recovery.$(OBJEXT) pool_relcache.$(OBJEXT) \
pool_process_reporting.$(OBJEXT) pool_ssl.$(OBJEXT) \
pool_timestamp.$(OBJEXT) pool_proto_modules.$(OBJEXT) \
- pool_lobj.$(OBJEXT) pool_process_context.$(OBJEXT)
+ pool_lobj.$(OBJEXT) pool_process_context.$(OBJEXT) \
+ pool_session_context.$(OBJEXT)
pgpool_OBJECTS = $(am_pgpool_OBJECTS)
pgpool_DEPENDENCIES = parser/libsql-parser.a pcp/libpcp.la \
parser/nodes.o
@@ -247,7 +248,8 @@ pgpool_SOURCES = pool.h pool_type.h version.h pgpool.conf.sample \
pool_ssl.c pool_timestamp.c pool_timestamp.h \
pool_proto_modules.c pool_proto_modules.h \
pool_lobj.c pool_lobj.h \
- pool_process_context.c pool_process_context.h
+ pool_process_context.c pool_process_context.h \
+ pool_session_context.c pool_session_context.h
pg_md5_SOURCES = pg_md5.c md5.c md5.h
sysconf_DATA = pgpool.conf.sample pcp.conf.sample pool_hba.conf.sample \
@@ -418,6 +420,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_rewrite_outfuncs.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_rewrite_query.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_sema.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_session_context.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_shmem.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_signal.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_ssl.Po@am__quote@
diff --git a/child.c b/child.c
index 4dceaed46..23a3e3ab3 100644
--- a/child.c
+++ b/child.c
@@ -51,6 +51,7 @@
#include "pool.h"
#include "pool_process_context.h"
+#include "pool_session_context.h"
#include "pool_config.h"
#include "pool_ip.h"
#include "md5.h"
@@ -70,7 +71,9 @@ static int s_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password);
static void connection_count_up(void);
static void connection_count_down(void);
static void init_system_db_connection(void);
-
+static bool connect_using_existing_connection(POOL_CONNECTION *frontend,
+ POOL_CONNECTION_POOL *backend,
+ StartupPacket *sp);
/*
* non 0 means SIGTERM(smart shutdown) or SIGINT(fast shutdown) has arrived
*/
@@ -304,67 +307,12 @@ void do_child(int unix_fd, int inet_fd)
else
{
- int i, freed = 0;
- /*
- * save startup packet info
- */
- for (i = 0; i < NUM_BACKENDS; i++)
- {
- if (VALID_BACKEND(i))
- {
- if (!freed)
- {
- pool_free_startup_packet(backend->slots[i]->sp);
- freed = 1;
- }
- backend->slots[i]->sp = sp;
- }
- }
-
- /* reuse existing connection to backend */
-
- if (pool_do_reauth(frontend, backend))
- {
- pool_close(frontend);
- connection_count_down();
+ /* reuse existing connection */
+ if (!connect_using_existing_connection(frontend, backend, sp))
continue;
- }
-
- if (MAJOR(backend) == 3)
- {
- if (send_params(frontend, backend))
- {
- pool_close(frontend);
- connection_count_down();
- continue;
- }
- }
-
- /* send ReadyForQuery to frontend */
- pool_write(frontend, "Z", 1);
-
- if (MAJOR(backend) == 3)
- {
- int len;
- char tstate;
-
- len = htonl(5);
- pool_write(frontend, &len, sizeof(len));
- tstate = TSTATE(backend);
- pool_write(frontend, &tstate, 1);
- }
-
- if (pool_flush(frontend) < 0)
- {
- pool_close(frontend);
- connection_count_down();
- continue;
- }
-
}
connected = 1;
- LocalSessionId++;
/* show ps status */
sp = MASTER_CONNECTION(backend)->sp;
@@ -372,14 +320,10 @@ void do_child(int unix_fd, int inet_fd)
sp->user, sp->database, remote_ps_data);
set_ps_display(psbuf, false);
- if (MAJOR(backend) == PROTO_MAJOR_V2)
- TSTATE(backend) = 'I';
-
- if (pool_config->load_balance_mode)
- {
- /* select load balancing node */
- backend->info->load_balancing_node = select_load_balancing_node();
- }
+ /*
+ * Initialize per session context
+ */
+ pool_init_session_context(frontend, backend);
/* query process loop */
for (;;)
@@ -999,6 +943,72 @@ int send_startup_packet(POOL_CONNECTION_POOL_SLOT *cp)
return pool_write_and_flush(cp->con, cp->sp->startup_packet, cp->sp->len);
}
+/*
+ * Reuse existing connection
+ */
+static bool connect_using_existing_connection(POOL_CONNECTION *frontend,
+ POOL_CONNECTION_POOL *backend,
+ StartupPacket *sp)
+{
+ int i, freed = 0;
+ /*
+ * save startup packet info
+ */
+ for (i = 0; i < NUM_BACKENDS; i++)
+ {
+ if (VALID_BACKEND(i))
+ {
+ if (!freed)
+ {
+ pool_free_startup_packet(backend->slots[i]->sp);
+ freed = 1;
+ }
+ backend->slots[i]->sp = sp;
+ }
+ }
+
+ /* reuse existing connection to backend */
+
+ if (pool_do_reauth(frontend, backend))
+ {
+ pool_close(frontend);
+ connection_count_down();
+ return false;
+ }
+
+ if (MAJOR(backend) == 3)
+ {
+ if (send_params(frontend, backend))
+ {
+ pool_close(frontend);
+ connection_count_down();
+ return false;
+ }
+ }
+
+ /* send ReadyForQuery to frontend */
+ pool_write(frontend, "Z", 1);
+
+ if (MAJOR(backend) == 3)
+ {
+ int len;
+ char tstate;
+
+ len = htonl(5);
+ pool_write(frontend, &len, sizeof(len));
+ tstate = TSTATE(backend);
+ pool_write(frontend, &tstate, 1);
+ }
+
+ if (pool_flush(frontend) < 0)
+ {
+ pool_close(frontend);
+ connection_count_down();
+ return false;
+ }
+ return true;
+}
+
/*
* process cancel request
*/
diff --git a/pool.h b/pool.h
index 3586095d2..0684711c9 100644
--- a/pool.h
+++ b/pool.h
@@ -203,6 +203,7 @@ typedef struct {
} POOL_CONNECTION_POOL_SLOT;
typedef struct {
+ int pool_index; /* currentlt used index(0 start) of pool */
ConnectionInfo *info; /* connection info on shmem */
POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS];
} POOL_CONNECTION_POOL;
diff --git a/pool_connection_pool.c b/pool_connection_pool.c
index 4c6700653..b1667c119 100644
--- a/pool_connection_pool.c
+++ b/pool_connection_pool.c
@@ -163,6 +163,7 @@ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, in
}
}
POOL_SETMASK(&oldmask);
+ p->pool_index = i;
return p;
}
p++;
@@ -632,6 +633,7 @@ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p)
if (active_backend_count > 0)
{
p->info->create_time = time(NULL);
+ p->pool_index = i;
return p;
}
diff --git a/pool_process_context.c b/pool_process_context.c
index 6eaa56a79..af57d2edd 100644
--- a/pool_process_context.c
+++ b/pool_process_context.c
@@ -48,6 +48,8 @@ void pool_init_process_context(void)
child_exit(1);
}
process_context->backend_desc = pool_config->backend_desc;
+
+ process_context->local_session_id = 0; /* initialize local session counter */
}
/*
@@ -57,7 +59,7 @@ POOL_PROCESS_CONTEXT *pool_get_process_context(void)
{
if (!process_context)
{
- pool_error("pool_get_process_context: Process context is not initialized");
+ pool_error("pool_get_process_context: process context is not initialized");
}
return process_context;
}
@@ -69,10 +71,24 @@ ProcessInfo *pool_get_my_process_info(void)
{
if (!process_context)
{
- pool_error("pool_get_my_process_info: Process context is not initialized");
+ pool_error("pool_get_my_process_info: process context is not initialized");
return NULL;
}
return &process_context->process_info[process_context->proc_id];
}
+/*
+ * Increment local session id
+ */
+void pool_incremnet_local_session_id(void)
+{
+ POOL_PROCESS_CONTEXT *p = pool_get_process_context();
+
+ if (!p)
+ {
+ pool_error("pool_incremnet_local_session_id: cannot get process context");
+ return;
+ }
+ p->local_session_id++;
+}
diff --git a/pool_process_context.h b/pool_process_context.h
index 373d3ee87..af36c71d0 100644
--- a/pool_process_context.h
+++ b/pool_process_context.h
@@ -42,11 +42,15 @@ typedef struct {
* PostgreSQL server description. Placed on shared memory.
* Includes backend up/down info, hostname, data directory etc.
*/
- BackendDesc *backend_desc;
+ BackendDesc *backend_desc;
+
+ int local_session_id; /* local session id */
+
} POOL_PROCESS_CONTEXT;
extern void pool_init_process_context(void);
extern POOL_PROCESS_CONTEXT *pool_get_process_context(void);
extern ProcessInfo *pool_get_my_process_info(void);
+extern void pool_incremnet_local_session_id(void);
#endif /* POOL_PROCESS_CONTEXT_H */
diff --git a/pool_session_context.c b/pool_session_context.c
new file mode 100644
index 000000000..f9e0c20de
--- /dev/null
+++ b/pool_session_context.c
@@ -0,0 +1,85 @@
+/* -*-pgsql-c-*- */
+/*
+ *
+ * $Header$
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Copyright (c) 2003-2010 PgPool Global Development Group
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appear in all
+ * copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of the
+ * author not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The author makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ */
+
+#include "pool.h"
+#include "pool_config.h"
+#include "pool_session_context.h"
+
+static POOL_SESSION_CONTEXT session_context_d;
+static POOL_SESSION_CONTEXT *session_context;
+
+/*
+ * Initialize per session context
+ */
+void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
+{
+ session_context = &session_context_d;
+
+ /* Get Process context */
+ session_context->process_context = pool_get_process_context();
+ if (!session_context->process_context)
+ {
+ pool_error("pool_init_session_context: cannot get process context");
+ return;
+ }
+
+ /* Set connection info */
+ session_context->frontend = frontend;
+ session_context->backend = backend;
+
+ /* Initialize local session id */
+ pool_incremnet_local_session_id();
+
+ /* Initialize transaction state to idle */
+ session_context->transaction_state = 'I';
+
+ /* Choose load balancing node if neccessary */
+ if (pool_config->load_balance_mode)
+ {
+ ProcessInfo *process_info = pool_get_my_process_info();
+ if (!process_info)
+ {
+ pool_error("pool_init_session_context: pool_get_my_process_info failed");
+ return;
+ }
+
+ process_info[backend->pool_index].connection_info->load_balancing_node = select_load_balancing_node();
+
+ pool_debug("selected load balancing node: %d", backend->info->load_balancing_node);
+ }
+}
+
+/*
+ * Return session context
+ */
+POOL_SESSION_CONTEXT *pool_get_session_context(void)
+{
+ if (!session_context)
+ {
+ pool_error("pool_get_session_context: session context is not initialized");
+ return NULL;
+ }
+
+ return session_context;
+}
+
diff --git a/pool_session_context.h b/pool_session_context.h
new file mode 100644
index 000000000..4e335a0d7
--- /dev/null
+++ b/pool_session_context.h
@@ -0,0 +1,57 @@
+/* -*-pgsql-c-*- */
+/*
+ *
+ * $Header$
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Copyright (c) 2003-2010 PgPool Global Development Group
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appear in all
+ * copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of the
+ * author not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The author makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * pool_process_context.h.: process context information
+ *
+ */
+
+#ifndef POOL_SESSION_CONTEXT_H
+#define POOL_SESSION_CONTEXT_H
+
+#include "pool.h"
+#include "pool_process_context.h"
+#include "pool_session_context.h"
+
+/*
+ * Per session context:
+ */
+typedef struct {
+ POOL_PROCESS_CONTEXT *process_context; /* belonging process */
+ char transaction_state; /* either 'U'(unknown), 'I' (idle), 'T'(in transaction), 'E'(error) */
+ POOL_CONNECTION *frontend; /* connection to frontend */
+ POOL_CONNECTION_POOL *backend; /* connection to backends */
+
+ bool in_progress; /* true if we are busy and do not accept input from frontend */
+ int load_balance_node_id; /* selected load balance node id */
+ bool received_write_query; /* have we recived a write query in this transaction? */
+ bool send_ready_for_query; /* ok to send ReadyForQuery */
+ bool igore_till_sync; /* ignore any command until Sync message */
+ LOAD_BALANCE_STATUS load_balance_status[MAX_NUM_BACKENDS]; /* to remember which DB node is selected for load balancing */
+ /* unnamed statement */
+ /* unnamed portal */
+ /* named statement list */
+ /* named portal list */
+} POOL_SESSION_CONTEXT;
+
+extern void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend);
+extern POOL_SESSION_CONTEXT *pool_get_session_context(void);
+
+#endif /* POOL_SESSION_CONTEXT_H */
[parent: 0b2082bb1f5b]