Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit fe186bd

Browse files
committed
postgres_fdw: Extend postgres_fdw_get_connections to return remote backend PID.
This commit adds a new "remote_backend_pid" output column to the postgres_fdw_get_connections function. It returns the process ID of the remote backend, on the foreign server, handling the connection. This enhancement is useful for troubleshooting, monitoring, and reporting. For example, if a connection is unexpectedly closed by the foreign server, the remote backend's PID can help diagnose the cause. No extension version bump is needed, as commit c297a47 already handled it for v18~. Author: Sagar Dilip Shedge <sagar.shedge92@gmail.com> Reviewed-by: Fujii Masao <masao.fujii@gmail.com> Discussion: https://postgr.es/m/CAPhYifF25q5xUQWXETfKwhc0YVa_6+tfG9Kw4bCvCjpCWxYs2A@mail.gmail.com
1 parent 15a79c7 commit fe186bd

File tree

5 files changed

+76
-32
lines changed

5 files changed

+76
-32
lines changed

contrib/postgres_fdw/connection.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -2111,8 +2111,8 @@ pgfdw_finish_abort_cleanup(List *pending_entries, List *cancel_requested,
21112111

21122112
/* Number of output arguments (columns) for various API versions */
21132113
#define POSTGRES_FDW_GET_CONNECTIONS_COLS_V1_1 2
2114-
#define POSTGRES_FDW_GET_CONNECTIONS_COLS_V1_2 5
2115-
#define POSTGRES_FDW_GET_CONNECTIONS_COLS 5 /* maximum of above */
2114+
#define POSTGRES_FDW_GET_CONNECTIONS_COLS_V1_2 6
2115+
#define POSTGRES_FDW_GET_CONNECTIONS_COLS 6 /* maximum of above */
21162116

21172117
/*
21182118
* Internal function used by postgres_fdw_get_connections variants.
@@ -2128,13 +2128,15 @@ pgfdw_finish_abort_cleanup(List *pending_entries, List *cancel_requested,
21282128
*
21292129
* For API version 1.2 and later, this function takes an input parameter
21302130
* to check a connection status and returns the following
2131-
* additional values along with the three values from version 1.1:
2131+
* additional values along with the four values from version 1.1:
21322132
*
21332133
* - user_name - the local user name of the active connection. In case the
21342134
* user mapping is dropped but the connection is still active, then the
21352135
* user name will be NULL in the output.
21362136
* - used_in_xact - true if the connection is used in the current transaction.
21372137
* - closed - true if the connection is closed.
2138+
* - remote_backend_pid - process ID of the remote backend, on the foreign
2139+
* server, handling the connection.
21382140
*
21392141
* No records are returned when there are no cached connections at all.
21402142
*/
@@ -2273,6 +2275,9 @@ postgres_fdw_get_connections_internal(FunctionCallInfo fcinfo,
22732275
values[i++] = BoolGetDatum(pgfdw_conn_check(entry->conn) != 0);
22742276
else
22752277
nulls[i++] = true;
2278+
2279+
/* Return process ID of remote backend */
2280+
values[i++] = Int32GetDatum(PQbackendPID(entry->conn));
22762281
}
22772282

22782283
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);

contrib/postgres_fdw/expected/postgres_fdw.out

+30-16
Original file line numberDiff line numberDiff line change
@@ -10589,13 +10589,18 @@ drop cascades to foreign table ft7
1058910589
-- List all the existing cached connections. loopback and loopback3
1059010590
-- should be output as invalid connections. Also the server name and user name
1059110591
-- for loopback3 should be NULL because both server and user mapping were
10592-
-- dropped.
10593-
SELECT server_name, user_name = CURRENT_USER as "user_name = CURRENT_USER", valid, used_in_xact, closed
10594-
FROM postgres_fdw_get_connections() ORDER BY 1;
10595-
server_name | user_name = CURRENT_USER | valid | used_in_xact | closed
10596-
-------------+--------------------------+-------+--------------+--------
10597-
loopback | t | f | t |
10598-
| | f | t |
10592+
-- dropped. In this test, the PIDs of remote backends can be gathered from
10593+
-- pg_stat_activity, and remote_backend_pid should match one of those PIDs.
10594+
SELECT server_name, user_name = CURRENT_USER as "user_name = CURRENT_USER",
10595+
valid, used_in_xact, closed,
10596+
remote_backend_pid = ANY(SELECT pid FROM pg_stat_activity
10597+
WHERE backend_type = 'client backend' AND pid <> pg_backend_pid())
10598+
as remote_backend_pid
10599+
FROM postgres_fdw_get_connections() ORDER BY 1;
10600+
server_name | user_name = CURRENT_USER | valid | used_in_xact | closed | remote_backend_pid
10601+
-------------+--------------------------+-------+--------------+--------+--------------------
10602+
loopback | t | f | t | | t
10603+
| | f | t | | t
1059910604
(2 rows)
1060010605

