pgpool2.git / summary / log / commit / refs

commit    fb07de60e5e32a3225c666d4d9075bfb77a24229
Author:   Yoshiyuki Asaba <y-asaba at pgfoundry.org>
Date:     Tue Jul 24 09:02:42 2007 +0000

    Detect deadlock in do_command().
    When insert_lock was true, kind mismatch error occured.


pool.h | 9 +++++---- pool_process_query.c | 29 ++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/pool.h b/pool.h index c4fdefbdb..1a7614b6a 100644 --- a/pool.h +++ b/pool.h @@ -64,11 +64,12 @@ #define NO_STRICT_MODE(s) (strncasecmp((s), NO_STRICT_MODE_STR, strlen(NO_STRICT_MODE_STR)) == 0) typedef enum { - POOL_CONTINUE = 0, + POOL_CONTINUE = 0, POOL_IDLE, - POOL_END, - POOL_ERROR, - POOL_FATAL + POOL_END, + POOL_ERROR, + POOL_FATAL, + POOL_DEADLOCK } POOL_STATUS; diff --git a/pool_process_query.c b/pool_process_query.c index 561ad06cc..0c673e457 100644 --- a/pool_process_query.c +++ b/pool_process_query.c @@ -4031,6 +4031,7 @@ static POOL_STATUS do_command(POOL_CONNECTION *backend, char *query, int protoMa int status; char kind; char *string; + int deadlock_detected = 0; pool_debug("do_command: Query: %s", query); @@ -4038,6 +4039,16 @@ static POOL_STATUS do_command(POOL_CONNECTION *backend, char *query, int protoMa if (send_simplequery_message(backend, strlen(query)+1, query, protoMajor) != POOL_CONTINUE) return POOL_END; + /* + * We must check deadlock error because a aborted transaction + * by detecting deadlock isn't same on all nodes. + * If a transaction is aborted on master node, pgpool send a + * error query to another nodes. + */ + deadlock_detected = detect_deadlock_error(backend, protoMajor); + if (deadlock_detected < 0) + return POOL_END; + /* * Expecting CompleteCommand */ @@ -4109,7 +4120,7 @@ static POOL_STATUS do_command(POOL_CONNECTION *backend, char *query, int protoMa backend->tstate = kind; } - return POOL_CONTINUE; + return deadlock_detected ? POOL_DEADLOCK : POOL_CONTINUE; } /* @@ -4252,7 +4263,7 @@ static POOL_STATUS insert_lock(POOL_CONNECTION_POOL *backend, char *query, Inser char *table; char qbuf[1024]; POOL_STATUS status; - int i; + int i, deadlock_detected = 0; /* insert_lock can be used in V3 only */ if (MAJOR(backend) != PROTO_MAJOR_V3) @@ -4278,17 +4289,25 @@ static POOL_STATUS insert_lock(POOL_CONNECTION_POOL *backend, char *query, Inser table = get_insert_command_table_name(node); snprintf(qbuf, sizeof(qbuf), "LOCK TABLE %s IN SHARE ROW EXCLUSIVE MODE", table); - if (do_command(MASTER(backend), qbuf, MAJOR(backend), 0) != POOL_CONTINUE) + status = do_command(MASTER(backend), qbuf, MAJOR(backend), 0); + if (status == POOL_END) { internal_transaction_started = 0; return POOL_END; } + else if (status == POOL_DEADLOCK) + deadlock_detected = 1; for (i=0;i<NUM_BACKENDS;i++) { if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i)) { - if (do_command(CONNECTION(backend, i), qbuf, MAJOR(backend), 0) != POOL_CONTINUE) + if (deadlock_detected) + status = do_command(CONNECTION(backend, i), POOL_ERROR_QUERY, PROTO_MAJOR_V3, 0); + else + status = do_command(CONNECTION(backend, i), qbuf, PROTO_MAJOR_V3, 0); + + if (status != POOL_CONTINUE) { internal_transaction_started = 0; return POOL_END; @@ -4296,7 +4315,7 @@ static POOL_STATUS insert_lock(POOL_CONNECTION_POOL *backend, char *query, Inser } } - return status; + return POOL_CONTINUE; } /* [parent: 90081110255c]