Re: postgres_fdw - cached connection leaks if the associated user mapping/foreign server is dropped
Fujii Masao <masao.fujii@oss.nttdata.com>
From: Fujii Masao <masao.fujii@oss.nttdata.com>
To: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>,
PostgreSQL-development <pgsql-hackers@postgresql.org>
Date: 2020-12-23T14:01:44Z
Lists: pgsql-hackers
Attachments
- postgres_fdw_conn_leak_fujii_poc.patch (text/plain) patch
On 2020/12/15 11:38, Bharath Rupireddy wrote: > Hi, > > As discussed in [1], in postgres_fdw the cached connections to remote > servers can stay until the lifetime of the local session without > getting a chance to disconnect (connection leak), if the underlying > user mapping or foreign server is dropped in another session. Here are > few scenarios how this can happen: > > Use case 1: > 1) Run a foreign query in session 1 with server 1 and user mapping 1 > 2) Drop user mapping 1 in another session 2, an invalidation message > gets generated which will have to be processed by all the sessions > 3) Run the foreign query again in session 1, at the start of txn the > cached entry gets invalidated via pgfdw_inval_callback() (as part of > invalidation message processing). Whatever may be the type of foreign > query (select, update, explain, delete, insert, analyze etc.), upon > next call to GetUserMapping() from postgres_fdw.c, the cache lookup > fails(with ERROR: user mapping not found for "XXXX") since the user > mapping 1 has been dropped in session 2 and the query will also fail > before reaching GetConnection() where the connections associated with > the invalidated entries would have got disconnected. > > So, the connection associated with invalidated entry would remain > until the local session exits. > > Use case 2: > 1) Run a foreign query in session 1 with server 1 and user mapping 1 > 2) Try to drop foreign server 1, then we would not be allowed because > of dependency. Use CASCADE so that dependent objects i.e. user mapping > 1 and foreign tables get dropped along with foreign server 1. > 3) Run the foreign query again in session 1, at the start of txn, the > cached entry gets invalidated via pgfdw_inval_callback() and the query > fails because there is no foreign table. > > Note that the remote connection remains open in session 1 until the > local session exits. > > To solve the above connection leak problem, it looks like the right > place to close all the invalid connections is pgfdw_xact_callback(), > once registered, which gets called at the end of every txn in the > current session(by then all the sub txns also would have been > finished). Note that if there are too many invalidated entries, then > the following txn has to close all of them, but that's okay than > having leaked connections and it's a one time job for the following > one txn. > > Attaching a patch for the same. > > Thoughts? Thanks for making the patch! I agree to make pgfdw_xact_callback() close the connection when entry->invalidated == true. But I think that it's better to get rid of have_invalid_connections flag and make pgfdw_inval_callback() close the connection immediately if entry->xact_depth == 0, to avoid unnecessary scan of the hashtable during COMMIT of transaction not accessing to foreign servers. Attached is the POC patch that I'm thinking. Thought? Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Commits
-
postgres_fdw: Fix connection leak.
- b5c73eef8adf 9.5.25 landed
- 03b7a1ee7b7f 9.6.21 landed
- 744357d8461c 10.16 landed
- 294cdd7d0fff 11.11 landed
- e792ca4aca26 12.6 landed
- 546f143740a0 13.2 landed
- e3ebcca843a4 14.0 landed