1060110606
-- The invalid connections get closed in pgfdw_xact_callback during commit.
@@ -12436,25 +12441,34 @@ SELECT 1 FROM ft1 LIMIT 1;
1243612441

1243712442
-- Since the remote server is still connected, "closed" should be FALSE,
1243812443
-- or NULL if the connection status check is not available.
12439-
SELECT CASE WHEN closed IS NOT true THEN 1 ELSE 0 END
12444+
-- In this test, the remote backend handling this connection should have
12445+
-- application_name set to "fdw_conn_check", so remote_backend_pid should
12446+
-- match the PID from the pg_stat_activity entry with that application_name.
12447+
SELECT server_name,
12448+
CASE WHEN closed IS NOT true THEN false ELSE true END AS closed,
12449+
remote_backend_pid = (SELECT pid FROM pg_stat_activity
12450+
WHERE application_name = 'fdw_conn_check') AS remote_backend_pid
1244012451
FROM postgres_fdw_get_connections(true);
12441-
case
12442-
------
12443-
1
12452+
server_name | closed | remote_backend_pid
12453+
-------------+--------+--------------------
12454+
loopback | f | t
1244412455
(1 row)
1244512456

1244612457
-- After terminating the remote backend, since the connection is closed,
1244712458
-- "closed" should be TRUE, or NULL if the connection status check
12448-
-- is not available.
12459+
-- is not available. Despite the termination, remote_backend_pid should
12460+
-- still show the non-zero PID of the terminated remote backend.
1244912461
DO $$ BEGIN
1245012462
PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity
1245112463
WHERE application_name = 'fdw_conn_check';
1245212464
END $$;
12453-
SELECT CASE WHEN closed IS NOT false THEN 1 ELSE 0 END
12465+
SELECT server_name,
12466+
CASE WHEN closed IS NOT false THEN true ELSE false END AS closed,
12467+
remote_backend_pid <> 0 AS remote_backend_pid
1245412468
FROM postgres_fdw_get_connections(true);
12455-
case
12456-
------
12457-
1
12469+
server_name | closed | remote_backend_pid
12470+
-------------+--------+--------------------
12471+
loopback | t | t
1245812472
(1 row)
1245912473

1246012474
-- Clean up

contrib/postgres_fdw/postgres_fdw--1.1--1.2.sql

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ DROP FUNCTION postgres_fdw_get_connections ();
1212
CREATE FUNCTION postgres_fdw_get_connections (
1313
IN check_conn boolean DEFAULT false, OUT server_name text,
1414
OUT user_name text, OUT valid boolean, OUT used_in_xact boolean,
15-
OUT closed boolean)
15+
OUT closed boolean, OUT remote_backend_pid int4)
1616
RETURNS SETOF record
1717
AS 'MODULE_PATHNAME', 'postgres_fdw_get_connections_1_2'
1818
LANGUAGE C STRICT PARALLEL RESTRICTED;

contrib/postgres_fdw/sql/postgres_fdw.sql

+20-6
Original file line numberDiff line numberDiff line change
@@ -3410,9 +3410,14 @@ DROP SERVER loopback3 CASCADE;
34103410
-- List all the existing cached connections. loopback and loopback3
34113411
-- should be output as invalid connections. Also the server name and user name
34123412
-- for loopback3 should be NULL because both server and user mapping were
3413-
-- dropped.
3414-
SELECT server_name, user_name = CURRENT_USER as "user_name = CURRENT_USER", valid, used_in_xact, closed
3415-
FROM postgres_fdw_get_connections() ORDER BY 1;
3413+
-- dropped. In this test, the PIDs of remote backends can be gathered from
3414+
-- pg_stat_activity, and remote_backend_pid should match one of those PIDs.
3415+
SELECT server_name, user_name = CURRENT_USER as "user_name = CURRENT_USER",
3416+
valid, used_in_xact, closed,
3417+
remote_backend_pid = ANY(SELECT pid FROM pg_stat_activity
3418+
WHERE backend_type = 'client backend' AND pid <> pg_backend_pid())
3419+
as remote_backend_pid
3420+
FROM postgres_fdw_get_connections() ORDER BY 1;
34163421
-- The invalid connections get closed in pgfdw_xact_callback during commit.
34173422
COMMIT;
34183423
-- All cached connections were closed while committing above xact, so no
@@ -4288,17 +4293,26 @@ SELECT 1 FROM ft1 LIMIT 1;
42884293

