pgpool2.git / summary / log / commit / refs
commit dd5fe2d7d429dddf8a794e579605761f78f7d312
Author: Tatsuo Ishii <ishii at sraoss.co.jp>
Date: Tue Jul 20 14:08:39 2010 +0000
Do not start internal transaction if taget backend is only one.
If SAVEPOINT/ROLLBACK TO/RELEASE SAVEPOINT, send to primary only.
pool_proto_modules.c | 33 +++++++++++++++---------
pool_query_context.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++-----
pool_query_context.h | 1 +
3 files changed, 87 insertions(+), 18 deletions(-)
diff --git a/pool_proto_modules.c b/pool_proto_modules.c
index be2a7439c..ed9950564 100644
--- a/pool_proto_modules.c
+++ b/pool_proto_modules.c
@@ -374,19 +374,26 @@ static int is_temp_table(POOL_CONNECTION_POOL *backend, Node *node);
*/
if (!RAW_MODE)
{
- /* start a transaction if needed */
- if (start_internal_transaction(frontend, backend, (Node *)node) != POOL_CONTINUE)
- return POOL_END;
-
- /* check if need lock */
- if (need_insert_lock(backend, string, node))
+ /*
+ * If there's only one node to send the commad, there's no
+ * point to start a transaction.
+ */
+ if (pool_multi_node_to_be_sent(query_context))
{
- /* if so, issue lock command */
- status = insert_lock(frontend, backend, string, (InsertStmt *)node);
- if (status != POOL_CONTINUE)
+ /* start a transaction if needed */
+ if (start_internal_transaction(frontend, backend, (Node *)node) != POOL_CONTINUE)
+ return POOL_END;
+
+ /* check if need lock */
+ if (need_insert_lock(backend, string, node))
{
- free_parser();
- return status;
+ /* if so, issue lock command */
+ status = insert_lock(frontend, backend, string, (InsertStmt *)node);
+ if (status != POOL_CONTINUE)
+ {
+ free_parser();
+ return status;
+ }
}
}
}
@@ -470,7 +477,9 @@ static int is_temp_table(POOL_CONNECTION_POOL *backend, Node *node);
}
}
- /* Send query to other than master node */
+ /*
+ * Send the query to other than master node.
+ */
if (pool_send_and_wait(query_context, string, len, -1, MASTER_NODE_ID, "") != POOL_CONTINUE)
{
free_parser();
diff --git a/pool_query_context.c b/pool_query_context.c
index dc75be4d7..bdd4f59ba 100644
--- a/pool_query_context.c
+++ b/pool_query_context.c
@@ -174,6 +174,36 @@ void pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT *query_context)
return;
}
+/*
+ * Return true if multiple nodes are targets
+ */
+bool pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT *query_context)
+{
+ int i;
+ int cnt = 0;
+
+ if (!query_context)
+ {
+ pool_error("pool_multi_node_to_be_sent: no query context");
+ return false;
+ }
+
+ for (i=0;i<NUM_BACKENDS;i++)
+ {
+ if (((BACKEND_INFO(i)).backend_status == CON_UP ||
+ BACKEND_INFO((i)).backend_status == CON_CONNECT_WAIT) &&
+ query_context->where_to_send[i])
+ {
+ cnt++;
+ if (cnt > 1)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
/*
* Return if the DB node is needed to send query
*/
@@ -384,12 +414,14 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no
{
pool_setall_node_to_be_sent(query_context);
}
-
- wts = pool_get_prep_where(d->name);
- if (wts)
+ else
{
- /* Inherit same map from PREPARE */
- pool_copy_prep_where(wts, query_context->where_to_send);
+ wts = pool_get_prep_where(d->name);
+ if (wts)
+ {
+ /* Inherit same map from PREPARE */
+ pool_copy_prep_where(wts, query_context->where_to_send);
+ }
}
}
}
@@ -491,9 +523,11 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, char *query, i
POOL_SESSION_CONTEXT *session_context;
POOL_CONNECTION *frontend;
POOL_CONNECTION_POOL *backend;
-
+ bool is_commit;
int i;
+ is_commit = is_commit_query(query_context->parse_tree);
+
session_context = pool_get_session_context();
frontend = session_context->frontend;
backend = session_context->backend;
@@ -508,6 +542,16 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, char *query, i
else if (send_type > 0 && i != node_id)
continue;
+ /*
+ * If in master/slave mode, we do not send COMMIT/ABORT to
+ * slaves/standbys if it's in I(idle) state.
+ */
+ if (is_commit && MASTER_SLAVE && !IS_MASTER_NODE_ID(i) && TSTATE(backend, i) == 'I')
+ {
+ pool_unset_node_to_be_sent(query_context, i);
+ continue;
+ }
+
per_node_statement_log(backend, i, query);
if (*kind == '\0')
@@ -532,6 +576,15 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, char *query, i
else if (send_type > 0 && i != node_id)
continue;
+ /*
+ * If in master/slave mode, we do not send COMMIT/ABORT to
+ * slaves/standbys if it's in I(idle) state.
+ */
+ if (is_commit && MASTER_SLAVE && !IS_MASTER_NODE_ID(i) && TSTATE(backend, i) == 'I')
+ {
+ continue;
+ }
+
if (wait_for_query_response(frontend, CONNECTION(backend, i), query, MAJOR(backend)) != POOL_CONTINUE)
{
/* Cancel current transaction */
@@ -751,6 +804,12 @@ static POOL_DEST send_to_where(Node *node, char *query)
}
return POOL_BOTH;
}
+ else if (((TransactionStmt *)node)->kind == TRANS_STMT_SAVEPOINT ||
+ ((TransactionStmt *)node)->kind == TRANS_STMT_ROLLBACK_TO ||
+ ((TransactionStmt *)node)->kind == TRANS_STMT_RELEASE)
+ {
+ return POOL_PRIMARY;
+ }
/*
* 2PC commands
diff --git a/pool_query_context.h b/pool_query_context.h
index 5dc6bf574..8d69a40e5 100644
--- a/pool_query_context.h
+++ b/pool_query_context.h
@@ -64,6 +64,7 @@ extern void pool_set_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node
extern void pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id);
extern void pool_clear_node_to_be_sent(POOL_QUERY_CONTEXT *query_context);
extern void pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT *query_context);
+extern bool pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT *query_context);
extern void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *node);
POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, char *query, int len,
int send_type, int node_id, char *kind);
[parent: 8050b030a85b]