From 808e2cecbb4cb684bb3ae1d45e5a0da86bef28d1 Mon Sep 17 00:00:00 2001 From: Yoshiyuki Asaba Date: Mon, 28 May 2007 01:26:12 +0000 Subject: [PATCH] pgpool did not failover when kind mismatch error occured using an extended query protocol. So if it occurs in Execute(), pgpool does failover. --- pool_auth.c | 6 ++- pool_process_query.c | 88 +++++++++++++++++++------------------------- 2 files changed, 42 insertions(+), 52 deletions(-) diff --git a/pool_auth.c b/pool_auth.c index 79ab132..9792ff5 100644 --- a/pool_auth.c +++ b/pool_auth.c @@ -1019,6 +1019,10 @@ int *pool_read_message_length2(POOL_CONNECTION_POOL *cp) return &length_array[0]; } +/* + * return: -2 if kind does not match. + * -1 if an error occured. + */ signed char pool_read_kind(POOL_CONNECTION_POOL *cp) { int status; @@ -1044,7 +1048,7 @@ signed char pool_read_kind(POOL_CONNECTION_POOL *cp) { pool_error("read_kind: kind does not match between backends master(%d) secondary(%d)", kind, kind1); - return -1; + return -2; } } diff --git a/pool_process_query.c b/pool_process_query.c index 80000ef..6c42f1a 100644 --- a/pool_process_query.c +++ b/pool_process_query.c @@ -136,6 +136,7 @@ static PreparedStatement *lookup_prepared_statement_by_statement(PreparedStateme static PreparedStatement *lookup_prepared_statement_by_portal(PreparedStatementList *p, const char *name); static int send_deallocate(POOL_CONNECTION_POOL *backend, PreparedStatementList *p, int n); static char *normalize_prepared_stmt_name(const char *name); +static POOL_STATUS error_kind_mismatch(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int kind, int kind1); static POOL_CONNECTION_POOL_SLOT *slots[MAX_CONNECTION_SLOTS]; @@ -321,31 +322,7 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, pool_read(SECONDARY(backend), &kind1, 1); if (kind == '\0' || kind != kind1) { - int sts; - - pool_error("pool_process_query: kind does not match between backends master(%c) secondary(%c)", - kind, kind1); - pool_send_error_message(frontend, MAJOR(backend), "XX000", - "kind mismatch between backends", "", - "check data consistency between master and secondary", __FILE__, __LINE__); - - /* health check */ - sts = health_check(); - if (sts == -1) - { - notice_backend_error(1); - exit(1); - } - else if (sts == -2) - { - notice_backend_error(0); - exit(1); - } - - if (pool_config.replication_stop_on_mismatch) - return POOL_FATAL; - else - return POOL_ERROR; + return error_kind_mismatch(frontend, backend, kind, kind1); } } pool_debug("read kind from backend pending data %c len: %d po: %d", kind, MASTER(backend)->len, MASTER(backend)->po); @@ -406,31 +383,7 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, if (kind == '\0' || kind != kind1) { - int sts; - - pool_error("pool_process_query: kind does not match between backends master(%c) secondary(%c)", - kind, kind1); - pool_send_error_message(frontend, MAJOR(backend), "XX000", - "kind mismatch between backends", "", - "check data consistency between master and secondary", __FILE__, __LINE__); - - /* health check */ - sts = health_check(); - if (sts == -1) - { - notice_backend_error(1); - exit(1); - } - else if (sts == -2) - { - notice_backend_error(0); - exit(1); - } - - if (pool_config.replication_stop_on_mismatch) - return POOL_FATAL; - else - return POOL_ERROR; + return error_kind_mismatch(frontend, backend, kind, kind1); } } @@ -911,7 +864,11 @@ static POOL_STATUS Execute(POOL_CONNECTION *frontend, while ((kind = pool_read_kind(backend)), (kind != 'C' && kind != 'E' && kind != 'l' && kind != 's')) { - if (kind < 0) + if (kind == -2) /* kind mismatch */ + { + return error_kind_mismatch(frontend, backend, 0, 0); + } + else if (kind < 0) { pool_error("Execute: pool_read_kind error"); return POOL_ERROR; @@ -3835,3 +3792,32 @@ static void query_ps_status(char *query, POOL_CONNECTION_POOL *backend) set_ps_display(psbuf, false); } + +static POOL_STATUS error_kind_mismatch(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int kind, int kind1) +{ + int sts; + + pool_error("pool_process_query: kind does not match between backends master(%c) secondary(%c)", + kind, kind1); + pool_send_error_message(frontend, MAJOR(backend), "XX000", + "kind mismatch between backends", "", + "check data consistency between master and secondary", __FILE__, __LINE__); + + /* health check */ + sts = health_check(); + if (sts == -1) + { + notice_backend_error(1); + exit(1); + } + else if (sts == -2) + { + notice_backend_error(0); + exit(1); + } + + if (pool_config.replication_stop_on_mismatch) + return POOL_FATAL; + else + return POOL_ERROR; +} -- 2.39.5