42894294
-- Since the remote server is still connected, "closed" should be FALSE,
42904295
-- or NULL if the connection status check is not available.
4291-
SELECT CASE WHEN closed IS NOT true THEN 1 ELSE 0 END
4296+
-- In this test, the remote backend handling this connection should have
4297+
-- application_name set to "fdw_conn_check", so remote_backend_pid should
4298+
-- match the PID from the pg_stat_activity entry with that application_name.
4299+
SELECT server_name,
4300+
CASE WHEN closed IS NOT true THEN false ELSE true END AS closed,
4301+
remote_backend_pid = (SELECT pid FROM pg_stat_activity
4302+
WHERE application_name = 'fdw_conn_check') AS remote_backend_pid
42924303
FROM postgres_fdw_get_connections(true);
42934304

42944305
-- After terminating the remote backend, since the connection is closed,
42954306
-- "closed" should be TRUE, or NULL if the connection status check
4296-
-- is not available.
4307+
-- is not available. Despite the termination, remote_backend_pid should
4308+
-- still show the non-zero PID of the terminated remote backend.
42974309
DO $$ BEGIN
42984310
PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity
42994311
WHERE application_name = 'fdw_conn_check';
43004312
END $$;
4301-
SELECT CASE WHEN closed IS NOT false THEN 1 ELSE 0 END
4313+
SELECT server_name,
4314+
CASE WHEN closed IS NOT false THEN true ELSE false END AS closed,
4315+
remote_backend_pid <> 0 AS remote_backend_pid
43024316
FROM postgres_fdw_get_connections(true);
43034317

43044318
-- Clean up

doc/src/sgml/postgres-fdw.sgml

+17-6
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ OPTIONS (ADD password_required 'false');
854854
<term><function>postgres_fdw_get_connections(
855855
IN check_conn boolean DEFAULT false, OUT server_name text,
856856
OUT user_name text, OUT valid boolean, OUT used_in_xact boolean,
857-
OUT closed boolean)
857+
OUT closed boolean, OUT remote_backend_pid int4)
858858
returns setof record</function></term>
859859
<listitem>
860860
<para>
@@ -882,11 +882,11 @@ OPTIONS (ADD password_required 'false');
882882
Example usage of the function:
883883
<screen>
884884
postgres=# SELECT * FROM postgres_fdw_get_connections(true);
885-
server_name | user_name | valid | used_in_xact | closed
886-
-------------+-----------+-------+--------------+--------
887-
loopback1 | postgres | t | t | f
888-
loopback2 | public | t | t | f
889-
loopback3 | | f | t | f
885+
server_name | user_name | valid | used_in_xact | closed | remote_backend_pid
886+
-------------+-----------+-------+--------------+-----------------------------
887+
loopback1 | postgres | t | t | f | 1353340
888+
loopback2 | public | t | t | f | 1353120
889+
loopback3 | | f | t | f | 1353156
890890
</screen>
891891
The output columns are described in
892892
<xref linkend="postgres-fdw-get-connections-columns"/>.
@@ -951,6 +951,17 @@ postgres=# SELECT * FROM postgres_fdw_get_connections(true);
951951
is not available on this platform.
952952
</entry>
953953
</row>
954+
<row>
955+
<entry><structfield>remote_backend_pid</structfield></entry>
956+
<entry><type>int4</type></entry>
957+
<entry>
958+
Process ID of the remote backend, on the foreign server,
959+
handling the connection. If the remote backend is terminated and
960+
the connection is closed (with <literal>closed</literal> set to
961+
<literal>true</literal>), this still shows the process ID of
962+
the terminated backend.
963+
</entry>
964+
</row>
954965
</tbody>
955966
</tgroup>
956967
</table>

0 commit comments

Comments
 (0)