Deal with "unable to bind D cannot get parse message "S1" error.
authorTatsuo Ishii <ishii@postgresql.org>
Wed, 14 Mar 2018 08:19:18 +0000 (17:19 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Wed, 14 Mar 2018 08:19:18 +0000 (17:19 +0900)
Before this just raised an exception and issue "DISCARD ALL" to only
node 0 if load balance node = 0 because query context wants to do
so. Problem is, when an exception is raised, the query context is not
active any more and Pgpool-II tries to read from node 1, which causes
a hang up.

Add new test for this to the extended query test.

src/protocol/pool_proto_modules.c
src/test/extended-query-test/expected/unable_to_bind.data [new file with mode: 0644]
src/test/extended-query-test/tests/unable_to_bind.data [new file with mode: 0644]

index 359875f3cc69990f6da5f6554c3c1cc6140740ff..d8d926288f50b29d792882c2c5c7942c2a1f5c29 100644 (file)
@@ -5,7 +5,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2017     PgPool Global Development Group
+ * Copyright (c) 2003-2018     PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -1303,7 +1303,7 @@ POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
                parse_msg = pool_get_sent_message('P', pstmt_name, POOL_SENT_MESSAGE_CREATED);
        if (!parse_msg)
        {
-        ereport(ERROR,
+        ereport(FATAL,
                 (errmsg("unable to bind"),
                  errdetail("cannot get parse message \"%s\"", pstmt_name)));
        }
@@ -1315,7 +1315,7 @@ POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
        query_context = parse_msg->query_context;
        if (!query_context)
        {
-        ereport(ERROR,
+        ereport(FATAL,
                 (errmsg("unable to bind"),
                  errdetail("cannot get the query context")));
        }
@@ -2883,7 +2883,7 @@ POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend,
                }
 
                if (string == NULL)
-            ereport(ERROR,
+            ereport(FATAL,
                 (errmsg("unable to copy data rows"),
                      errdetail("cannot read string message from backend")));
 
diff --git a/src/test/extended-query-test/expected/unable_to_bind.data b/src/test/extended-query-test/expected/unable_to_bind.data
new file mode 100644 (file)
index 0000000..034f77d
--- /dev/null
@@ -0,0 +1,19 @@
+FE=> Query(query="DROP TABLE IF EXISTS pgproto_test1")
+<= BE NoticeResponse(S NOTICE V NOTICE C 00000 M table "pgproto_test1" does not exist, skipping F tablecmds.c L 914 R DropErrorMsgNonExistent )
+<= BE CommandComplete(DROP TABLE)
+<= BE ReadyForQuery(I)
+FE=> Query(query="CREATE TABLE pgproto_test1(i INT)")
+<= BE CommandComplete(CREATE TABLE)
+<= BE ReadyForQuery(I)
+FE=> Parse(stmt="", query="BEGIN")
+FE=> Bind(stmt="S1", portal="")
+FE=> Execute(portal="")
+FE=> Parse(stmt="", query="INSERT INTO pgproto_test1 VALUES(1)")
+FE=> Bind(stmt="", portal="")
+FE=> Execute(portal="")
+FE=> Parse(stmt="", query="COMMIT")
+FE=> Bind(stmt="", portal="")
+FE=> Execute(portal="")
+FE=> Sync
+<= BE ErrorResponse(S FATAL C XX000 M unable to bind D cannot get parse message "S1" F pool_proto_modules.c L 1308 )
+read_it: read(2) returns error Connection reset by peer
diff --git a/src/test/extended-query-test/tests/unable_to_bind.data b/src/test/extended-query-test/tests/unable_to_bind.data
new file mode 100644 (file)
index 0000000..b660005
--- /dev/null
@@ -0,0 +1,34 @@
+# Test data for FATAL: unable to bind DETAIL: cannot get parse message
+# "S1". This caused hang up of Pgpool-II.
+
+##backend_weight0 = 1
+##backend_weight1 = 0
+
+# Create test table
+'Q'    "DROP TABLE IF EXISTS pgproto_test1"
+'Y'
+'Q'    "CREATE TABLE pgproto_test1(i INT)"
+'Y'
+
+# Start a transaction
+'P'    ""      "BEGIN" 0
+'B'    ""      "S1"    0       0       0
+'E'    ""      0
+
+# Issue INSERT
+'P'    ""      "INSERT INTO pgproto_test1 VALUES(1)"   0
+'B'    ""      ""      0       0       0
+'E'    ""      0
+
+# Issue COMMIT
+'P'    ""      "COMMIT"        0
+'B'    ""      ""      0       0       0
+'E'    ""      0
+'S'
+'Y'
+
+# DROP test table
+'Q'    "DROP TABLE pgproto_test1"
+'Y'
+
+'X'