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]