[pgpool-hackers: 1463] Intermediate report: bug#167

Tatsuo Ishii ishii at postgresql.org
Wed Mar 16 15:12:43 JST 2016


This is an intermediate report for bug#167, willing to share
information on inspecting the issue.

http://www.pgpool.net/mantisbt/view.php?id=167

With pgpool-II 3.5 stable head still has a hang up problem when
certain extended queries are executed in streaming replication mode.
Here is a debug out from the Java application:

(1) 16:05:39.248 (1)  FE=> Parse(stmt=null,query="BEGIN",oids={})
16:05:39.248 (1)  FE=> Bind(stmt=null,portal=null)
16:05:39.248 (1)  FE=> Execute(portal=null,limit=0)
(2) 16:05:39.248 (1)  FE=> Parse(stmt=null,query="SELECT t.typname,t.oid FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON (t.typnamespace = n.oid)  WHERE n.nspname != 'pg_toast'",oids={})
16:05:39.248 (1)  FE=> Bind(stmt=null,portal=null)
16:05:39.249 (1)  FE=> Describe(portal=null)
16:05:39.249 (1)  FE=> Execute(portal=null,limit=0)
16:05:39.249 (1)  FE=> Sync
[hang]

Cause of the problem:

In (1), "sync map" for node 0, 1 are set to on. Sync map is an in
memory data structure which represents to which database node
pgpool-II send data. Pgpool-II later on uses the sync map to determine
from which node it should expect response.

In (2), pgpool-II calls do_query() to get meta table info. The
function sends query to node 0 followed by a flush message. Then
pgpool-II receives responses of the query from node 0 *and* the
response for the "BEGIN".

(3) Because there is pending data in the receive buffer of node 0,
pgpool-II calls ProcessBackendResponse() which in turn calls
read_kind_from_backend(). Since in the sync map data for both node 0,
1 are on, it hangs while trying to read data from node 1.  Note that
this only happens when the load balance node is 1. If the load balance
node is 0, this does not happen. This is the reason why the reporter
occasionally sees the issue, not always.

How to fix the problem:

- In (2), sends a flush message to node 1 as well. Node 1 will sends
  response for BEGIN and pgpool-II will not hang in (3). Problem is,
  this might cause performance problem since more message exchanging
  will be involved.

- Even if we implement above, pgpool-II will hang later on, trying to
  read data from node 1 since the SELECT was sent to only node 0.

It seems the only solution would be:

- Every time pgpool-II sends a message to backend, it remembers it in
  a FIFO queue along with data which node it sends message (similar to
  the sync map). When trying to receive message from backend,
  pgpool-II should consult the data to decide from which node it
  should read.

This is not a trivial work. If you have a simpler solution, please let
me know.

Best regards,
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese:http://www.sraoss.co.jp


More information about the pgpool-hackers mailing list