pgpool2.git / summary / log / commit / refs
commit 22e045e2f362bb007a72ef1651ed2da897e3aa86
Author: Tatsuo Ishii <ishii@postgresql.org>
Date: Mon Dec 10 04:08:22 2012 +0000
Fix long standing bug "portal not found" error when replication delay
is too much in streaming replication mode. The bug had been there
since the delay threshold was introduced.
We changed destination DB node if delay threshold exceeds in bind,
describe and execute. However, if parse sends to different node, bind,
describe or execute will fail because no parsed statement or portal
exists. Solution is, not to send to different parse node even
if delay threshold is too much.
pool_proto_modules.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/pool_proto_modules.c b/pool_proto_modules.c
index 2fd2a1d8c..17534eed8 100644
--- a/pool_proto_modules.c
+++ b/pool_proto_modules.c
@@ -779,11 +779,13 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
}
}
+ session_context->query_context = query_context;
/*
- * Decide where to send query
+ * Calling pool_where_to_send here is dangerous because the node
+ * parse/bind has been sent could be change by
+ * pool_where_to_send() and it leads to "portal not found"
+ * etc. errors.
*/
- session_context->query_context = query_context;
- pool_where_to_send(query_context, query, node);
/* check if query is "COMMIT" or "ROLLBACK" */
commit = is_commit_or_rollback_query(node);
@@ -1275,11 +1277,12 @@ POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
}
session_context->query_context = query_context;
- pool_where_to_send(query_context, query_context->original_query,
- query_context->parse_tree);
if (pool_config->load_balance_mode && pool_is_writing_transaction())
{
+ pool_where_to_send(query_context, query_context->original_query,
+ query_context->parse_tree);
+
if (parse_before_bind(frontend, backend, parse_msg) != POOL_CONTINUE)
return POOL_END;
}
@@ -1354,9 +1357,13 @@ POOL_STATUS Describe(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
}
session_context->query_context = query_context;
- pool_where_to_send(query_context, query_context->original_query,
- query_context->parse_tree);
+ /*
+ * Calling pool_where_to_send here is dangerous because the node
+ * parse/bind has been sent could be change by
+ * pool_where_to_send() and it leads to "portal not found"
+ * etc. errors.
+ */
pool_debug("Describe: waiting for master completing the query");
if (pool_extended_send_and_wait(query_context, "D", len, contents, 1, MASTER_NODE_ID)
!= POOL_CONTINUE)
[parent: 13c8b36ac068]