pgpool2.git / summary / log / commit / refs

commit    56bb2e4bf27900f34672ea93864d23635a7dcf6a
Author:   Tatsuo Ishii <ishii at sraoss.co.jp>
Date:     Mon Dec 08 12:32:29 2008 +0000

    Fix uninitialized variable in read_kind_from_backend.
    Also refactor to make it more effective and readable.
    Add lots of comments and enhance error message to display
    eacho kinds.


pool_process_query.c | 75 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/pool_process_query.c b/pool_process_query.c index 19d63924d..4ea27bf7a 100644 --- a/pool_process_query.c +++ b/pool_process_query.c @@ -5271,38 +5271,63 @@ static POOL_STATUS read_kind_from_one_backend(POOL_CONNECTION *frontend, POOL_CO } /* - * read kind from backends + * read_kind_from_backend: read kind from backends. + * the "frontend" parameter is used to send "kind mismatch" error message to the frontend. + * the out parameter "decided_kind" is the packet kind decided by this function. + * this function uses "decide by majority" method if kinds from all backends do not agree. */ -static POOL_STATUS read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *kind) +static POOL_STATUS read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *decided_kind) { int i; - char kind_list[MAX_NUM_BACKENDS]; - char kind_map[256]; /* 256 is the number of sizeof(char) */ + unsigned char kind_list[MAX_NUM_BACKENDS]; /* records each backend's kind */ + unsigned char kind_map[256]; /* records which kind gets majority. + * 256 is the number of distinct values expressed by unsigned char + */ + unsigned char kind; + int trust_kind; /* decided kind */ int max_kind = 0; double max_count = 0; - int degenerate_node_num = 0; - int degenerate_node[MAX_NUM_BACKENDS]; + int degenerate_node_num = 0; /* number of backends degeneration requested */ + int degenerate_node[MAX_NUM_BACKENDS]; /* degeneration requested backend list */ - memset(kind_list, -1, sizeof(kind_list)); memset(kind_map, 0, sizeof(kind_map)); for (i=0;i<NUM_BACKENDS;i++) { + /* initialize degenerate record */ + degenerate_node[i] = 0; + if (VALID_BACKEND(i)) { - if (pool_read(CONNECTION(backend, i), &kind_list[i], 1) < 0) + if (pool_read(CONNECTION(backend, i), &kind, 1) < 0) { pool_error("pool_process_query: failed to read kind from %d th backend", i); return POOL_ERROR; } pool_debug("read_kind_from_backend: read kind from %d th backend %c NUM_BACKENDS: %d", i, kind_list[i], NUM_BACKENDS); + + kind_list[i] = kind; + + kind_map[kind]++; + + if (kind_map[kind] > max_count) + { + max_kind = kind_list[i]; + max_count = kind_map[kind]; + } } + else + kind_list[i] = 0; } +#ifdef NOT_USED /* register kind map */ for (i = 0; i < NUM_BACKENDS; i++) { + /* initialize degenerate record */ + degenerate_node[i] = 0; + /* kind is singed char. * We must check negative number. */ @@ -5318,38 +5343,59 @@ static POOL_STATUS read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNEC max_count = kind_map[id]; } } +#endif if (max_count != NUM_BACKENDS) { - int trust_kind; + /* + * not all backends agree with kind. We need to do "decide by majority" + */ if (max_count <= NUM_BACKENDS / 2.0) { - /* The group belonging to master is trusted. */ + /* no one gets majority. We trust master node's kind */ trust_kind = kind_list[MASTER_NODE_ID]; } else /* max_count > NUM_BACKENDS / 2.0 */ { + /* trust majority's kind */ trust_kind = max_kind; } for (i = 0; i < NUM_BACKENDS; i++) { - if (kind_list[i] != -1 && trust_kind != kind_list[i]) + if (kind_list[i] != 0 && trust_kind != kind_list[i]) { /* degenerate */ - pool_error("pool_process_query: %d th kind %c does not match with master connection kind %c", + pool_error("pool_process_query: %d th kind %c does not match with master or majority connection kind %c", i, kind_list[i], trust_kind); degenerate_node[degenerate_node_num++] = i; } } } + else + trust_kind = kind_list[MASTER_NODE_ID]; + + *decided_kind = trust_kind; if (degenerate_node_num) { + String *msg = init_string("kind mismatch among backends"); + + for (i=0;i<NUM_BACKENDS;i++) + { + char buf[32]; + + if (kind_list[i]) + { + snprintf(buf, sizeof(buf), " %d[%c]", i, kind_list[i]); + string_append_char(msg, buf); + } + } + pool_send_error_message(frontend, MAJOR(backend), "XX000", - "kind mismatch between backends", "", - "check data consistency between master and other db node", + msg->data, "", + "check data consistency among db nodes", __FILE__, __LINE__); if (pool_config->replication_stop_on_mismatch) { @@ -5360,7 +5406,6 @@ static POOL_STATUS read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNEC return POOL_ERROR; } - *kind = kind_list[MASTER_NODE_ID]; return POOL_CONTINUE; } [parent: 52a682a23827]