Hello All,

The query on foreign table hangs due to network down of remote server for
near about 16 minutes before exiting.
statement_timeout is expected to work in this case as well but when i tried
statement_timeout, it is not working as expected.

Below is test case to reproduce the issue: [I am testing this on two
different systems]

1: Set the postgres_fdw

postgres=# CREATE SERVER myserver FOREIGN DATA WRAPPER postgres_fdw OPTIONS
(host '172.16.173.237', dbname 'postgres', port '5432',keepalives '1',
keepalives_interval '3',keepalives_idle '3', keepalives_count '1');
CREATE SERVER
postgres=# CREATE USER MAPPING FOR postgres SERVER myserver OPTIONS (user
'postgres', password 'edb');
CREATE USER MAPPING
postgres=# CREATE FOREIGN TABLE test(id int) SERVER myserver;
CREATE FOREIGN TABLE
postgres=# select * from test;
 id
----
  1
 10
  2
  1
(4 rows)

postgres=# \d
            List of relations
 Schema | Name |     Type      |  Owner
--------+------+---------------+----------
 public | test | foreign table | postgres
(1 row)
postgres=#
postgres=# select * from pg_foreign_server ;
 srvname  | srvowner | srvfdw | srvtype | srvversion | srvacl |
                                          srvoptions


----------+----------+--------+---------+------------+--------+------------------------------------------------------------------------------------------------------------------
-------
 myserver |       10 |  16387 |         |            |        |
{host=172.16.173.237,dbname=postgres,port=5432,keepalives=1,keepalives_interval=3,keepalives_idle=3,keepalives_co
unt=1}
(1 row)

3. Execute the insert command.
E.g: insert into test values (generate_series(1,1000000));
* You need to do network down of remote server during insert command.

postgres=# set statement_timeout to 6000;
SET
postgres=# insert into test values (generate_series(1,1000000));
WARNING:  server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.

CONTEXT:  Remote SQL command: ABORT TRANSACTION
ERROR:  could not receive data from server: No route to host

CONTEXT:  Remote SQL command: INSERT INTO public.test(id) VALUES ($1)
Time: 931427.002 ms

It was in hang state for approx 15-16 minute before exit.

In pg_log, i see below error for above query:
=========
2017-04-20 15:22:02 IST ERROR:  could not receive data from server: No
route to host
2017-04-20 15:22:02 IST CONTEXT:  Remote SQL command: INSERT INTO
public.test(id) VALUES ($1)
2017-04-20 15:22:02 IST STATEMENT:  insert into test values
(generate_series(1,1000000));
2017-04-20 15:22:02 IST WARNING:  server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
2017-04-20 15:22:02 IST CONTEXT:  Remote SQL command: ABORT TRANSACTION
==========

I tested the patch submitted by Ashutosh Bapat on community [
https://www.postgresql.org/message-id/CAFjFpRdcWw4h0a-zrL-EiaekkPj8O0GR2M1FwZ1useSRfRm3-g%40mail.gmail.com]
to make the statement_timeout working and i can see statement_timeout is
working but it is taking some extra time as statement_timeout.

postgres=# set statement_timeout to 6000;
SET
postgres=#
postgres=# \timing on
Timing is on.
postgres=# insert into test values (generate_series(1,1000000));
-- [after executing query immediately disconnect the ethernet on remote
server ]
2017-04-20 07:10:51.588 IST [10467] ERROR:  canceling statement due to
statement timeout
2017-04-20 07:10:51.588 IST [10467] STATEMENT:  insert into test values
(generate_series(1,1000000));
2017-04-20 07:11:25.590 IST [10467] WARNING:  discarding connection
0xfe4260 because of failed cancel request: PQcancel() -- connect() failed:
No route to host
WARNING:  discarding connection 0xfe4260 because of failed cancel request:
PQcancel() -- connect() failed: No route to host

ERROR:  canceling statement due to statement timeout
Time: 40001.765 ms (00:40.002)
postgres=#
postgres=#

In above case, I got the error related to statement timeout after 6 seconds,
but it it taking more time (approx 34 sec and it is varing each time if you
see below) to terminate the connection and to exit from query. As per the
tcp keepavlies settings for foreign server, it should take max 6 sec to
terminate the connection.


postgres=#
postgres=# set statement_timeout to 20000;
SET
Time: 0.254 ms
postgres=#
postgres=# insert into test values (generate_series(1,1000000));
2017-04-20 07:13:25.666 IST [10467] ERROR:  canceling statement due to
statement timeout
2017-04-20 07:13:25.666 IST [10467] STATEMENT:  insert into test values
(generate_series(1,1000000));
2017-04-20 07:13:43.668 IST [10467] WARNING:  discarding connection
0xfe4260 because of failed cancel request: PQcancel() -- connect() failed:
No route to host
WARNING:  discarding connection 0xfe4260 because of failed cancel request:
PQcancel() -- connect() failed: No route to host

ERROR:  canceling statement due to statement timeout
Time: 38004.169 ms (00:38.004)
postgres=#


When I tested this using a local TCP connection, then query was exited
immediately after statement timeout.


Suraj Kharage
EnterpriseDB Corporation
The Postgres Database Company

Reply via email to