pgpool2.git / summary / log / commit / refs
commit 39e07ea13a7f318f2c50a8aec7baa93e13a347d3
Author: Tatsuo Ishii <ishii@postgresql.org>
Date: Tue Mar 29 11:05:06 2016 +0000
Fix extended query hangs
Deal with bug 167. The problem is in the following sequence:
Parse(BEGIN)
Bind
:
Execute
Parse(SELECT)
Bind
:
(Notice that no Sync message between Execute and Parse)
BEGIN is sent to all db nodes while select is sent to one of db
nodes. So pgpool is confused which DB node to read the response. To
fix this, after each Execute, send flash message to backend to get
response. This will ensure that the responses of BEGIN etc. are read
from all DB nodes while the responses of SELECT etc. are read from
only one of DB node.
src/protocol/CommandComplete.c | 3 +++
src/protocol/pool_proto_modules.c | 26 ++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/src/protocol/CommandComplete.c b/src/protocol/CommandComplete.c
index e72b9066e..f18f3db11 100644
--- a/src/protocol/CommandComplete.c
+++ b/src/protocol/CommandComplete.c
@@ -150,6 +150,9 @@ POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
pool_set_query_state(session_context->query_context, POOL_EXECUTE_COMPLETE);
}
+ if (STREAM && pool_is_doing_extended_query_message())
+ pool_unset_query_in_progress();
+
return POOL_CONTINUE;
}
diff --git a/src/protocol/pool_proto_modules.c b/src/protocol/pool_proto_modules.c
index 5e871233e..15aa00bcc 100644
--- a/src/protocol/pool_proto_modules.c
+++ b/src/protocol/pool_proto_modules.c
@@ -760,7 +760,30 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
{
pool_extended_send_and_wait(query_context, "E", len, contents, 1, MASTER_NODE_ID, true);
pool_extended_send_and_wait(query_context, "E", len, contents, -1, MASTER_NODE_ID, true);
+
+ /*
+ * Send flush message to backend to make sure that we get any response
+ * from backend.
+ */
+ pool_write(MASTER(session_context->backend), "H", 1);
+ len = htonl(sizeof(len));
+ pool_write_and_flush(MASTER(session_context->backend), &len, sizeof(len));
+ if (MASTER(session_context->backend)->db_node_id != session_context->load_balance_node_id)
+ {
+ POOL_CONNECTION *con;
+
+ con = session_context->backend->slots[session_context->load_balance_node_id]->con;
+ pool_write(con, "H", 1);
+ len = htonl(sizeof(len));
+ pool_write_and_flush(con, &len, sizeof(len));
+ }
+ /*
+ * Remeber that we send flush or sync message to backend.
+ */
+ pool_unset_pending_response();
+#ifdef NOT_USED
pool_unset_query_in_progress();
+#endif
}
return POOL_CONTINUE;
@@ -1087,6 +1110,7 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
{
/* XXX fix me:even with streaming replication mode, couldn't we have a deadlock */
pool_set_query_in_progress();
+ pool_clear_sync_map();
pool_extended_send_and_wait(query_context, "P", len, contents, 1, MASTER_NODE_ID, true);
pool_extended_send_and_wait(query_context, "P", len, contents, -1, MASTER_NODE_ID, true);
pool_add_sent_message(session_context->uncompleted_message);
@@ -1216,6 +1240,7 @@ POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
nowait = (STREAM? true: false);
+ pool_clear_sync_map();
pool_extended_send_and_wait(query_context, "B", len, contents, 1, MASTER_NODE_ID, nowait);
pool_extended_send_and_wait(query_context, "B", len, contents, -1, MASTER_NODE_ID, nowait);
@@ -1367,6 +1392,7 @@ POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
{
POOL_PENDING_MESSAGE *pmsg;
+ pool_clear_sync_map();
pool_extended_send_and_wait(query_context, "C", len, contents, 1, MASTER_NODE_ID, true);
pool_extended_send_and_wait(query_context, "C", len, contents, -1, MASTER_NODE_ID, true);
[parent: 37767d0910b9]