pgpool2.git / summary / log / commit / refs
commit 535ded49ffd58ffaefde28d8a8e46e6012532c46
Author: Tatsuo Ishii <ishii at sraoss.co.jp>
Date: Tue Dec 30 00:59:35 2008 +0000
Fix bug with query cancel. It seems this has not been working since
pgpool-II was born.
To fix this, now we have each connection's pid and cancel key in the
shared memory area. If a cancel packet is sent, the table is searched
by the pid and the cancel key. If found, the actual cancel key is
sent to each backend.
child.c | 42 +++++++++++++++++++++++++++++++++++-------
main.c | 10 ++++++++--
pool.h | 5 +++--
pool_auth.c | 6 ++++--
pool_type.h | 4 +++-
5 files changed, 53 insertions(+), 14 deletions(-)
diff --git a/child.c b/child.c
index 425afe583..ee9eda42f 100644
--- a/child.c
+++ b/child.c
@@ -62,7 +62,7 @@ void child_exit(int code);
static POOL_CONNECTION *do_accept(int unix_fd, int inet_fd, struct timeval *timeout);
static StartupPacket *read_startup_packet(POOL_CONNECTION *cp);
static POOL_CONNECTION_POOL *connect_backend(StartupPacket *sp, POOL_CONNECTION *frontend);
-static void cancel_request(CancelPacket *sp, int secondary_backend);
+static void cancel_request(CancelPacket *sp);
static RETSIGTYPE die(int sig);
static RETSIGTYPE close_idle_connection(int sig);
static RETSIGTYPE wakeup_handler(int sig);
@@ -226,9 +226,8 @@ void do_child(int unix_fd, int inet_fd)
/* cancel request? */
if (sp->major == 1234 && sp->minor == 5678)
{
- cancel_request((CancelPacket *)sp->startup_packet, 0);
- if (DUAL_MODE)
- cancel_request((CancelPacket *)sp->startup_packet, 1);
+ cancel_request((CancelPacket *)sp->startup_packet);
+
pool_close(frontend);
pool_free_startup_packet(sp);
connection_count_down();
@@ -1078,16 +1077,33 @@ int send_startup_packet(POOL_CONNECTION_POOL_SLOT *cp)
/*
* process cancel request
*/
-static void cancel_request(CancelPacket *sp, int backend_id)
+static void cancel_request(CancelPacket *sp)
{
int len;
int fd;
POOL_CONNECTION *con;
int i;
+ ConnectionInfo *c = NULL;
+ CancelPacket cp;
pool_debug("Cancel request received");
- for (i=0;i<NUM_BACKENDS;i++)
+ /* look for cancel key from shmem info */
+ for (i=0;i<pool_config->num_init_children*pool_config->max_pool;i++)
+ {
+ c = &con_info[i];
+
+ if (c->pid == sp->pid && c->key == sp->key)
+ {
+ pool_debug("found pid:%d key:%d i:%d",c->pid, c->key,i);
+ c = &con_info[i/pool_config->max_pool * pool_config->max_pool];
+ break;
+ }
+ }
+ if (i == pool_config->num_init_children*pool_config->max_pool)
+ return; /* invalid key */
+
+ for (i=0;i<NUM_BACKENDS;i++,c++)
{
if (!VALID_BACKEND(i))
continue;
@@ -1110,10 +1126,22 @@ static void cancel_request(CancelPacket *sp, int backend_id)
len = htonl(sizeof(len) + sizeof(CancelPacket));
pool_write(con, &len, sizeof(len));
- if (pool_write_and_flush(con, sp, sizeof(CancelPacket)) < 0)
+ cp.protoVersion = sp->protoVersion;
+ cp.pid = c->pid;
+ cp.key = c->key;
+
+ pool_debug("pid:%d key: %d",cp.pid,cp.key);
+
+ if (pool_write_and_flush(con, &cp, sizeof(CancelPacket)) < 0)
pool_error("Could not send cancel request packet for backend %d", i);
pool_close(con);
+
+ /*
+ * this is needed to enure that the next DB node executes the
+ * query supposed to be canceled.
+ */
+ sleep(1);
}
}
diff --git a/main.c b/main.c
index 4ef3e264b..72a195571 100644
--- a/main.c
+++ b/main.c
@@ -114,7 +114,14 @@ static int trigger_failover_command(int node, const char *command_line);
static struct sockaddr_un un_addr; /* unix domain socket path */
static struct sockaddr_un pcp_un_addr; /* unix domain socket path for PCP */
-ProcessInfo *pids; /* child pid table */
+ProcessInfo *pids; /* shmem child pid table */
+
+/*
+ * shmem connection info table
+ * this is a two dimention array. i.e.:
+ * con_info[pool_config->num_init_children][pool_config->max_pool]
+ */
+ConnectionInfo *con_info;
static int unix_fd; /* unix domain socket fd */
static int inet_fd; /* inet domain socket fd */
@@ -168,7 +175,6 @@ int main(int argc, char **argv)
int i;
int pid;
int size;
- ConnectionInfo *con_info = NULL;
int retrycnt;
int sys_retrycnt;
diff --git a/pool.h b/pool.h
index a88b4139c..42705e04b 100644
--- a/pool.h
+++ b/pool.h
@@ -269,7 +269,7 @@ typedef struct {
} POOL_CONNECTION_POOL_SLOT;
typedef struct {
- ConnectionInfo *info;
+ ConnectionInfo *info; /* connection info on shmem */
POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS];
} POOL_CONNECTION_POOL;
@@ -411,7 +411,8 @@ extern volatile sig_atomic_t backend_timer_expired; /* flag for connection close
extern long int weight_master; /* normalized weight of master (0-RAND_MAX range) */
extern int my_proc_id; /* process table id (!= UNIX's PID) */
extern POOL_SYSTEMDB_CONNECTION_POOL *system_db_info; /* systemdb */
-extern ProcessInfo *pids; /* process information table */
+extern ProcessInfo *pids; /* shmem process information table */
+extern ConnectionInfo *con_info; /* shmem connection info table */
extern int in_load_balance; /* non 0 if in load balance mode */
extern int selected_slot; /* selected DB node for load balance */
extern int master_slave_dml; /* non 0 if master/slave mode is specified in config file */
diff --git a/pool_auth.c b/pool_auth.c
index 8224ce573..e4f2f6add 100644
--- a/pool_auth.c
+++ b/pool_auth.c
@@ -327,7 +327,8 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
pool_error("pool_do_auth: failed to read pid in slot %d", i);
return -1;
}
- CONNECTION_SLOT(cp, i)->pid = pid;
+
+ CONNECTION_SLOT(cp, i)->pid = cp->info[i].pid = pid;
/* read key */
if (pool_read(CONNECTION(cp, i), &key, sizeof(key)) < 0)
@@ -335,7 +336,8 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
pool_error("pool_do_auth: failed to read key in slot %d", i);
return -1;
}
- CONNECTION_SLOT(cp, i)->key = key;
+ CONNECTION_SLOT(cp, i)->key = cp->info[i].key = key;
+
}
}
diff --git a/pool_type.h b/pool_type.h
index 654d58e04..f281376b5 100644
--- a/pool_type.h
+++ b/pool_type.h
@@ -108,6 +108,8 @@ typedef struct {
char user[SM_USER]; /* User name */
int major; /* protocol major version */
int minor; /* protocol minor version */
+ int pid; /* backend process id */
+ int key; /* cancel key */
int counter; /* used counter */
time_t create_time; /* connection creation time */
int load_balancing_node; /* load balancing node */
@@ -121,7 +123,7 @@ typedef struct {
typedef struct {
pid_t pid; /* OS's process id */
time_t start_time; /* fork() time */
- ConnectionInfo *connection_info; /* connection information */
+ ConnectionInfo *connection_info; /* head of the connection info for this process */
} ProcessInfo;
/*
[parent: 2f03396e91d2]