pgpool did not failover when kind mismatch error occured using an
authorYoshiyuki Asaba <y-asaba at pgfoundry.org>
Mon, 28 May 2007 01:26:12 +0000 (01:26 +0000)
committerYoshiyuki Asaba <y-asaba at pgfoundry.org>
Mon, 28 May 2007 01:26:12 +0000 (01:26 +0000)
extended query protocol. So if it occurs in Execute(), pgpool does
failover.

pool_auth.c
pool_process_query.c

index 79ab1323358d3604da9a4c539d0aaf0f07c2500b..9792ff52baf3eb4ef7612cf9685a1bd33330d920 100644 (file)
@@ -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;
                }
        }
 
index 80000ef4ecc23994a6c7c738744a06fde78f25c2..6c42f1a08ea2fb55f6fa411649d425e942324e96 100644 (file)
@@ -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;
+}