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]