Fix bug with sending bind message to wrong target node.
authorTatsuo Ishii <ishii@postgresql.org>
Wed, 7 Jun 2017 04:53:13 +0000 (13:53 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Wed, 7 Jun 2017 04:53:13 +0000 (13:53 +0900)
commitc1892fffde8b47207eacb47d337281d37b2e4ce2
tree13ded2658ea7184b14323db7093bff7cdc6d3468
parent20e1dab7786f458a0aca4a1b884f9672e8e4df1a
Fix bug with sending bind message to wrong target node.

When a close portal message received, Pgpool-II forwards it to both
primary and load balance node in streaming replication mode. Later on
a close complete message returned from backend, and
read_kind_from_backend gets called, then it calls
pool_pending_message_query_context_dest_set, which rewrites
where_to_send map in the current query context accordingly. If a bind
message using the same query is received, it will be forwarded to both
primary and load balance node because the where_to_send map was
rewritten so. Unfortunately, the prepared statement might not exist on
primary node, if the query was parsed only on the load balance
node. So we get an error.

Fix is, restoring the where_to_send map after processing the close
complete message. For this sake, where_to_send map back up area is
added to session context. Also new flag need_to_restore_where_to_send
is added. Those new data is handled inside
pool_pending_message_query_context_dest_set. The where_to_send map is
restored in pool_unset_query_in_progress. There were several places
which do not call pool_unset_query_in_progress. They are also fixed to
call it.

Per bug #314.
https://www.pgpool.net/mantisbt/view.php?id=314

To reproduce the problem, following pgproto data can be used. Also you
need to set the weight parameter on primary to 0 and standby to 1 to reliably
reproduce the problem.

'P' "S_1" "SELECT 1" 0
'B' "C_1" "S_1" 0 0    0
'E' "C_1" 0
'S'
'Y'

'C' 'P' "C_1"

'B' "C_2" "S_1" 0 0 0
'E' "C_2" 0
'S'
'Y'

'X'
src/context/pool_session_context.c
src/include/context/pool_session_context.h
src/protocol/pool_proto_modules.c