Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/04/02 2:22, Fujii Masao wrote: Thanks a lot! Barring any objection, I will commit this version. Pushed. Thanks! Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/04/02 1:13, Bharath Rupireddy wrote: On Thu, Apr 1, 2021 at 8:56 PM Fujii Masao wrote: Attaching v21 patch set, rebased onto the latest master. I agree to add the server-level option. But I'm still not sure if it's good idea to also expose that option as GUC. Isn't the server-level option enough for most cases? Also it's strange to expose only this option as GUC while there are other many postgres_fdw options? With v21-002 patch, even when keep_connections GUC is disabled, the existing open connections are not close immediately. Only connections used in the transaction are closed at the end of that transaction. That is, the existing connections that no transactions use will never be closed. I'm not sure if this behavior is intuitive for users. Therefore for now I'm thinking to support the server-level option at first... Then if we find it's not enough for most cases in practice, I'd like to consider to expose postgres_fdw options including keep_connections as GUC. Thought? +1 to have only a server-level option for now and if the need arises we could expose it as a GUC. BTW these patches fail to be applied to the master because of commit 27e1f14563. I updated and simplified the 003 patch. Patch attached. Thanks for updating the patch. It looks good to me. Just a minor change, instead of using "true" and "off" for the option, I used "on" and "off" in the docs. Attaching v23. Thanks a lot! Barring any objection, I will commit this version. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Thu, Apr 1, 2021 at 8:56 PM Fujii Masao wrote: > > > Attaching v21 patch set, rebased onto the latest master. > > I agree to add the server-level option. But I'm still not sure if it's good > idea to also expose that option as GUC. Isn't the server-level option enough > for most cases? > > Also it's strange to expose only this option as GUC while there are other > many postgres_fdw options? > > With v21-002 patch, even when keep_connections GUC is disabled, the existing > open connections are not close immediately. Only connections used in the > transaction are closed at the end of that transaction. That is, the existing > connections that no transactions use will never be closed. I'm not sure if > this behavior is intuitive for users. > > Therefore for now I'm thinking to support the server-level option at first... > Then if we find it's not enough for most cases in practice, I'd like to > consider to expose postgres_fdw options including keep_connections as GUC. > > Thought? +1 to have only a server-level option for now and if the need arises we could expose it as a GUC. > BTW these patches fail to be applied to the master because of commit > 27e1f14563. I updated and simplified the 003 patch. Patch attached. Thanks for updating the patch. It looks good to me. Just a minor change, instead of using "true" and "off" for the option, I used "on" and "off" in the docs. Attaching v23. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v23-0003-postgres_fdw-server-level-option-keep_connection.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/02/22 14:55, Bharath Rupireddy wrote: On Thu, Feb 4, 2021 at 9:36 AM Bharath Rupireddy wrote: On Wed, Feb 3, 2021 at 4:22 PM Fujii Masao wrote: Maybe my explanation in the previous email was unclear. What I think is; If the server-level option is explicitly specified, its setting is used whatever GUC is. On the other hand, if the server-level option is NOT specified, GUC setting is used. For example, if we define the server as follows, GUC setting is used because the server-level option is NOT specified. CREATE SERVER loopback FOREIGN DATA WRAPPER postgres; If we define the server as follows, the server-level setting is used. CREATE SERVER loopback FOREIGN DATA WRAPPER postgres OPTIONS (keep_connections 'on'); Attaching v20 patch set. Now, server level option if provided overrides the GUC.The GUC will be used only if server level option is not provided. And also, both server level option and GUC are named the same - "keep_connections". Please have a look. Attaching v21 patch set, rebased onto the latest master. I agree to add the server-level option. But I'm still not sure if it's good idea to also expose that option as GUC. Isn't the server-level option enough for most cases? Also it's strange to expose only this option as GUC while there are other many postgres_fdw options? With v21-002 patch, even when keep_connections GUC is disabled, the existing open connections are not close immediately. Only connections used in the transaction are closed at the end of that transaction. That is, the existing connections that no transactions use will never be closed. I'm not sure if this behavior is intuitive for users. Therefore for now I'm thinking to support the server-level option at first... Then if we find it's not enough for most cases in practice, I'd like to consider to expose postgres_fdw options including keep_connections as GUC. Thought? BTW these patches fail to be applied to the master because of commit 27e1f14563. I updated and simplified the 003 patch. Patch attached. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c index 54ab8edfab..6a61d83862 100644 --- a/contrib/postgres_fdw/connection.c +++ b/contrib/postgres_fdw/connection.c @@ -59,6 +59,8 @@ typedef struct ConnCacheEntry boolhave_error; /* have any subxacts aborted in this xact? */ boolchanging_xact_state;/* xact state change in process */ boolinvalidated;/* true if reconnect is pending */ + boolkeep_connections; /* setting value of keep_connections +* server option */ Oid serverid; /* foreign server OID used to get server name */ uint32 server_hashvalue; /* hash value of foreign server OID */ uint32 mapping_hashvalue; /* hash value of user mapping OID */ @@ -286,6 +288,7 @@ static void make_new_connection(ConnCacheEntry *entry, UserMapping *user) { ForeignServer *server = GetForeignServer(user->serverid); + ListCell *lc; Assert(entry->conn == NULL); @@ -304,6 +307,26 @@ make_new_connection(ConnCacheEntry *entry, UserMapping *user) ObjectIdGetDatum(user->umid)); memset(&entry->state, 0, sizeof(entry->state)); + /* +* Determine whether to keep the connection that we're about to make here +* open even after the transaction using it ends, so that the subsequent +* transactions can re-use it. +* +* It's enough to determine this only when making new connection because +* all the connections to the foreign server whose keep_connections option +* is changed will be closed and re-made later. +* +* By default, all the connections to any foreign servers are kept open. +*/ + entry->keep_connections = true; + foreach(lc, server->options) + { + DefElem*def = (DefElem *) lfirst(lc); + + if (strcmp(def->defname, "keep_connections") == 0) + entry->keep_connections = defGetBoolean(def); + } + /* Now try to make the connection */ entry->conn = connect_pg_server(server, user); @@ -970,14 +993,16 @@ pgfdw_xact_callback(XactEvent event, void *arg) entry->xact_depth = 0; /* -* If the connection isn't in a good idle state or it is marked as -* invalid, then discard it to recover. Next GetConnection will open a -* new connection. +* If the connection isn't in a good idle state, it is marked as +* inv
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Thu, Feb 4, 2021 at 9:36 AM Bharath Rupireddy wrote: > > On Wed, Feb 3, 2021 at 4:22 PM Fujii Masao > wrote: > > Maybe my explanation in the previous email was unclear. What I think is; If > > the server-level option is explicitly specified, its setting is used > > whatever GUC is. On the other hand, if the server-level option is NOT > > specified, GUC setting is used. For example, if we define the server as > > follows, GUC setting is used because the server-level option is NOT > > specified. > > > > CREATE SERVER loopback FOREIGN DATA WRAPPER postgres; > > > > If we define the server as follows, the server-level setting is used. > > > > CREATE SERVER loopback FOREIGN DATA WRAPPER postgres OPTIONS > > (keep_connections 'on'); > > Attaching v20 patch set. Now, server level option if provided > overrides the GUC.The GUC will be used only if server level option is > not provided. And also, both server level option and GUC are named the > same - "keep_connections". > > Please have a look. Attaching v21 patch set, rebased onto the latest master. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v21-0002-postgres_fdw-add-keep_connections-GUC-to-not-cac.patch Description: Binary data v21-0003-postgres_fdw-server-level-option-keep_connection.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Wed, Feb 3, 2021 at 4:22 PM Fujii Masao wrote: > Maybe my explanation in the previous email was unclear. What I think is; If > the server-level option is explicitly specified, its setting is used whatever > GUC is. On the other hand, if the server-level option is NOT specified, GUC > setting is used. For example, if we define the server as follows, GUC setting > is used because the server-level option is NOT specified. > > CREATE SERVER loopback FOREIGN DATA WRAPPER postgres; > > If we define the server as follows, the server-level setting is used. > > CREATE SERVER loopback FOREIGN DATA WRAPPER postgres OPTIONS > (keep_connections 'on'); Attaching v20 patch set. Now, server level option if provided overrides the GUC.The GUC will be used only if server level option is not provided. And also, both server level option and GUC are named the same - "keep_connections". Please have a look. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v20-0002-postgres_fdw-add-keep_connections-GUC-to-not-cac.patch Description: Binary data v20-0003-postgres_fdw-server-level-option-keep_connection.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/02/03 13:56, Bharath Rupireddy wrote: On Tue, Feb 2, 2021 at 9:45 AM Fujii Masao wrote: One merit of keep_connections that I found is that we can use it even when connecting to the older PostgreSQL that doesn't support idle_session_timeout. Also it seems simpler to use keep_connections rather than setting idle_session_timeout in multiple remote servers. So I'm inclined to add this feature, but I'd like to hear more opinions. Thanks. And, just using idle_session_timeout on a remote server may not help us completely. Because the remote session may go away, while we are still using that cached connection in an explicit txn on the local session. Our connection retry will also not work because we are in the middle of an xact, so the local explicit txn gets aborted. Regarding idle_in_transaction_session_timeout, this seems true. But I was thinking that idle_session_timeout doesn't cause this issue because it doesn't close the connection in the middle of transaction. No? You are right. idle_session_timeout doesn't take effect when in the middle of an explicit txn. I missed this point. Here are some review comments. - (used_in_current_xact && !keep_connections)) + (used_in_current_xact && + (!keep_connections || !entry->keep_connection))) The names of GUC and server-level option should be the same, to make the thing less confusing? We can have GUC name keep_connections as there can be multiple connections within a local session and I can change the server level option keep_connection to keep_connections because a single foreign server can have multiple connections as we have seen that in the use case identified by you. I will change that in the next patch set. IMO the server-level option should override GUC. IOW, GUC setting should be used only when the server-level option is not specified. But the above code doesn't seem to do that. Thought? Note that default values for GUC and server level option are on i.e. connections are cached. The main intention of the GUC is to not set server level options to false for all the foreign servers in case users don't want to keep any foreign server connections. If the server level option overrides GUC, then even if users set GUC to off, they have to set the server level option to false for all the foreign servers. Maybe my explanation in the previous email was unclear. What I think is; If the server-level option is explicitly specified, its setting is used whatever GUC is. On the other hand, if the server-level option is NOT specified, GUC setting is used. For example, if we define the server as follows, GUC setting is used because the server-level option is NOT specified. CREATE SERVER loopback FOREIGN DATA WRAPPER postgres; If we define the server as follows, the server-level setting is used. CREATE SERVER loopback FOREIGN DATA WRAPPER postgres OPTIONS (keep_connections 'on'); For example, log_autovacuum_min_duration GUC and reloption work in the similar way. That is, reloption setting overrides GUC. If reltion is not specified, GUC is used. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Tue, Feb 2, 2021 at 9:45 AM Fujii Masao wrote: > One merit of keep_connections that I found is that we can use it even > when connecting to the older PostgreSQL that doesn't support > idle_session_timeout. Also it seems simpler to use keep_connections > rather than setting idle_session_timeout in multiple remote servers. > So I'm inclined to add this feature, but I'd like to hear more opinions. Thanks. > > And, just using idle_session_timeout on a remote server may not help > > us completely. Because the remote session may go away, while we are > > still using that cached connection in an explicit txn on the local > > session. Our connection retry will also not work because we are in the > > middle of an xact, so the local explicit txn gets aborted. > > Regarding idle_in_transaction_session_timeout, this seems true. But > I was thinking that idle_session_timeout doesn't cause this issue because > it doesn't close the connection in the middle of transaction. No? You are right. idle_session_timeout doesn't take effect when in the middle of an explicit txn. I missed this point. > Here are some review comments. > > - (used_in_current_xact && !keep_connections)) > + (used_in_current_xact && > + (!keep_connections || !entry->keep_connection))) > > The names of GUC and server-level option should be the same, > to make the thing less confusing? We can have GUC name keep_connections as there can be multiple connections within a local session and I can change the server level option keep_connection to keep_connections because a single foreign server can have multiple connections as we have seen that in the use case identified by you. I will change that in the next patch set. > IMO the server-level option should override GUC. IOW, GUC setting > should be used only when the server-level option is not specified. > But the above code doesn't seem to do that. Thought? Note that default values for GUC and server level option are on i.e. connections are cached. The main intention of the GUC is to not set server level options to false for all the foreign servers in case users don't want to keep any foreign server connections. If the server level option overrides GUC, then even if users set GUC to off, they have to set the server level option to false for all the foreign servers. So, the below code in the patch, first checks the GUC. If the GUC is off, then discards the connections. If the GUC is on, then it further checks the server level option. If it's off discards the connection, otherwise not. I would like it to keep this behaviour as is. Thoughts? if (PQstatus(entry->conn) != CONNECTION_OK || PQtransactionStatus(entry->conn) != PQTRANS_IDLE || entry->changing_xact_state || entry->invalidated || +(used_in_current_xact && +(!keep_connections || !entry->keep_connection))) { elog(DEBUG3, "discarding connection %p", entry->conn); disconnect_pg_server(entry); With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/02/01 16:39, Bharath Rupireddy wrote: On Mon, Feb 1, 2021 at 12:43 PM Fujii Masao wrote: On 2021/01/27 10:06, Bharath Rupireddy wrote: On Tue, Jan 26, 2021 at 8:38 AM Bharath Rupireddy wrote: I will post "keep_connections" GUC and "keep_connection" server level option patches later. Attaching v19 patch set for "keep_connections" GUC and "keep_connection" server level option. Please review them further. These options are no longer necessary because we now support idle_session_timeout? If we want to disconnect the foreign server connections that sit on idle to prevent them from eating up the connection capacities in the foriegn servers, we can just set idle_session_timeout in those foreign servers. If we want to avoid the cluster-wide setting of idle_session_timeout, we can set that per role. One issue for this approach is that the connection entry remains even after idle_session_timeout happens. So postgres_fdw_get_connections() returns that connection even though it's actually closed by the timeout. Which is confusing. But which doesn't cause any actual problem, right? When the foreign table is accessed the next time, that connection entry is dropped, an error is detected, and then new connection will be remade. First of all, idle_session_timeout is by default 0 i.e. disabled, there are chances that users may not use that and don't want to set it just for not caching any foreign server connection. A simple use case where server level option can be useful is that, users are accessing foreign tables (may be not that frequently, once in a while) from a long running local session using foreign servers and they don't want to keep the local session cache those connections, then setting this server level option, keep_connections to false makes their life easier, without having to depend on setting idle_session_timeout on the remote server. Thanks for explaining this! I understand that use case. But I still think that we can use idle_session_timeout for that use case without keep_connections. Per the past discussion, Robert seems to prefer controling the cached connection by timeout rather than boolean, at [1]. Bruce seems to think that idle_session_timeout is enough for the use case, at [2]. So I'm not sure what the current consensus is... Also Alexey seems to have thought that idle_session_timeout is not suitable for cached connection because it's the cluster-wide option, at [3]. But since it's marked as PGC_USERSET, we can set it per-role, e.g., by using ALTER ROLE SET, so that it can affect only the foreign server connections. One merit of keep_connections that I found is that we can use it even when connecting to the older PostgreSQL that doesn't support idle_session_timeout. Also it seems simpler to use keep_connections rather than setting idle_session_timeout in multiple remote servers. So I'm inclined to add this feature, but I'd like to hear more opinions. [1] https://www.postgresql.org/message-id/CA%2BTgmob_nF7NkBfVLUhmQ%2Bt8JGVV4hXy%2BzkuMUtTSd-%3DHPBeuA%40mail.gmail.com [2] https://www.postgresql.org/message-id/20200714165822.GE7628%40momjian.us [3] https://www.postgresql.org/message-id/6df6525ca7a4b54a4a39f55e4dd6b3e9%40postgrespro.ru And, just using idle_session_timeout on a remote server may not help us completely. Because the remote session may go away, while we are still using that cached connection in an explicit txn on the local session. Our connection retry will also not work because we are in the middle of an xact, so the local explicit txn gets aborted. Regarding idle_in_transaction_session_timeout, this seems true. But I was thinking that idle_session_timeout doesn't cause this issue because it doesn't close the connection in the middle of transaction. No? So, IMO, we can still have both server level option as well as postgres_fdw contrib level GUC (to tell the local session that "I don't want to keep any foreign connections active" instead of setting keep_connection server level option for each foreign server). Sorry I've not read the past long discussion about this feature. If there is the consensus that these options are still necessary and useful even when we have idle_session_timeout, please correct me. ISTM that it's intuitive (at least for me) to add this kind of option into the foreign server. But I'm not sure if it's good idea to expose the option as GUC. Also if there is the consensus about this, please correct me. See here [1]. [1] - https://www.postgresql.org/message-id/f58d1df4ae58f6cf3bfa560f923462e0%40postgrespro.ru Thanks! Here are some review comments. - (used_in_current_xact && !keep_connections)) + (used_in_current_xact && + (!keep_connections || !entry->keep_connection))) The names of GUC and server-level option should be the same, to make the thing less confusing? IMO the server-level option should override GUC. IOW, GUC setting should
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/02/01 16:13, Bharath Rupireddy wrote: On Mon, Feb 1, 2021 at 12:29 PM Fujii Masao wrote: On 2021/01/30 9:28, Bharath Rupireddy wrote: On Sat, Jan 30, 2021 at 12:14 AM Fujii Masao wrote: + /* +* It doesn't make sense to show this entry in the output with a +* NULL server_name as it will be closed at the xact end. +*/ + continue; -1 with this change because I still think that it's more useful to list all the open connections. If postgres_fdw_get_connections doesn't have a "valid" column, then I thought it's better not showing server_name NULL in the output. Or if we don't have strong reason to remove "valid" column, the current design is enough? My only worry was that the statement from [1] "A cache flush should not cause user-visible state changes." If we follow this strictly, I'm afraid that postgres_fdw_get_connections() itself would also be a problem because the cached connections are affected by cache flush and postgres_fdw_get_connections() shows that to users. I'm not sure if removing "valid" column is actually helpful for that statement. Anyway, for now we have the following options; (1) keep the feature as it is (2) remove "valid" column (2-1) show NULL for the connection whose server was dropped (2-2) show fixed value (e.g., ) for the connection whose server was dropped (3) remove "valid" column and don't display connection whose server was dropped (4) remove postgres_fdw_get_connections() For now I like (1), but if others think "valid" column should be dropped, I'm fine with (2). But I'd like to avoid (3) because I think that postgres_fdw_get_connections() should list all the connections that are actually being established. I have no strong opinion about whether (2-1) or (2-2) is better, for now. But the newly added function postgres_fdw_get_connections is VOLATILE which means that the results returned by postgres_fdw_get_connections() is also VOLATILE. Isn't this enough, so that users will not get surprised with different results in case invalidations occur within the server by the time they run the query subsequent times and see different results than what they saw in the first run? I'm not sure about this... Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Mon, Feb 1, 2021 at 12:43 PM Fujii Masao wrote: > On 2021/01/27 10:06, Bharath Rupireddy wrote: > > On Tue, Jan 26, 2021 at 8:38 AM Bharath Rupireddy > > wrote: > >> I will post "keep_connections" GUC and "keep_connection" server level > >> option patches later. > > > > Attaching v19 patch set for "keep_connections" GUC and > > "keep_connection" server level option. Please review them further. > > These options are no longer necessary because we now support > idle_session_timeout? If we want to disconnect the foreign server connections > that sit on idle to prevent them from eating up the connection capacities in > the foriegn servers, we can just set idle_session_timeout in those foreign > servers. If we want to avoid the cluster-wide setting of > idle_session_timeout, we can set that per role. One issue for this approach > is that the connection entry remains even after idle_session_timeout happens. > So postgres_fdw_get_connections() returns that connection even though it's > actually closed by the timeout. Which is confusing. But which doesn't cause > any actual problem, right? When the foreign table is accessed the next time, > that connection entry is dropped, an error is detected, and then new > connection will be remade. First of all, idle_session_timeout is by default 0 i.e. disabled, there are chances that users may not use that and don't want to set it just for not caching any foreign server connection. A simple use case where server level option can be useful is that, users are accessing foreign tables (may be not that frequently, once in a while) from a long running local session using foreign servers and they don't want to keep the local session cache those connections, then setting this server level option, keep_connections to false makes their life easier, without having to depend on setting idle_session_timeout on the remote server. And, just using idle_session_timeout on a remote server may not help us completely. Because the remote session may go away, while we are still using that cached connection in an explicit txn on the local session. Our connection retry will also not work because we are in the middle of an xact, so the local explicit txn gets aborted. So, IMO, we can still have both server level option as well as postgres_fdw contrib level GUC (to tell the local session that "I don't want to keep any foreign connections active" instead of setting keep_connection server level option for each foreign server). > Sorry I've not read the past long discussion about this feature. If there is > the consensus that these options are still necessary and useful even when we > have idle_session_timeout, please correct me. > > ISTM that it's intuitive (at least for me) to add this kind of option into > the foreign server. But I'm not sure if it's good idea to expose the option > as GUC. Also if there is the consensus about this, please correct me. See here [1]. [1] - https://www.postgresql.org/message-id/f58d1df4ae58f6cf3bfa560f923462e0%40postgrespro.ru With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Mon, Feb 1, 2021 at 12:29 PM Fujii Masao wrote: > On 2021/01/30 9:28, Bharath Rupireddy wrote: > > On Sat, Jan 30, 2021 at 12:14 AM Fujii Masao > > wrote: > >> + /* > >> +* It doesn't make sense to show this entry in the > >> output with a > >> +* NULL server_name as it will be closed at the > >> xact end. > >> +*/ > >> + continue; > >> > >> -1 with this change because I still think that it's more useful to list > >> all the open connections. > > > > If postgres_fdw_get_connections doesn't have a "valid" column, then I > > thought it's better not showing server_name NULL in the output. > > Or if we don't have strong reason to remove "valid" column, > the current design is enough? My only worry was that the statement from [1] "A cache flush should not cause user-visible state changes." But the newly added function postgres_fdw_get_connections is VOLATILE which means that the results returned by postgres_fdw_get_connections() is also VOLATILE. Isn't this enough, so that users will not get surprised with different results in case invalidations occur within the server by the time they run the query subsequent times and see different results than what they saw in the first run? Thoughts? [1] https://www.postgresql.org/message-id/flat/2724627.1611886184%40sss.pgh.pa.us With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/27 10:06, Bharath Rupireddy wrote: On Tue, Jan 26, 2021 at 8:38 AM Bharath Rupireddy wrote: I will post "keep_connections" GUC and "keep_connection" server level option patches later. Attaching v19 patch set for "keep_connections" GUC and "keep_connection" server level option. Please review them further. These options are no longer necessary because we now support idle_session_timeout? If we want to disconnect the foreign server connections that sit on idle to prevent them from eating up the connection capacities in the foriegn servers, we can just set idle_session_timeout in those foreign servers. If we want to avoid the cluster-wide setting of idle_session_timeout, we can set that per role. One issue for this approach is that the connection entry remains even after idle_session_timeout happens. So postgres_fdw_get_connections() returns that connection even though it's actually closed by the timeout. Which is confusing. But which doesn't cause any actual problem, right? When the foreign table is accessed the next time, that connection entry is dropped, an error is detected, and then new connection will be remade. Sorry I've not read the past long discussion about this feature. If there is the consensus that these options are still necessary and useful even when we have idle_session_timeout, please correct me. ISTM that it's intuitive (at least for me) to add this kind of option into the foreign server. But I'm not sure if it's good idea to expose the option as GUC. Also if there is the consensus about this, please correct me. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/30 9:28, Bharath Rupireddy wrote: On Sat, Jan 30, 2021 at 12:14 AM Fujii Masao wrote: + /* +* It doesn't make sense to show this entry in the output with a +* NULL server_name as it will be closed at the xact end. +*/ + continue; -1 with this change because I still think that it's more useful to list all the open connections. If postgres_fdw_get_connections doesn't have a "valid" column, then I thought it's better not showing server_name NULL in the output. Or if we don't have strong reason to remove "valid" column, the current design is enough? Do you think that we need to output some fixed strings for such connections like "" or "" or "" or ""? I'm not sure whether we are allowed to have fixed strings as column output. This makes me think that more discussion would be necessary before changing the interface of postgres_fdw_get_connections(). On the other hand, we should address the issue ASAP to make the buildfarm member fine. So at first I'd like to push only the change of regression test. Patch attached. I tested it both with CLOBBER_CACHE_ALWAYS set and unset, and the results were stable. Thanks, the postgres_fdw.patch looks good to me. Thanks for checking the patch! I pushed that. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Sat, Jan 30, 2021 at 12:14 AM Fujii Masao wrote: > + /* > +* It doesn't make sense to show this entry in the > output with a > +* NULL server_name as it will be closed at the xact > end. > +*/ > + continue; > > -1 with this change because I still think that it's more useful to list > all the open connections. If postgres_fdw_get_connections doesn't have a "valid" column, then I thought it's better not showing server_name NULL in the output. Do you think that we need to output some fixed strings for such connections like "" or "" or "" or ""? I'm not sure whether we are allowed to have fixed strings as column output. > This makes me think that more discussion would be necessary before > changing the interface of postgres_fdw_get_connections(). On the other > hand, we should address the issue ASAP to make the buildfarm member fine. > So at first I'd like to push only the change of regression test. > Patch attached. I tested it both with CLOBBER_CACHE_ALWAYS set and unset, > and the results were stable. Thanks, the postgres_fdw.patch looks good to me. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/29 19:45, Bharath Rupireddy wrote: On Fri, Jan 29, 2021 at 1:24 PM Bharath Rupireddy wrote: On Fri, Jan 29, 2021 at 1:17 PM Fujii Masao wrote: But if the issue is only the inconsistency of test results, we can go with the option (2)? Even with (2), we can make the test stable by removing "valid" column and executing postgres_fdw_get_connections() within the transaction? Hmmm, and we should have the tests at the start of the file postgres_fdw.sql before even we make any foreign server connections. We don't need to move the test if we always call postgres_fdw_disconnect_all() just before starting new transaction and calling postgres_fdw_get_connections() as follows? SELECT 1 FROM postgres_fdw_disconnect_all(); BEGIN; ... SELECT * FROM postgres_fdw_get_connections(); ... Yes, that works, but we cannot show true/false for the postgres_fdw_disconnect_all output. I will post the patch soon. Thanks a lot. Attaching a patch that has following changes: 1) Now, postgres_fdw_get_connections will only return set of active connections server names not their valid state 2) The functions postgres_fdw_get_connections, postgres_fdw_disconnect and postgres_fdw_disconnect_all are now being tested within an explicit xact block, this way the tests are more stable even with clobber cache always builds. I tested the patch here on my development system with -DCLOBBER_CACHE_ALWAYS configuration, the tests look consistent. Please review the patch. Thanks for the patch! --- Return false as loopback2 connectin is closed already. -SELECT postgres_fdw_disconnect('loopback2'); - postgres_fdw_disconnect -- - f -(1 row) - --- Return an error as there is no foreign server with given name. -SELECT postgres_fdw_disconnect('unknownserver'); -ERROR: server "unknownserver" does not exist Why do we need to remove these? These seem to work fine even in CLOBBER_CACHE_ALWAYS. + /* +* It doesn't make sense to show this entry in the output with a +* NULL server_name as it will be closed at the xact end. +*/ + continue; -1 with this change because I still think that it's more useful to list all the open connections. This makes me think that more discussion would be necessary before changing the interface of postgres_fdw_get_connections(). On the other hand, we should address the issue ASAP to make the buildfarm member fine. So at first I'd like to push only the change of regression test. Patch attached. I tested it both with CLOBBER_CACHE_ALWAYS set and unset, and the results were stable. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 07e06e5bf7..b09dce63f5 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -17,10 +17,6 @@ DO $d$ OPTIONS (dbname '$$||current_database()||$$', port '$$||current_setting('port')||$$' )$$; -EXECUTE $$CREATE SERVER loopback4 FOREIGN DATA WRAPPER postgres_fdw -OPTIONS (dbname '$$||current_database()||$$', - port '$$||current_setting('port')||$$' -)$$; END; $d$; CREATE USER MAPPING FOR public SERVER testserver1 @@ -28,7 +24,6 @@ CREATE USER MAPPING FOR public SERVER testserver1 CREATE USER MAPPING FOR CURRENT_USER SERVER loopback; CREATE USER MAPPING FOR CURRENT_USER SERVER loopback2; CREATE USER MAPPING FOR public SERVER loopback3; -CREATE USER MAPPING FOR public SERVER loopback4; -- === -- create objects used through FDW loopback server -- === @@ -144,11 +139,6 @@ CREATE FOREIGN TABLE ft7 ( c2 int NOT NULL, c3 text ) SERVER loopback3 OPTIONS (schema_name 'S 1', table_name 'T 4'); -CREATE FOREIGN TABLE ft8 ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text -) SERVER loopback4 OPTIONS (schema_name 'S 1', table_name 'T 4'); -- === -- tests for validator -- === @@ -220,8 +210,7 @@ ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); public | ft5 | loopback | (schema_name 'S 1', table_name 'T 4') | public | ft6 | loopback2 | (schema_name 'S 1', table_name 'T 4') | public | ft7 | loopback3 | (schema_name 'S 1', table_name 'T 4') | - public | ft8 | loopback4 | (schema_name 'S 1', table_name 'T 4') | -(7 rows) +(6 rows) -- Test that alteration of server options causes reconnection -- Remote's errors might be non-English, so hide them to ensure stable results @@ -
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 29, 2021 at 1:24 PM Bharath Rupireddy wrote: > > On Fri, Jan 29, 2021 at 1:17 PM Fujii Masao > wrote: > > >> But if the issue is only the inconsistency of test results, > > >> we can go with the option (2)? Even with (2), we can make the test > > >> stable by removing "valid" column and executing > > >> postgres_fdw_get_connections() within the transaction? > > > > > > Hmmm, and we should have the tests at the start of the file > > > postgres_fdw.sql before even we make any foreign server connections. > > > > We don't need to move the test if we always call > > postgres_fdw_disconnect_all() just before starting new transaction and > > calling postgres_fdw_get_connections() as follows? > > > > SELECT 1 FROM postgres_fdw_disconnect_all(); > > BEGIN; > > ... > > SELECT * FROM postgres_fdw_get_connections(); > > ... > > Yes, that works, but we cannot show true/false for the > postgres_fdw_disconnect_all output. > > I will post the patch soon. Thanks a lot. Attaching a patch that has following changes: 1) Now, postgres_fdw_get_connections will only return set of active connections server names not their valid state 2) The functions postgres_fdw_get_connections, postgres_fdw_disconnect and postgres_fdw_disconnect_all are now being tested within an explicit xact block, this way the tests are more stable even with clobber cache always builds. I tested the patch here on my development system with -DCLOBBER_CACHE_ALWAYS configuration, the tests look consistent. Please review the patch. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v1-0001-Don-t-return-valid-state-in-postgres_fdw_get_conn.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 29, 2021 at 1:17 PM Fujii Masao wrote: > >> But if the issue is only the inconsistency of test results, > >> we can go with the option (2)? Even with (2), we can make the test > >> stable by removing "valid" column and executing > >> postgres_fdw_get_connections() within the transaction? > > > > Hmmm, and we should have the tests at the start of the file > > postgres_fdw.sql before even we make any foreign server connections. > > We don't need to move the test if we always call > postgres_fdw_disconnect_all() just before starting new transaction and > calling postgres_fdw_get_connections() as follows? > > SELECT 1 FROM postgres_fdw_disconnect_all(); > BEGIN; > ... > SELECT * FROM postgres_fdw_get_connections(); > ... Yes, that works, but we cannot show true/false for the postgres_fdw_disconnect_all output. I will post the patch soon. Thanks a lot. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/29 16:12, Bharath Rupireddy wrote: On Fri, Jan 29, 2021 at 12:36 PM Fujii Masao wrote: On 2021/01/29 15:44, Bharath Rupireddy wrote: On Fri, Jan 29, 2021 at 11:54 AM Fujii Masao wrote: IIRC, when we were finding a way to close the invalidated connections so that they don't leaked, we had two options: 1) let those connections (whether currently being used in the xact or not) get marked invalidated in pgfdw_inval_callback and closed in pgfdw_xact_callback at the main txn end as shown below if (PQstatus(entry->conn) != CONNECTION_OK || PQtransactionStatus(entry->conn) != PQTRANS_IDLE || entry->changing_xact_state || entry->invalidated). > by adding this { elog(DEBUG3, "discarding connection %p", entry->conn); disconnect_pg_server(entry); } 2) close the unused connections right away in pgfdw_inval_callback instead of marking them invalidated. Mark used connections as invalidated in pgfdw_inval_callback and close them in pgfdw_xact_callback at the main txn end. We went with option (2) because we thought this would ease some burden on pgfdw_xact_callback closing a lot of invalid connections at once. Also, see the original patch for the connection leak issue just does option (1), see [1]. But in [2] and [3], we chose option (2). I feel, we can go for option (1), with the patch attached in [1] i.e. having have_invalid_connections whenever any connection gets invalided so that we don't quickly exit in pgfdw_xact_callback and the invalidated connections get closed properly. Thoughts? Before going for (1) or something, I'd like to understand what the actual issue of (2), i.e., the current code is. Otherwise other approaches might have the same issue. The problem with option (2) is that because of CLOBBER_CACHE_ALWAYS, pgfdw_inval_callback is getting called many times and the connections that are not used i..e xact_depth == 0, are getting disconnected there, so we are not seeing the consistent results for postgres_fdw_get_connectionstest cases. If the connections are being used within the xact, then the valid option for those connections are being shown as false again making postgres_fdw_get_connections output inconsistent. This is what happened on the build farm member with CLOBBER_CACHE_ALWAYS build. But if the issue is only the inconsistency of test results, we can go with the option (2)? Even with (2), we can make the test stable by removing "valid" column and executing postgres_fdw_get_connections() within the transaction? Hmmm, and we should have the tests at the start of the file postgres_fdw.sql before even we make any foreign server connections. We don't need to move the test if we always call postgres_fdw_disconnect_all() just before starting new transaction and calling postgres_fdw_get_connections() as follows? SELECT 1 FROM postgres_fdw_disconnect_all(); BEGIN; ... SELECT * FROM postgres_fdw_get_connections(); ... If okay, I can prepare the patch and run with clobber cache build locally. Many thanks! So if we go with option (1), get rid of valid state from postgres_fdw_get_connectionstest and having the test cases inside an explicit xact block at the beginning of the postgres_fdw.sql test file, we don't see CLOBBER_CACHE_ALWAYS inconsistencies. I'm not sure if this is the correct way. Regarding (1), as far as I understand correctly, even when the transaction doesn't use foreign tables at all, it needs to scan the connection cache entries if necessary. I was thinking to avoid this. I guess that this doesn't work with at least the postgres_fdw 2PC patch that Sawada-san is proposing because with the patch the commit/rollback callback is performed only for the connections used in the transaction. You mean to say, pgfdw_xact_callback will not get called when the xact uses no foreign server connection or is it that pgfdw_xact_callback gets called but exits quickly from it? I'm not sure what the 2PC patch does. Maybe it's chance to review the patch! ;P BTW his patch tries to add new callback interfaces for commit/rollback of foreign transactions, and make postgres_fdw use them instead of XactCallback. And those new interfaces are executed only when the transaction has started the foreign transactions. IMHO, it's better to keep it as a separate discussion. Yes, of course! Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 29, 2021 at 12:36 PM Fujii Masao wrote: > On 2021/01/29 15:44, Bharath Rupireddy wrote: > > On Fri, Jan 29, 2021 at 11:54 AM Fujii Masao > > wrote: > IIRC, when we were finding a way to close the invalidated connections > so that they don't leaked, we had two options: > > 1) let those connections (whether currently being used in the xact or > not) get marked invalidated in pgfdw_inval_callback and closed in > pgfdw_xact_callback at the main txn end as shown below > > if (PQstatus(entry->conn) != CONNECTION_OK || > PQtransactionStatus(entry->conn) != PQTRANS_IDLE || > entry->changing_xact_state || > entry->invalidated). > by adding this > { > elog(DEBUG3, "discarding connection %p", entry->conn); > disconnect_pg_server(entry); > } > > 2) close the unused connections right away in pgfdw_inval_callback > instead of marking them invalidated. Mark used connections as > invalidated in pgfdw_inval_callback and close them in > pgfdw_xact_callback at the main txn end. > > We went with option (2) because we thought this would ease some burden > on pgfdw_xact_callback closing a lot of invalid connections at once. > >>> > >>> Also, see the original patch for the connection leak issue just does > >>> option (1), see [1]. But in [2] and [3], we chose option (2). > >>> > >>> I feel, we can go for option (1), with the patch attached in [1] i.e. > >>> having have_invalid_connections whenever any connection gets invalided > >>> so that we don't quickly exit in pgfdw_xact_callback and the > >>> invalidated connections get closed properly. Thoughts? > >> > >> Before going for (1) or something, I'd like to understand what the actual > >> issue of (2), i.e., the current code is. Otherwise other approaches might > >> have the same issue. > > > > The problem with option (2) is that because of CLOBBER_CACHE_ALWAYS, > > pgfdw_inval_callback is getting called many times and the connections > > that are not used i..e xact_depth == 0, are getting disconnected > > there, so we are not seeing the consistent results for > > postgres_fdw_get_connectionstest cases. If the connections are being > > used within the xact, then the valid option for those connections are > > being shown as false again making postgres_fdw_get_connections output > > inconsistent. This is what happened on the build farm member with > > CLOBBER_CACHE_ALWAYS build. > > But if the issue is only the inconsistency of test results, > we can go with the option (2)? Even with (2), we can make the test > stable by removing "valid" column and executing > postgres_fdw_get_connections() within the transaction? Hmmm, and we should have the tests at the start of the file postgres_fdw.sql before even we make any foreign server connections. If okay, I can prepare the patch and run with clobber cache build locally. > > > > So if we go with option (1), get rid of valid state from > > postgres_fdw_get_connectionstest and having the test cases inside an > > explicit xact block at the beginning of the postgres_fdw.sql test > > file, we don't see CLOBBER_CACHE_ALWAYS inconsistencies. I'm not sure > > if this is the correct way. > > > >> Regarding (1), as far as I understand correctly, even when the transaction > >> doesn't use foreign tables at all, it needs to scan the connection cache > >> entries if necessary. I was thinking to avoid this. I guess that this > >> doesn't > >> work with at least the postgres_fdw 2PC patch that Sawada-san is proposing > >> because with the patch the commit/rollback callback is performed only > >> for the connections used in the transaction. > > > > You mean to say, pgfdw_xact_callback will not get called when the xact > > uses no foreign server connection or is it that pgfdw_xact_callback > > gets called but exits quickly from it? I'm not sure what the 2PC patch > > does. > > Maybe it's chance to review the patch! ;P > > BTW his patch tries to add new callback interfaces for commit/rollback of > foreign transactions, and make postgres_fdw use them instead of > XactCallback. And those new interfaces are executed only when > the transaction has started the foreign transactions. IMHO, it's better to keep it as a separate discussion. I will try to review that patch later. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/29 15:44, Bharath Rupireddy wrote: On Fri, Jan 29, 2021 at 11:54 AM Fujii Masao wrote: IIRC, when we were finding a way to close the invalidated connections so that they don't leaked, we had two options: 1) let those connections (whether currently being used in the xact or not) get marked invalidated in pgfdw_inval_callback and closed in pgfdw_xact_callback at the main txn end as shown below if (PQstatus(entry->conn) != CONNECTION_OK || PQtransactionStatus(entry->conn) != PQTRANS_IDLE || entry->changing_xact_state || entry->invalidated). > by adding this { elog(DEBUG3, "discarding connection %p", entry->conn); disconnect_pg_server(entry); } 2) close the unused connections right away in pgfdw_inval_callback instead of marking them invalidated. Mark used connections as invalidated in pgfdw_inval_callback and close them in pgfdw_xact_callback at the main txn end. We went with option (2) because we thought this would ease some burden on pgfdw_xact_callback closing a lot of invalid connections at once. Also, see the original patch for the connection leak issue just does option (1), see [1]. But in [2] and [3], we chose option (2). I feel, we can go for option (1), with the patch attached in [1] i.e. having have_invalid_connections whenever any connection gets invalided so that we don't quickly exit in pgfdw_xact_callback and the invalidated connections get closed properly. Thoughts? Before going for (1) or something, I'd like to understand what the actual issue of (2), i.e., the current code is. Otherwise other approaches might have the same issue. The problem with option (2) is that because of CLOBBER_CACHE_ALWAYS, pgfdw_inval_callback is getting called many times and the connections that are not used i..e xact_depth == 0, are getting disconnected there, so we are not seeing the consistent results for postgres_fdw_get_connectionstest cases. If the connections are being used within the xact, then the valid option for those connections are being shown as false again making postgres_fdw_get_connections output inconsistent. This is what happened on the build farm member with CLOBBER_CACHE_ALWAYS build. But if the issue is only the inconsistency of test results, we can go with the option (2)? Even with (2), we can make the test stable by removing "valid" column and executing postgres_fdw_get_connections() within the transaction? So if we go with option (1), get rid of valid state from postgres_fdw_get_connectionstest and having the test cases inside an explicit xact block at the beginning of the postgres_fdw.sql test file, we don't see CLOBBER_CACHE_ALWAYS inconsistencies. I'm not sure if this is the correct way. Regarding (1), as far as I understand correctly, even when the transaction doesn't use foreign tables at all, it needs to scan the connection cache entries if necessary. I was thinking to avoid this. I guess that this doesn't work with at least the postgres_fdw 2PC patch that Sawada-san is proposing because with the patch the commit/rollback callback is performed only for the connections used in the transaction. You mean to say, pgfdw_xact_callback will not get called when the xact uses no foreign server connection or is it that pgfdw_xact_callback gets called but exits quickly from it? I'm not sure what the 2PC patch does. Maybe it's chance to review the patch! ;P BTW his patch tries to add new callback interfaces for commit/rollback of foreign transactions, and make postgres_fdw use them instead of XactCallback. And those new interfaces are executed only when the transaction has started the foreign transactions. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 29, 2021 at 11:54 AM Fujii Masao wrote: > >> IIRC, when we were finding a way to close the invalidated connections > >> so that they don't leaked, we had two options: > >> > >> 1) let those connections (whether currently being used in the xact or > >> not) get marked invalidated in pgfdw_inval_callback and closed in > >> pgfdw_xact_callback at the main txn end as shown below > >> > >> if (PQstatus(entry->conn) != CONNECTION_OK || > >> PQtransactionStatus(entry->conn) != PQTRANS_IDLE || > >> entry->changing_xact_state || > >> entry->invalidated). > by adding this > >> { > >> elog(DEBUG3, "discarding connection %p", entry->conn); > >> disconnect_pg_server(entry); > >> } > >> > >> 2) close the unused connections right away in pgfdw_inval_callback > >> instead of marking them invalidated. Mark used connections as > >> invalidated in pgfdw_inval_callback and close them in > >> pgfdw_xact_callback at the main txn end. > >> > >> We went with option (2) because we thought this would ease some burden > >> on pgfdw_xact_callback closing a lot of invalid connections at once. > > > > Also, see the original patch for the connection leak issue just does > > option (1), see [1]. But in [2] and [3], we chose option (2). > > > > I feel, we can go for option (1), with the patch attached in [1] i.e. > > having have_invalid_connections whenever any connection gets invalided > > so that we don't quickly exit in pgfdw_xact_callback and the > > invalidated connections get closed properly. Thoughts? > > Before going for (1) or something, I'd like to understand what the actual > issue of (2), i.e., the current code is. Otherwise other approaches might > have the same issue. The problem with option (2) is that because of CLOBBER_CACHE_ALWAYS, pgfdw_inval_callback is getting called many times and the connections that are not used i..e xact_depth == 0, are getting disconnected there, so we are not seeing the consistent results for postgres_fdw_get_connectionstest cases. If the connections are being used within the xact, then the valid option for those connections are being shown as false again making postgres_fdw_get_connections output inconsistent. This is what happened on the build farm member with CLOBBER_CACHE_ALWAYS build. So if we go with option (1), get rid of valid state from postgres_fdw_get_connectionstest and having the test cases inside an explicit xact block at the beginning of the postgres_fdw.sql test file, we don't see CLOBBER_CACHE_ALWAYS inconsistencies. I'm not sure if this is the correct way. > Regarding (1), as far as I understand correctly, even when the transaction > doesn't use foreign tables at all, it needs to scan the connection cache > entries if necessary. I was thinking to avoid this. I guess that this doesn't > work with at least the postgres_fdw 2PC patch that Sawada-san is proposing > because with the patch the commit/rollback callback is performed only > for the connections used in the transaction. You mean to say, pgfdw_xact_callback will not get called when the xact uses no foreign server connection or is it that pgfdw_xact_callback gets called but exits quickly from it? I'm not sure what the 2PC patch does. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/29 14:46, Bharath Rupireddy wrote: On Fri, Jan 29, 2021 at 11:08 AM Bharath Rupireddy wrote: On Fri, Jan 29, 2021 at 10:55 AM Fujii Masao wrote: On 2021/01/29 14:12, Bharath Rupireddy wrote: On Fri, Jan 29, 2021 at 10:28 AM Fujii Masao wrote: On 2021/01/29 11:09, Tom Lane wrote: Bharath Rupireddy writes: On Fri, Jan 29, 2021 at 1:52 AM Tom Lane wrote: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=trilobite&dt=2021-01-26%2019%3A59%3A40 This is a CLOBBER_CACHE_ALWAYS build, so I suspect what it's telling us is that the patch's behavior is unstable in the face of unexpected cache flushes. Thanks a lot! It looks like the syscache invalidation messages are generated too frequently with -DCLOBBER_CACHE_ALWAYS build due to which pgfdw_inval_callback gets called many times in which the cached entries are marked as invalid and closed if they are not used in the txn. The new function postgres_fdw_get_connections outputs the information of the cached connections such as name if the connection is still open and their validity. Hence the output of the postgres_fdw_get_connections became unstable in the buildfarm member. I will further analyze making tests stable, meanwhile any suggestions are welcome. I do not think you should regard this as "we need to hack the test to make it stable". I think you should regard this as "this is a bug". A cache flush should not cause user-visible state changes. In particular, the above analysis implies that you think a cache flush is equivalent to end-of-transaction, which it absolutely is not. Also, now that I've looked at pgfdw_inval_callback, it scares the heck out of me. Actually disconnecting a connection during a cache inval callback seems quite unsafe --- what if that happens while we're using the connection? If the connection is still used in the transaction, pgfdw_inval_callback() marks it as invalidated and doesn't close it. So I was not thinking that this is so unsafe. The disconnection code in pgfdw_inval_callback() was added in commit e3ebcca843 to fix connection leak issue, and it's back-patched. If this change is really unsafe, we need to revert it immediately at least from back branches because the next minor release is scheduled soon. I think we can remove disconnect_pg_server in pgfdw_inval_callback and make entries only invalidated. Anyways, those connections can get closed at the end of main txn in pgfdw_xact_callback. Thoughts? But this revives the connection leak issue. So isn't it better to to do that after we confirm that the current code is really unsafe? IMO, connections will not leak, because the invalidated connections eventually will get closed in pgfdw_xact_callback at the main txn end. IIRC, when we were finding a way to close the invalidated connections so that they don't leaked, we had two options: 1) let those connections (whether currently being used in the xact or not) get marked invalidated in pgfdw_inval_callback and closed in pgfdw_xact_callback at the main txn end as shown below if (PQstatus(entry->conn) != CONNECTION_OK || PQtransactionStatus(entry->conn) != PQTRANS_IDLE || entry->changing_xact_state || entry->invalidated). > by adding this { elog(DEBUG3, "discarding connection %p", entry->conn); disconnect_pg_server(entry); } 2) close the unused connections right away in pgfdw_inval_callback instead of marking them invalidated. Mark used connections as invalidated in pgfdw_inval_callback and close them in pgfdw_xact_callback at the main txn end. We went with option (2) because we thought this would ease some burden on pgfdw_xact_callback closing a lot of invalid connections at once. Also, see the original patch for the connection leak issue just does option (1), see [1]. But in [2] and [3], we chose option (2). I feel, we can go for option (1), with the patch attached in [1] i.e. having have_invalid_connections whenever any connection gets invalided so that we don't quickly exit in pgfdw_xact_callback and the invalidated connections get closed properly. Thoughts? Before going for (1) or something, I'd like to understand what the actual issue of (2), i.e., the current code is. Otherwise other approaches might have the same issue. Regarding (1), as far as I understand correctly, even when the transaction doesn't use foreign tables at all, it needs to scan the connection cache entries if necessary. I was thinking to avoid this. I guess that this doesn't work with at least the postgres_fdw 2PC patch that Sawada-san is proposing because with the patch the commit/rollback callback is performed only for the connections used in the transaction. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 29, 2021 at 11:38 AM Fujii Masao wrote: > On 2021/01/29 14:53, Bharath Rupireddy wrote: > > On Fri, Jan 29, 2021 at 10:55 AM Fujii Masao > > wrote: > BTW, even if we change pgfdw_inval_callback() so that it doesn't close > the connection at all, ISTM that the results of > postgres_fdw_get_connections() > would not be stable because entry->invalidated would vary based on > whether CLOBBER_CACHE_ALWAYS is used or not. > >>> > >>> Yes, after the above change (removing disconnect_pg_server in > >>> pgfdw_inval_callback), our tests don't get stable because > >>> postgres_fdw_get_connections shows the valid state of the connections. > >>> I think we can change postgres_fdw_get_connections so that it only > >>> shows the active connections server name but not valid state. Because, > >>> the valid state is something dependent on the internal state change > >>> and is not consistent with the user expectation but we are exposing it > >>> to the user. Thoughts? > >> > >> I don't think that's enough because even the following simple > >> queries return the different results, depending on whether > >> CLOBBER_CACHE_ALWAYS is used or not. > >> > >> SELECT * FROM ft6; -- ft6 is the foreign table > >> SELECT server_name FROM postgres_fdw_get_connections(); > >> > >> When CLOBBER_CACHE_ALWAYS is used, postgres_fdw_get_connections() > >> returns no records because the connection is marked as invalidated, > >> and then closed at xact callback in SELECT query. Otherwise, > >> postgres_fdw_get_connections() returns at least one connection that > >> was established in the SELECT query. > > > > Right. In that case, after changing postgres_fdw_get_connections() so > > that it doesn't output the valid state of the connections at all, we > > You're thinking to get rid of "valid" column? Or hide it from the test query > (e.g., SELECT server_name from postgres_fdw_get_connections())? I'm thinking we can get rid of the "valid" column from the postgres_fdw_get_connections() function, not from the tests. Seems like we are exposing some internal state(connection is valid or not) which can change because of internal events. And also with the existing postgres_fdw_get_connections(), the valid will always be true if the user calls postgres_fdw_get_connections() outside an explicit xact block, it can become false only when it's used in an explicit txn block. So, the valid column may not be much useful for the user. Thoughts? > > can have all the new function test cases inside an explicit txn block. > > So even if the clobber cache invalidates the connections, they don't > > get closed until the end of main xact, the tests will be stable. > > Thoughts? > > Also if there are cached connections before starting that transaction, > they should be closed or established again before executing > postgres_fdw_get_connections(). Otherwise, those connections are > returned from postgres_fdw_get_connections() when > CLOBBER_CACHE_ALWAYS is not used, but not when it's used. Yes, we need to move the test to the place where cache wouldn't have been initialized yet or no foreign connection has been made yet in the session. ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); \det+ <<<>>> -- Test that alteration of server options causes reconnection -- Remote's errors might be non-English, so hide them to ensure stable results \set VERBOSITY terse SELECT c3, c4 FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work ALTER SERVER loopback OPTIONS (SET dbname 'no such database'); SELECT c3, c4 FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should fail DO $d$ With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/29 14:53, Bharath Rupireddy wrote: On Fri, Jan 29, 2021 at 10:55 AM Fujii Masao wrote: BTW, even if we change pgfdw_inval_callback() so that it doesn't close the connection at all, ISTM that the results of postgres_fdw_get_connections() would not be stable because entry->invalidated would vary based on whether CLOBBER_CACHE_ALWAYS is used or not. Yes, after the above change (removing disconnect_pg_server in pgfdw_inval_callback), our tests don't get stable because postgres_fdw_get_connections shows the valid state of the connections. I think we can change postgres_fdw_get_connections so that it only shows the active connections server name but not valid state. Because, the valid state is something dependent on the internal state change and is not consistent with the user expectation but we are exposing it to the user. Thoughts? I don't think that's enough because even the following simple queries return the different results, depending on whether CLOBBER_CACHE_ALWAYS is used or not. SELECT * FROM ft6; -- ft6 is the foreign table SELECT server_name FROM postgres_fdw_get_connections(); When CLOBBER_CACHE_ALWAYS is used, postgres_fdw_get_connections() returns no records because the connection is marked as invalidated, and then closed at xact callback in SELECT query. Otherwise, postgres_fdw_get_connections() returns at least one connection that was established in the SELECT query. Right. In that case, after changing postgres_fdw_get_connections() so that it doesn't output the valid state of the connections at all, we You're thinking to get rid of "valid" column? Or hide it from the test query (e.g., SELECT server_name from postgres_fdw_get_connections())? can have all the new function test cases inside an explicit txn block. So even if the clobber cache invalidates the connections, they don't get closed until the end of main xact, the tests will be stable. Thoughts? Also if there are cached connections before starting that transaction, they should be closed or established again before executing postgres_fdw_get_connections(). Otherwise, those connections are returned from postgres_fdw_get_connections() when CLOBBER_CACHE_ALWAYS is not used, but not when it's used. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 29, 2021 at 10:55 AM Fujii Masao wrote: > >> BTW, even if we change pgfdw_inval_callback() so that it doesn't close > >> the connection at all, ISTM that the results of > >> postgres_fdw_get_connections() > >> would not be stable because entry->invalidated would vary based on > >> whether CLOBBER_CACHE_ALWAYS is used or not. > > > > Yes, after the above change (removing disconnect_pg_server in > > pgfdw_inval_callback), our tests don't get stable because > > postgres_fdw_get_connections shows the valid state of the connections. > > I think we can change postgres_fdw_get_connections so that it only > > shows the active connections server name but not valid state. Because, > > the valid state is something dependent on the internal state change > > and is not consistent with the user expectation but we are exposing it > > to the user. Thoughts? > > I don't think that's enough because even the following simple > queries return the different results, depending on whether > CLOBBER_CACHE_ALWAYS is used or not. > > SELECT * FROM ft6; -- ft6 is the foreign table > SELECT server_name FROM postgres_fdw_get_connections(); > > When CLOBBER_CACHE_ALWAYS is used, postgres_fdw_get_connections() > returns no records because the connection is marked as invalidated, > and then closed at xact callback in SELECT query. Otherwise, > postgres_fdw_get_connections() returns at least one connection that > was established in the SELECT query. Right. In that case, after changing postgres_fdw_get_connections() so that it doesn't output the valid state of the connections at all, we can have all the new function test cases inside an explicit txn block. So even if the clobber cache invalidates the connections, they don't get closed until the end of main xact, the tests will be stable. Thoughts? With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 29, 2021 at 11:08 AM Bharath Rupireddy wrote: > > On Fri, Jan 29, 2021 at 10:55 AM Fujii Masao > wrote: > > On 2021/01/29 14:12, Bharath Rupireddy wrote: > > > On Fri, Jan 29, 2021 at 10:28 AM Fujii Masao > > > wrote: > > >> On 2021/01/29 11:09, Tom Lane wrote: > > >>> Bharath Rupireddy writes: > > On Fri, Jan 29, 2021 at 1:52 AM Tom Lane wrote: > > > https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=trilobite&dt=2021-01-26%2019%3A59%3A40 > > > This is a CLOBBER_CACHE_ALWAYS build, so I suspect what it's > > > telling us is that the patch's behavior is unstable in the face > > > of unexpected cache flushes. > > >>> > > Thanks a lot! It looks like the syscache invalidation messages are > > generated too frequently with -DCLOBBER_CACHE_ALWAYS build due to > > which pgfdw_inval_callback gets called many times in which the cached > > entries are marked as invalid and closed if they are not used in the > > txn. The new function postgres_fdw_get_connections outputs the > > information of the cached connections such as name if the connection > > is still open and their validity. Hence the output of the > > postgres_fdw_get_connections became unstable in the buildfarm member. > > I will further analyze making tests stable, meanwhile any suggestions > > are welcome. > > >>> > > >>> I do not think you should regard this as "we need to hack the test > > >>> to make it stable". I think you should regard this as "this is a > > >>> bug". A cache flush should not cause user-visible state changes. > > >>> In particular, the above analysis implies that you think a cache > > >>> flush is equivalent to end-of-transaction, which it absolutely > > >>> is not. > > >>> > > >>> Also, now that I've looked at pgfdw_inval_callback, it scares > > >>> the heck out of me. Actually disconnecting a connection during > > >>> a cache inval callback seems quite unsafe --- what if that happens > > >>> while we're using the connection? > > >> > > >> If the connection is still used in the transaction, > > >> pgfdw_inval_callback() > > >> marks it as invalidated and doesn't close it. So I was not thinking that > > >> this is so unsafe. > > >> > > >> The disconnection code in pgfdw_inval_callback() was added in commit > > >> e3ebcca843 to fix connection leak issue, and it's back-patched. If this > > >> change is really unsafe, we need to revert it immediately at least from > > >> back > > >> branches because the next minor release is scheduled soon. > > > > > > I think we can remove disconnect_pg_server in pgfdw_inval_callback and > > > make entries only invalidated. Anyways, those connections can get > > > closed at the end of main txn in pgfdw_xact_callback. Thoughts? > > > > But this revives the connection leak issue. So isn't it better to > > to do that after we confirm that the current code is really unsafe? > > IMO, connections will not leak, because the invalidated connections > eventually will get closed in pgfdw_xact_callback at the main txn end. > > IIRC, when we were finding a way to close the invalidated connections > so that they don't leaked, we had two options: > > 1) let those connections (whether currently being used in the xact or > not) get marked invalidated in pgfdw_inval_callback and closed in > pgfdw_xact_callback at the main txn end as shown below > > if (PQstatus(entry->conn) != CONNECTION_OK || > PQtransactionStatus(entry->conn) != PQTRANS_IDLE || > entry->changing_xact_state || > entry->invalidated). > by adding this > { > elog(DEBUG3, "discarding connection %p", entry->conn); > disconnect_pg_server(entry); > } > > 2) close the unused connections right away in pgfdw_inval_callback > instead of marking them invalidated. Mark used connections as > invalidated in pgfdw_inval_callback and close them in > pgfdw_xact_callback at the main txn end. > > We went with option (2) because we thought this would ease some burden > on pgfdw_xact_callback closing a lot of invalid connections at once. Also, see the original patch for the connection leak issue just does option (1), see [1]. But in [2] and [3], we chose option (2). I feel, we can go for option (1), with the patch attached in [1] i.e. having have_invalid_connections whenever any connection gets invalided so that we don't quickly exit in pgfdw_xact_callback and the invalidated connections get closed properly. Thoughts? static void pgfdw_xact_callback(XactEvent event, void *arg) { HASH_SEQ_STATUS scan; ConnCacheEntry *entry; /* Quick exit if no connections were touched in this transaction. */ if (!xact_got_connection) return; [1] https://www.postgresql.org/message-id/CALj2ACVNcGH_6qLY-4_tXz8JLvA%2B4yeBThRfxMz7Oxbk1aHcpQ%40mail.gmail.com [2] https://www.postgresql.org/message-id/f57dd9c3-0664-5f4c-41f0-0713047ae7b7%40oss.nttdata.com [3] https://www.postgresql
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 29, 2021 at 10:55 AM Fujii Masao wrote: > On 2021/01/29 14:12, Bharath Rupireddy wrote: > > On Fri, Jan 29, 2021 at 10:28 AM Fujii Masao > > wrote: > >> On 2021/01/29 11:09, Tom Lane wrote: > >>> Bharath Rupireddy writes: > On Fri, Jan 29, 2021 at 1:52 AM Tom Lane wrote: > > https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=trilobite&dt=2021-01-26%2019%3A59%3A40 > > This is a CLOBBER_CACHE_ALWAYS build, so I suspect what it's > > telling us is that the patch's behavior is unstable in the face > > of unexpected cache flushes. > >>> > Thanks a lot! It looks like the syscache invalidation messages are > generated too frequently with -DCLOBBER_CACHE_ALWAYS build due to > which pgfdw_inval_callback gets called many times in which the cached > entries are marked as invalid and closed if they are not used in the > txn. The new function postgres_fdw_get_connections outputs the > information of the cached connections such as name if the connection > is still open and their validity. Hence the output of the > postgres_fdw_get_connections became unstable in the buildfarm member. > I will further analyze making tests stable, meanwhile any suggestions > are welcome. > >>> > >>> I do not think you should regard this as "we need to hack the test > >>> to make it stable". I think you should regard this as "this is a > >>> bug". A cache flush should not cause user-visible state changes. > >>> In particular, the above analysis implies that you think a cache > >>> flush is equivalent to end-of-transaction, which it absolutely > >>> is not. > >>> > >>> Also, now that I've looked at pgfdw_inval_callback, it scares > >>> the heck out of me. Actually disconnecting a connection during > >>> a cache inval callback seems quite unsafe --- what if that happens > >>> while we're using the connection? > >> > >> If the connection is still used in the transaction, pgfdw_inval_callback() > >> marks it as invalidated and doesn't close it. So I was not thinking that > >> this is so unsafe. > >> > >> The disconnection code in pgfdw_inval_callback() was added in commit > >> e3ebcca843 to fix connection leak issue, and it's back-patched. If this > >> change is really unsafe, we need to revert it immediately at least from > >> back > >> branches because the next minor release is scheduled soon. > > > > I think we can remove disconnect_pg_server in pgfdw_inval_callback and > > make entries only invalidated. Anyways, those connections can get > > closed at the end of main txn in pgfdw_xact_callback. Thoughts? > > But this revives the connection leak issue. So isn't it better to > to do that after we confirm that the current code is really unsafe? IMO, connections will not leak, because the invalidated connections eventually will get closed in pgfdw_xact_callback at the main txn end. IIRC, when we were finding a way to close the invalidated connections so that they don't leaked, we had two options: 1) let those connections (whether currently being used in the xact or not) get marked invalidated in pgfdw_inval_callback and closed in pgfdw_xact_callback at the main txn end as shown below if (PQstatus(entry->conn) != CONNECTION_OK || PQtransactionStatus(entry->conn) != PQTRANS_IDLE || entry->changing_xact_state || entry->invalidated). > by adding this { elog(DEBUG3, "discarding connection %p", entry->conn); disconnect_pg_server(entry); } 2) close the unused connections right away in pgfdw_inval_callback instead of marking them invalidated. Mark used connections as invalidated in pgfdw_inval_callback and close them in pgfdw_xact_callback at the main txn end. We went with option (2) because we thought this would ease some burden on pgfdw_xact_callback closing a lot of invalid connections at once. Hope that's fine. I will respond to postgres_fdw_get_connections issue separately. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/29 14:12, Bharath Rupireddy wrote: On Fri, Jan 29, 2021 at 10:28 AM Fujii Masao wrote: On 2021/01/29 11:09, Tom Lane wrote: Bharath Rupireddy writes: On Fri, Jan 29, 2021 at 1:52 AM Tom Lane wrote: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=trilobite&dt=2021-01-26%2019%3A59%3A40 This is a CLOBBER_CACHE_ALWAYS build, so I suspect what it's telling us is that the patch's behavior is unstable in the face of unexpected cache flushes. Thanks a lot! It looks like the syscache invalidation messages are generated too frequently with -DCLOBBER_CACHE_ALWAYS build due to which pgfdw_inval_callback gets called many times in which the cached entries are marked as invalid and closed if they are not used in the txn. The new function postgres_fdw_get_connections outputs the information of the cached connections such as name if the connection is still open and their validity. Hence the output of the postgres_fdw_get_connections became unstable in the buildfarm member. I will further analyze making tests stable, meanwhile any suggestions are welcome. I do not think you should regard this as "we need to hack the test to make it stable". I think you should regard this as "this is a bug". A cache flush should not cause user-visible state changes. In particular, the above analysis implies that you think a cache flush is equivalent to end-of-transaction, which it absolutely is not. Also, now that I've looked at pgfdw_inval_callback, it scares the heck out of me. Actually disconnecting a connection during a cache inval callback seems quite unsafe --- what if that happens while we're using the connection? If the connection is still used in the transaction, pgfdw_inval_callback() marks it as invalidated and doesn't close it. So I was not thinking that this is so unsafe. The disconnection code in pgfdw_inval_callback() was added in commit e3ebcca843 to fix connection leak issue, and it's back-patched. If this change is really unsafe, we need to revert it immediately at least from back branches because the next minor release is scheduled soon. I think we can remove disconnect_pg_server in pgfdw_inval_callback and make entries only invalidated. Anyways, those connections can get closed at the end of main txn in pgfdw_xact_callback. Thoughts? But this revives the connection leak issue. So isn't it better to to do that after we confirm that the current code is really unsafe? If okay, I can make a patch for this. BTW, even if we change pgfdw_inval_callback() so that it doesn't close the connection at all, ISTM that the results of postgres_fdw_get_connections() would not be stable because entry->invalidated would vary based on whether CLOBBER_CACHE_ALWAYS is used or not. Yes, after the above change (removing disconnect_pg_server in pgfdw_inval_callback), our tests don't get stable because postgres_fdw_get_connections shows the valid state of the connections. I think we can change postgres_fdw_get_connections so that it only shows the active connections server name but not valid state. Because, the valid state is something dependent on the internal state change and is not consistent with the user expectation but we are exposing it to the user. Thoughts? I don't think that's enough because even the following simple queries return the different results, depending on whether CLOBBER_CACHE_ALWAYS is used or not. SELECT * FROM ft6; -- ft6 is the foreign table SELECT server_name FROM postgres_fdw_get_connections(); When CLOBBER_CACHE_ALWAYS is used, postgres_fdw_get_connections() returns no records because the connection is marked as invalidated, and then closed at xact callback in SELECT query. Otherwise, postgres_fdw_get_connections() returns at least one connection that was established in the SELECT query. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 29, 2021 at 10:42 AM Bharath Rupireddy wrote: > > > Also, now that I've looked at pgfdw_inval_callback, it scares > > > the heck out of me. Actually disconnecting a connection during > > > a cache inval callback seems quite unsafe --- what if that happens > > > while we're using the connection? > > > > If the connection is still used in the transaction, pgfdw_inval_callback() > > marks it as invalidated and doesn't close it. So I was not thinking that > > this is so unsafe. > > > > The disconnection code in pgfdw_inval_callback() was added in commit > > e3ebcca843 to fix connection leak issue, and it's back-patched. If this > > change is really unsafe, we need to revert it immediately at least from back > > branches because the next minor release is scheduled soon. > > I think we can remove disconnect_pg_server in pgfdw_inval_callback and > make entries only invalidated. Anyways, those connections can get > closed at the end of main txn in pgfdw_xact_callback. Thoughts? > > If okay, I can make a patch for this. Attaching a patch for this, which can be back patched. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v1-0001-Fix-connection-closure-issue-in-pgfdw_inval_callb.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 29, 2021 at 10:28 AM Fujii Masao wrote: > On 2021/01/29 11:09, Tom Lane wrote: > > Bharath Rupireddy writes: > >> On Fri, Jan 29, 2021 at 1:52 AM Tom Lane wrote: > >>> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=trilobite&dt=2021-01-26%2019%3A59%3A40 > >>> This is a CLOBBER_CACHE_ALWAYS build, so I suspect what it's > >>> telling us is that the patch's behavior is unstable in the face > >>> of unexpected cache flushes. > > > >> Thanks a lot! It looks like the syscache invalidation messages are > >> generated too frequently with -DCLOBBER_CACHE_ALWAYS build due to > >> which pgfdw_inval_callback gets called many times in which the cached > >> entries are marked as invalid and closed if they are not used in the > >> txn. The new function postgres_fdw_get_connections outputs the > >> information of the cached connections such as name if the connection > >> is still open and their validity. Hence the output of the > >> postgres_fdw_get_connections became unstable in the buildfarm member. > >> I will further analyze making tests stable, meanwhile any suggestions > >> are welcome. > > > > I do not think you should regard this as "we need to hack the test > > to make it stable". I think you should regard this as "this is a > > bug". A cache flush should not cause user-visible state changes. > > In particular, the above analysis implies that you think a cache > > flush is equivalent to end-of-transaction, which it absolutely > > is not. > > > > Also, now that I've looked at pgfdw_inval_callback, it scares > > the heck out of me. Actually disconnecting a connection during > > a cache inval callback seems quite unsafe --- what if that happens > > while we're using the connection? > > If the connection is still used in the transaction, pgfdw_inval_callback() > marks it as invalidated and doesn't close it. So I was not thinking that > this is so unsafe. > > The disconnection code in pgfdw_inval_callback() was added in commit > e3ebcca843 to fix connection leak issue, and it's back-patched. If this > change is really unsafe, we need to revert it immediately at least from back > branches because the next minor release is scheduled soon. I think we can remove disconnect_pg_server in pgfdw_inval_callback and make entries only invalidated. Anyways, those connections can get closed at the end of main txn in pgfdw_xact_callback. Thoughts? If okay, I can make a patch for this. > BTW, even if we change pgfdw_inval_callback() so that it doesn't close > the connection at all, ISTM that the results of postgres_fdw_get_connections() > would not be stable because entry->invalidated would vary based on > whether CLOBBER_CACHE_ALWAYS is used or not. Yes, after the above change (removing disconnect_pg_server in pgfdw_inval_callback), our tests don't get stable because postgres_fdw_get_connections shows the valid state of the connections. I think we can change postgres_fdw_get_connections so that it only shows the active connections server name but not valid state. Because, the valid state is something dependent on the internal state change and is not consistent with the user expectation but we are exposing it to the user. Thoughts? If okay, I can work on the patch for this. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/29 11:09, Tom Lane wrote: Bharath Rupireddy writes: On Fri, Jan 29, 2021 at 1:52 AM Tom Lane wrote: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=trilobite&dt=2021-01-26%2019%3A59%3A40 This is a CLOBBER_CACHE_ALWAYS build, so I suspect what it's telling us is that the patch's behavior is unstable in the face of unexpected cache flushes. Thanks a lot! It looks like the syscache invalidation messages are generated too frequently with -DCLOBBER_CACHE_ALWAYS build due to which pgfdw_inval_callback gets called many times in which the cached entries are marked as invalid and closed if they are not used in the txn. The new function postgres_fdw_get_connections outputs the information of the cached connections such as name if the connection is still open and their validity. Hence the output of the postgres_fdw_get_connections became unstable in the buildfarm member. I will further analyze making tests stable, meanwhile any suggestions are welcome. I do not think you should regard this as "we need to hack the test to make it stable". I think you should regard this as "this is a bug". A cache flush should not cause user-visible state changes. In particular, the above analysis implies that you think a cache flush is equivalent to end-of-transaction, which it absolutely is not. Also, now that I've looked at pgfdw_inval_callback, it scares the heck out of me. Actually disconnecting a connection during a cache inval callback seems quite unsafe --- what if that happens while we're using the connection? If the connection is still used in the transaction, pgfdw_inval_callback() marks it as invalidated and doesn't close it. So I was not thinking that this is so unsafe. The disconnection code in pgfdw_inval_callback() was added in commit e3ebcca843 to fix connection leak issue, and it's back-patched. If this change is really unsafe, we need to revert it immediately at least from back branches because the next minor release is scheduled soon. BTW, even if we change pgfdw_inval_callback() so that it doesn't close the connection at all, ISTM that the results of postgres_fdw_get_connections() would not be stable because entry->invalidated would vary based on whether CLOBBER_CACHE_ALWAYS is used or not. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
Bharath Rupireddy writes: > On Fri, Jan 29, 2021 at 1:52 AM Tom Lane wrote: >> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=trilobite&dt=2021-01-26%2019%3A59%3A40 >> This is a CLOBBER_CACHE_ALWAYS build, so I suspect what it's >> telling us is that the patch's behavior is unstable in the face >> of unexpected cache flushes. > Thanks a lot! It looks like the syscache invalidation messages are > generated too frequently with -DCLOBBER_CACHE_ALWAYS build due to > which pgfdw_inval_callback gets called many times in which the cached > entries are marked as invalid and closed if they are not used in the > txn. The new function postgres_fdw_get_connections outputs the > information of the cached connections such as name if the connection > is still open and their validity. Hence the output of the > postgres_fdw_get_connections became unstable in the buildfarm member. > I will further analyze making tests stable, meanwhile any suggestions > are welcome. I do not think you should regard this as "we need to hack the test to make it stable". I think you should regard this as "this is a bug". A cache flush should not cause user-visible state changes. In particular, the above analysis implies that you think a cache flush is equivalent to end-of-transaction, which it absolutely is not. Also, now that I've looked at pgfdw_inval_callback, it scares the heck out of me. Actually disconnecting a connection during a cache inval callback seems quite unsafe --- what if that happens while we're using the connection? I fear this patch needs to be reverted and redesigned. regards, tom lane
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 29, 2021 at 1:52 AM Tom Lane wrote: > > Bharath Rupireddy writes: > > On Tue, Jan 26, 2021 at 1:55 PM Fujii Masao > > wrote: > >> Thanks for the patch! I also created that patch, confirmed that the test > >> successfully passed with -DENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS, > >> and pushed the patch. > > > Thanks a lot! > > Seems you're not out of the woods yet: > > https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=trilobite&dt=2021-01-26%2019%3A59%3A40 > > This is a CLOBBER_CACHE_ALWAYS build, so I suspect what it's > telling us is that the patch's behavior is unstable in the face > of unexpected cache flushes. Thanks a lot! It looks like the syscache invalidation messages are generated too frequently with -DCLOBBER_CACHE_ALWAYS build due to which pgfdw_inval_callback gets called many times in which the cached entries are marked as invalid and closed if they are not used in the txn. The new function postgres_fdw_get_connections outputs the information of the cached connections such as name if the connection is still open and their validity. Hence the output of the postgres_fdw_get_connections became unstable in the buildfarm member. I will further analyze making tests stable, meanwhile any suggestions are welcome. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
Bharath Rupireddy writes: > On Tue, Jan 26, 2021 at 1:55 PM Fujii Masao > wrote: >> Thanks for the patch! I also created that patch, confirmed that the test >> successfully passed with -DENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS, >> and pushed the patch. > Thanks a lot! Seems you're not out of the woods yet: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=trilobite&dt=2021-01-26%2019%3A59%3A40 This is a CLOBBER_CACHE_ALWAYS build, so I suspect what it's telling us is that the patch's behavior is unstable in the face of unexpected cache flushes. regards, tom lane
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Tue, Jan 26, 2021 at 8:38 AM Bharath Rupireddy wrote: > I will post "keep_connections" GUC and "keep_connection" server level > option patches later. Attaching v19 patch set for "keep_connections" GUC and "keep_connection" server level option. Please review them further. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v19-0002-postgres_fdw-add-keep_connections-GUC-to-not-cac.patch Description: Binary data v19-0003-postgres_fdw-server-level-option-keep_connection.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Tue, Jan 26, 2021 at 1:55 PM Fujii Masao wrote: > Thanks for the patch! I also created that patch, confirmed that the test > successfully passed with -DENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS, > and pushed the patch. Thanks a lot! With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/26 17:07, Bharath Rupireddy wrote: On Tue, Jan 26, 2021 at 1:27 PM Fujii Masao wrote: Yes, so I pushed that change to stabilize the regression test. Let's keep checking how the results of buildfarm members are changed. Sorry, I'm unfamiliar with checking the system status on the build farm website - https://buildfarm.postgresql.org/cgi-bin/show_failures.pl. I'm trying to figure that out. +WARNING: roles created by regression test cases should have names starting with "regress_" CREATE ROLE multi_conn_user2 SUPERUSER; +WARNING: roles created by regression test cases should have names starting with "regress_" Hmm... another failure happened. My bad. I should have caught that earlier. I will take care in future. Attaching a patch to fix it. Thanks for the patch! I also created that patch, confirmed that the test successfully passed with -DENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS, and pushed the patch. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Tue, Jan 26, 2021 at 1:27 PM Fujii Masao wrote: > > Yes, so I pushed that change to stabilize the regression test. > > Let's keep checking how the results of buildfarm members are changed. Sorry, I'm unfamiliar with checking the system status on the build farm website - https://buildfarm.postgresql.org/cgi-bin/show_failures.pl. I'm trying to figure that out. > +WARNING: roles created by regression test cases should have names starting > with "regress_" > CREATE ROLE multi_conn_user2 SUPERUSER; > +WARNING: roles created by regression test cases should have names starting > with "regress_" > > Hmm... another failure happened. My bad. I should have caught that earlier. I will take care in future. Attaching a patch to fix it. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v1-0001-Stabilize-test-case-for-postgres_fdw_disconnect_a.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/26 16:39, Fujii Masao wrote: On 2021/01/26 16:33, Bharath Rupireddy wrote: On Tue, Jan 26, 2021 at 12:54 PM Fujii Masao wrote: On 2021/01/26 16:05, Tom Lane wrote: Fujii Masao writes: Thanks for the review! I fixed them and pushed the patch! Buildfarm is very not happy ... Yes I'm investigating that.   -- Return false as connections are still in use, warnings are issued.   SELECT postgres_fdw_disconnect_all(); -WARNING: cannot close dropped server connection because it is still in use -WARNING: cannot close connection for server "loopback" because it is still in use   WARNING: cannot close connection for server "loopback2" because it is still in use +WARNING: cannot close connection for server "loopback" because it is still in use +WARNING: cannot close dropped server connection because it is still in use The cause of the regression test failure is that the order of warning messages is not stable. So I'm thinking to set client_min_messages to ERROR temporarily when doing the above test. Looks like we do suppress warnings/notices by setting client_min_messages to ERROR/WARNING. For instance, "suppress warning that depends on wal_level" and "Suppress NOTICE messages when users/groups don't exist". Yes, so I pushed that change to stabilize the regression test. Let's keep checking how the results of buildfarm members are changed. +WARNING: roles created by regression test cases should have names starting with "regress_" CREATE ROLE multi_conn_user2 SUPERUSER; +WARNING: roles created by regression test cases should have names starting with "regress_" Hmm... another failure happened. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/26 16:33, Bharath Rupireddy wrote: On Tue, Jan 26, 2021 at 12:54 PM Fujii Masao wrote: On 2021/01/26 16:05, Tom Lane wrote: Fujii Masao writes: Thanks for the review! I fixed them and pushed the patch! Buildfarm is very not happy ... Yes I'm investigating that. -- Return false as connections are still in use, warnings are issued. SELECT postgres_fdw_disconnect_all(); -WARNING: cannot close dropped server connection because it is still in use -WARNING: cannot close connection for server "loopback" because it is still in use WARNING: cannot close connection for server "loopback2" because it is still in use +WARNING: cannot close connection for server "loopback" because it is still in use +WARNING: cannot close dropped server connection because it is still in use The cause of the regression test failure is that the order of warning messages is not stable. So I'm thinking to set client_min_messages to ERROR temporarily when doing the above test. Looks like we do suppress warnings/notices by setting client_min_messages to ERROR/WARNING. For instance, "suppress warning that depends on wal_level" and "Suppress NOTICE messages when users/groups don't exist". Yes, so I pushed that change to stabilize the regression test. Let's keep checking how the results of buildfarm members are changed. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Tue, Jan 26, 2021 at 12:54 PM Fujii Masao wrote: > On 2021/01/26 16:05, Tom Lane wrote: > > Fujii Masao writes: > >> Thanks for the review! I fixed them and pushed the patch! > > > > Buildfarm is very not happy ... > > Yes I'm investigating that. > > -- Return false as connections are still in use, warnings are issued. > SELECT postgres_fdw_disconnect_all(); > -WARNING: cannot close dropped server connection because it is still in use > -WARNING: cannot close connection for server "loopback" because it is still > in use > WARNING: cannot close connection for server "loopback2" because it is > still in use > +WARNING: cannot close connection for server "loopback" because it is still > in use > +WARNING: cannot close dropped server connection because it is still in use > > The cause of the regression test failure is that the order of warning messages > is not stable. So I'm thinking to set client_min_messages to ERROR temporarily > when doing the above test. Looks like we do suppress warnings/notices by setting client_min_messages to ERROR/WARNING. For instance, "suppress warning that depends on wal_level" and "Suppress NOTICE messages when users/groups don't exist". With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/26 16:05, Tom Lane wrote: Fujii Masao writes: Thanks for the review! I fixed them and pushed the patch! Buildfarm is very not happy ... Yes I'm investigating that. -- Return false as connections are still in use, warnings are issued. SELECT postgres_fdw_disconnect_all(); -WARNING: cannot close dropped server connection because it is still in use -WARNING: cannot close connection for server "loopback" because it is still in use WARNING: cannot close connection for server "loopback2" because it is still in use +WARNING: cannot close connection for server "loopback" because it is still in use +WARNING: cannot close dropped server connection because it is still in use The cause of the regression test failure is that the order of warning messages is not stable. So I'm thinking to set client_min_messages to ERROR temporarily when doing the above test. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
Fujii Masao writes: > Thanks for the review! I fixed them and pushed the patch! Buildfarm is very not happy ... regards, tom lane
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/26 12:08, Bharath Rupireddy wrote: On Tue, Jan 26, 2021 at 12:38 AM Fujii Masao wrote: Attaching v17 patch set, please review it further. Thanks for updating the patch! Attached is the tweaked version of the patch. I didn't change any logic, but I updated some comments and docs. Also I added the regresssion test to check that postgres_fdw_disconnect() closes multiple connections. Barring any objection, I will commit this version. Thanks. The patch LGTM, except few typos: 1) in the commit message "a warning messsage is emitted." it's "message" not "messsage". 2) in the documentation "+ a user mapping, the correspoinding connections are closed." it's "corresponding" not "correspoinding". Thanks for the review! I fixed them and pushed the patch! Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Tue, Jan 26, 2021 at 12:38 AM Fujii Masao wrote: > > Attaching v17 patch set, please review it further. > > Thanks for updating the patch! > > Attached is the tweaked version of the patch. I didn't change any logic, > but I updated some comments and docs. Also I added the regresssion test > to check that postgres_fdw_disconnect() closes multiple connections. > Barring any objection, I will commit this version. Thanks. The patch LGTM, except few typos: 1) in the commit message "a warning messsage is emitted." it's "message" not "messsage". 2) in the documentation "+ a user mapping, the correspoinding connections are closed." it's "corresponding" not "correspoinding". I will post "keep_connections" GUC and "keep_connection" server level option patches later. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/26 0:12, Bharath Rupireddy wrote: On Mon, Jan 25, 2021 at 7:28 PM Bharath Rupireddy wrote: I will provide the updated patch set soon. Attaching v17 patch set, please review it further. Thanks for updating the patch! Attached is the tweaked version of the patch. I didn't change any logic, but I updated some comments and docs. Also I added the regresssion test to check that postgres_fdw_disconnect() closes multiple connections. Barring any objection, I will commit this version. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION From fa3e0f0a700588ab644c4c752e06c03845450712 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Tue, 26 Jan 2021 03:54:46 +0900 Subject: [PATCH] postgres_fdw: Add functions to discard cached connections. This commit introduces two new functions postgres_fdw_disconnect() and postgres_fdw_disconnect_all(). The former function discards the cached connection to the specified foreign server. The latter discards all the cached connections. If the connection is used in the current transaction, it's not closed and a warning messsage is emitted. For example, these functions are useful when users want to explicitly close the foreign server connections that are no longer necessary and then to prevent them from eating up the foreign servers connections capacity. Author: Bharath Rupireddy, tweaked a bit by Fujii Masao Reviewed-by: Alexey Kondratov, Zhijie Hou, Zhihong Yu, Fujii Masao Discussion: https://postgr.es/m/CALj2ACVvrp5=avp2pupem+nac8s4buqr3fjmmacoc7ftt0a...@mail.gmail.com --- contrib/postgres_fdw/connection.c | 135 +++- .../postgres_fdw/expected/postgres_fdw.out| 208 +- .../postgres_fdw/postgres_fdw--1.0--1.1.sql | 10 + contrib/postgres_fdw/sql/postgres_fdw.sql | 98 - doc/src/sgml/postgres-fdw.sgml| 67 +- 5 files changed, 505 insertions(+), 13 deletions(-) diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c index a1404cb6bb..ee0b4acf0b 100644 --- a/contrib/postgres_fdw/connection.c +++ b/contrib/postgres_fdw/connection.c @@ -80,6 +80,8 @@ static bool xact_got_connection = false; * SQL functions */ PG_FUNCTION_INFO_V1(postgres_fdw_get_connections); +PG_FUNCTION_INFO_V1(postgres_fdw_disconnect); +PG_FUNCTION_INFO_V1(postgres_fdw_disconnect_all); /* prototypes of private functions */ static void make_new_connection(ConnCacheEntry *entry, UserMapping *user); @@ -102,6 +104,7 @@ static bool pgfdw_exec_cleanup_query(PGconn *conn, const char *query, static bool pgfdw_get_cleanup_result(PGconn *conn, TimestampTz endtime, PGresult **result); static bool UserMappingPasswordRequired(UserMapping *user); +static bool disconnect_cached_connections(Oid serverid); /* * Get a PGconn which can be used to execute queries on the remote PostgreSQL @@ -1428,8 +1431,8 @@ postgres_fdw_get_connections(PG_FUNCTION_ARGS) * Even though the server is dropped in the current transaction, the * cache can still have associated active connection entry, say we * call such connections dangling. Since we can not fetch the server -* name from system catalogs for dangling connections, instead we -* show NULL value for server name in output. +* name from system catalogs for dangling connections, instead we show +* NULL value for server name in output. * * We could have done better by storing the server name in the cache * entry instead of server oid so that it could be used in the output. @@ -1447,7 +1450,7 @@ postgres_fdw_get_connections(PG_FUNCTION_ARGS) /* * If the server has been dropped in the current explicit * transaction, then this entry would have been invalidated in -* pgfdw_inval_callback at the end of drop sever command. Note +* pgfdw_inval_callback at the end of drop server command. Note * that this connection would not have been closed in * pgfdw_inval_callback because it is still being used in the * current explicit transaction. So, assert that here. @@ -1470,3 +1473,129 @@ postgres_fdw_get_connections(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } + +/* + * Disconnect the specified cached connections. + * + * This function discards the open connections that are established by + * postgres_fdw from the local session to the foreign server with + * the given name. Note that there can be multiple connections to + * the given server using different user mappings. If the connections + * are used in the current local transaction, they are not disconne
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Mon, Jan 25, 2021 at 7:28 PM Bharath Rupireddy wrote: > I will provide the updated patch set soon. Attaching v17 patch set, please review it further. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v17-0001-postgres_fdw-function-to-discard-cached-connecti.patch Description: Binary data v17-0002-postgres_fdw-add-keep_connections-GUC-to-not-cac.patch Description: Binary data v17-0003-postgres_fdw-server-level-option-keep_connection.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Mon, Jan 25, 2021 at 7:20 PM Fujii Masao wrote: > On 2021/01/25 19:28, Bharath Rupireddy wrote: > > On Mon, Jan 25, 2021 at 3:17 PM Fujii Masao > > wrote: > >>> Yes, if required backends can establish the connection again. But my > >>> worry is this - a non-super user disconnecting all or a given > >>> connection created by a super user? > >> > >> Yes, I was also worried about that. But I found that there are other > >> similar cases, for example, > >> > >> - a cursor that superuser declared can be closed by non-superuser (set by > >> SET ROLE or SET SESSION AUTHORIZATION) in the same session. > >> - a prepared statement that superuser created can be deallocated by > >> non-superuser in the same session. > >> > >> This makes me think that it's OK even for non-superuser to disconnect the > >> connections established by superuser in the same session. For now I've not > >> found any real security issue by doing that yet. Thought? Am I missing > >> something? > > > > Oh, and added to that list is dblink_disconnect(). I don't know > > whether there's any security risk if we allow non-superusers to > > discard the super users connections. > > I guess that's ok because superuser and nonsuperuser are running in the same > session. That is, since this is the case where superuser switches to > nonsuperuser intentionally, interactions between them is also intentional. > > OTOH, if nonsuperuser in one session can affect superuser in another session > that way, which would be problematic. So, for example, for now > pg_stat_activity disallows nonsuperuser to see the query that superuser in > another session is running, from it. Hmm, that makes sense. > > In this case, the super users > > will just have to re make the connection. > > > >>> For now I'm thinking that it might better to add the restriction like > >>> pg_terminate_backend() at first and relax that later if possible. But I'd > >>> like hear more opinions about this. > >> > >> I agree. If required we can lift it later, once we get the users using > >> these functions? Maybe we can have a comment near superchecks in > >> disconnect_cached_connections saying, we can lift this in future? > > > > Maybe we can do the opposite of the above that is not doing any > > superuser checks in disconnect functions for now, and later if some > > users complain we can add it? > > +1 Thanks, will send the updated patch set soon. > > We can leave a comment there that "As of > > now we don't see any security risks if a non-super user disconnects > > the connections made by super users. If required, non-supers can be > > disallowed to disconnct the connections" ? > > Yes. Also we should note that that's ok because they are in the same session. I will add this comment in disconnect_cached_connections so that we don't lose track of it. I will provide the updated patch set soon. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/25 19:28, Bharath Rupireddy wrote: On Mon, Jan 25, 2021 at 3:17 PM Fujii Masao wrote: Yes, if required backends can establish the connection again. But my worry is this - a non-super user disconnecting all or a given connection created by a super user? Yes, I was also worried about that. But I found that there are other similar cases, for example, - a cursor that superuser declared can be closed by non-superuser (set by SET ROLE or SET SESSION AUTHORIZATION) in the same session. - a prepared statement that superuser created can be deallocated by non-superuser in the same session. This makes me think that it's OK even for non-superuser to disconnect the connections established by superuser in the same session. For now I've not found any real security issue by doing that yet. Thought? Am I missing something? Oh, and added to that list is dblink_disconnect(). I don't know whether there's any security risk if we allow non-superusers to discard the super users connections. I guess that's ok because superuser and nonsuperuser are running in the same session. That is, since this is the case where superuser switches to nonsuperuser intentionally, interactions between them is also intentional. OTOH, if nonsuperuser in one session can affect superuser in another session that way, which would be problematic. So, for example, for now pg_stat_activity disallows nonsuperuser to see the query that superuser in another session is running, from it. In this case, the super users will just have to re make the connection. For now I'm thinking that it might better to add the restriction like pg_terminate_backend() at first and relax that later if possible. But I'd like hear more opinions about this. I agree. If required we can lift it later, once we get the users using these functions? Maybe we can have a comment near superchecks in disconnect_cached_connections saying, we can lift this in future? Maybe we can do the opposite of the above that is not doing any superuser checks in disconnect functions for now, and later if some users complain we can add it? +1 We can leave a comment there that "As of now we don't see any security risks if a non-super user disconnects the connections made by super users. If required, non-supers can be disallowed to disconnct the connections" ? Yes. Also we should note that that's ok because they are in the same session. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Mon, Jan 25, 2021 at 3:17 PM Fujii Masao wrote: > > Yes, if required backends can establish the connection again. But my > > worry is this - a non-super user disconnecting all or a given > > connection created by a super user? > > Yes, I was also worried about that. But I found that there are other similar > cases, for example, > > - a cursor that superuser declared can be closed by non-superuser (set by SET > ROLE or SET SESSION AUTHORIZATION) in the same session. > - a prepared statement that superuser created can be deallocated by > non-superuser in the same session. > > This makes me think that it's OK even for non-superuser to disconnect the > connections established by superuser in the same session. For now I've not > found any real security issue by doing that yet. Thought? Am I missing > something? Oh, and added to that list is dblink_disconnect(). I don't know whether there's any security risk if we allow non-superusers to discard the super users connections. In this case, the super users will just have to re make the connection. > > For now I'm thinking that it might better to add the restriction like > > pg_terminate_backend() at first and relax that later if possible. But I'd > > like hear more opinions about this. > > I agree. If required we can lift it later, once we get the users using > these functions? Maybe we can have a comment near superchecks in > disconnect_cached_connections saying, we can lift this in future? Maybe we can do the opposite of the above that is not doing any superuser checks in disconnect functions for now, and later if some users complain we can add it? We can leave a comment there that "As of now we don't see any security risks if a non-super user disconnects the connections made by super users. If required, non-supers can be disallowed to disconnct the connections" ? With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/25 18:13, Bharath Rupireddy wrote: On Mon, Jan 25, 2021 at 1:20 PM Fujii Masao wrote: Yeah, connections can be discarded by non-super users using postgres_fdw_disconnect_all and postgres_fdw_disconnect. Given the fact that a non-super user requires a password to access foreign tables [1], IMO a non-super user changing something related to a super user makes no sense at all. If okay, we can have a check in disconnect_cached_connections something like below: Also like pg_terminate_backend(), we should disallow non-superuser to disconnect the connections established by other non-superuser if the requesting user is not a member of the other? Or that's overkill because the target to discard is just a connection and it can be established again if necessary? Yes, if required backends can establish the connection again. But my worry is this - a non-super user disconnecting all or a given connection created by a super user? Yes, I was also worried about that. But I found that there are other similar cases, for example, - a cursor that superuser declared can be closed by non-superuser (set by SET ROLE or SET SESSION AUTHORIZATION) in the same session. - a prepared statement that superuser created can be deallocated by non-superuser in the same session. This makes me think that it's OK even for non-superuser to disconnect the connections established by superuser in the same session. For now I've not found any real security issue by doing that yet. Thought? Am I missing something? Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Mon, Jan 25, 2021 at 1:20 PM Fujii Masao wrote: > > Yeah, connections can be discarded by non-super users using > > postgres_fdw_disconnect_all and postgres_fdw_disconnect. Given the > > fact that a non-super user requires a password to access foreign > > tables [1], IMO a non-super user changing something related to a super > > user makes no sense at all. If okay, we can have a check in > > disconnect_cached_connections something like below: > > Also like pg_terminate_backend(), we should disallow non-superuser to > disconnect the connections established by other non-superuser if the > requesting user is not a member of the other? Or that's overkill because the > target to discard is just a connection and it can be established again if > necessary? Yes, if required backends can establish the connection again. But my worry is this - a non-super user disconnecting all or a given connection created by a super user? > For now I'm thinking that it might better to add the restriction like > pg_terminate_backend() at first and relax that later if possible. But I'd > like hear more opinions about this. I agree. If required we can lift it later, once we get the users using these functions? Maybe we can have a comment near superchecks in disconnect_cached_connections saying, we can lift this in future? Do you want me to add these checks like in pg_signal_backend? /* Only allow superusers to signal superuser-owned backends. */ if (superuser_arg(proc->roleId) && !superuser()) return SIGNAL_BACKEND_NOSUPERUSER; /* Users can signal backends they have role membership in. */ if (!has_privs_of_role(GetUserId(), proc->roleId) && !has_privs_of_role(GetUserId(), DEFAULT_ROLE_SIGNAL_BACKENDID)) return SIGNAL_BACKEND_NOPERMISSION; or only below is enough? +/* Non-super users are not allowed to disconnect cached connections. */ +if (!superuser()) +ereport(ERROR, +(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to discard open connections"))); > > +static bool > > +disconnect_cached_connections(Oid serverid) > > +{ > > +HASH_SEQ_STATUSscan; > > +ConnCacheEntry*entry; > > +boolall = !OidIsValid(serverid); > > +boolresult = false; > > + > > +if (!superuser()) > > +ereport(ERROR, > > +(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), > > + errmsg("must be superuser to discard open connections"))); > > + > > +if (!ConnectionHash) > > > > Having said that, it looks like dblink_disconnect doesn't perform > > superuser checks. > > Also non-superuser (set by SET ROLE or SET SESSION AUTHORIZATION) seems to be > able to run SQL using the dblink connection established by superuser. If we > didn't think that this is a problem, we also might not need to care about > issue even for postgres_fdw. IMO, we can have superuser checks for postgres_fdw new functions for now. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/23 13:40, Bharath Rupireddy wrote: On Fri, Jan 22, 2021 at 6:43 PM Fujii Masao wrote: Please review the v16 patch set further. Thanks! Will review that later. + /* +* For the given server, if we closed connection or it is still in +* use, then no need of scanning the cache further. We do this +* because the cache can not have multiple cache entries for a +* single foreign server. +*/ On second thought, ISTM that single foreign server can have multiple cache entries. For example, CREATE ROLE foo1 SUPERUSER; CREATE ROLE foo2 SUPERUSER; CREATE EXTENSION postgres_fdw; CREATE SERVER loopback FOREIGN DATA WRAPPER postgres_fdw OPTIONS (port '5432'); CREATE USER MAPPING FOR foo1 SERVER loopback OPTIONS (user 'postgres'); CREATE USER MAPPING FOR foo2 SERVER loopback OPTIONS (user 'postgres'); CREATE TABLE t (i int); CREATE FOREIGN TABLE ft (i int) SERVER loopback OPTIONS (table_name 't'); SET SESSION AUTHORIZATION foo1; SELECT * FROM ft; SET SESSION AUTHORIZATION foo2; SELECT * FROM ft; Then you can see there are multiple open connections for the same server as follows. So we need to scan all the entries even when the serverid is specified. SELECT * FROM postgres_fdw_get_connections(); server_name | valid -+--- loopback| t loopback| t (2 rows) This is a great finding. Thanks a lot. I will remove hash_seq_term(&scan); in disconnect_cached_connections and add this as a test case for postgres_fdw_get_connections function, just to show there can be multiple connections with a single server name. This means that user (even non-superuser) can disconnect the connection established by another user (superuser), by using postgres_fdw_disconnect_all(). Is this really OK? Yeah, connections can be discarded by non-super users using postgres_fdw_disconnect_all and postgres_fdw_disconnect. Given the fact that a non-super user requires a password to access foreign tables [1], IMO a non-super user changing something related to a super user makes no sense at all. If okay, we can have a check in disconnect_cached_connections something like below: Also like pg_terminate_backend(), we should disallow non-superuser to disconnect the connections established by other non-superuser if the requesting user is not a member of the other? Or that's overkill because the target to discard is just a connection and it can be established again if necessary? For now I'm thinking that it might better to add the restriction like pg_terminate_backend() at first and relax that later if possible. But I'd like hear more opinions about this. +static bool +disconnect_cached_connections(Oid serverid) +{ +HASH_SEQ_STATUSscan; +ConnCacheEntry*entry; +boolall = !OidIsValid(serverid); +boolresult = false; + +if (!superuser()) +ereport(ERROR, +(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to discard open connections"))); + +if (!ConnectionHash) Having said that, it looks like dblink_disconnect doesn't perform superuser checks. Also non-superuser (set by SET ROLE or SET SESSION AUTHORIZATION) seems to be able to run SQL using the dblink connection established by superuser. If we didn't think that this is a problem, we also might not need to care about issue even for postgres_fdw. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 22, 2021 at 6:43 PM Fujii Masao wrote: > >> Please review the v16 patch set further. > > > > Thanks! Will review that later. > > + /* > +* For the given server, if we closed connection or > it is still in > +* use, then no need of scanning the cache further. > We do this > +* because the cache can not have multiple cache > entries for a > +* single foreign server. > +*/ > > On second thought, ISTM that single foreign server can have multiple cache > entries. For example, > > CREATE ROLE foo1 SUPERUSER; > CREATE ROLE foo2 SUPERUSER; > CREATE EXTENSION postgres_fdw; > CREATE SERVER loopback FOREIGN DATA WRAPPER postgres_fdw OPTIONS (port > '5432'); > CREATE USER MAPPING FOR foo1 SERVER loopback OPTIONS (user 'postgres'); > CREATE USER MAPPING FOR foo2 SERVER loopback OPTIONS (user 'postgres'); > CREATE TABLE t (i int); > CREATE FOREIGN TABLE ft (i int) SERVER loopback OPTIONS (table_name 't'); > SET SESSION AUTHORIZATION foo1; > SELECT * FROM ft; > SET SESSION AUTHORIZATION foo2; > SELECT * FROM ft; > > > Then you can see there are multiple open connections for the same server > as follows. So we need to scan all the entries even when the serverid is > specified. > > SELECT * FROM postgres_fdw_get_connections(); > > server_name | valid > -+--- > loopback| t > loopback| t > (2 rows) This is a great finding. Thanks a lot. I will remove hash_seq_term(&scan); in disconnect_cached_connections and add this as a test case for postgres_fdw_get_connections function, just to show there can be multiple connections with a single server name. > This means that user (even non-superuser) can disconnect the connection > established by another user (superuser), by using > postgres_fdw_disconnect_all(). > Is this really OK? Yeah, connections can be discarded by non-super users using postgres_fdw_disconnect_all and postgres_fdw_disconnect. Given the fact that a non-super user requires a password to access foreign tables [1], IMO a non-super user changing something related to a super user makes no sense at all. If okay, we can have a check in disconnect_cached_connections something like below: +static bool +disconnect_cached_connections(Oid serverid) +{ +HASH_SEQ_STATUSscan; +ConnCacheEntry*entry; +boolall = !OidIsValid(serverid); +boolresult = false; + +if (!superuser()) +ereport(ERROR, +(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to discard open connections"))); + +if (!ConnectionHash) Having said that, it looks like dblink_disconnect doesn't perform superuser checks. Thoughts? [1] SELECT * FROM ft1_nopw LIMIT 1; ERROR: password is required DETAIL: Non-superusers must provide a password in the user mapping. > + if (all || (OidIsValid(serverid) && entry->serverid == > serverid)) > + { > > I don't think that "OidIsValid(serverid)" condition is necessary here. > But you're just concerned about the case where the caller mistakenly > specifies invalid oid and all=false? One idea to avoid that inconsistent > combination of inputs is to change disconnect_cached_connections() > as follows. > > -disconnect_cached_connections(Oid serverid, bool all) > +disconnect_cached_connections(Oid serverid) > { > HASH_SEQ_STATUS scan; > ConnCacheEntry *entry; > + boolall = !OidIsValid(serverid); +1. Will change it. > +* in pgfdw_inval_callback at the end > of drop sever > > Typo: "sever" should be "server". +1. Will change it. > +-- === > +-- test postgres_fdw_disconnect function > +-- === > > This regression test is placed at the end of test file. But isn't it better > to place that just after the regression test "test connection invalidation > cases" because they are related? +1. Will change it. > + > +postgres=# SELECT * FROM postgres_fdw_disconnect('loopback1'); > + postgres_fdw_disconnect > > The tag should start from the beginning. +1. Will change it. > As I commented upthread, what about replacing the example query with > "SELECT postgres_fdw_disconnect('loopback1');" because it's more common? Sorry, I forgot to check that in the documentation earlier. +1. Will change it. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/22 3:29, Fujii Masao wrote: On 2021/01/22 1:17, Bharath Rupireddy wrote: On Thu, Jan 21, 2021 at 8:58 PM Fujii Masao wrote: My opinion is to check "!all", but if others prefer using such boolean flag, I'd withdraw my opinion. I'm really sorry, actually if (!all) is enough there, my earlier understanding was wrong. +  if ((all || entry->server_hashvalue == hashvalue) && What about making disconnect_cached_connections() accept serverid instead of hashvalue, and perform the above comparison based on serverid? That is, I'm thinking "if (all || entry->serverid == serverid)". If we do that, we can simplify postgres_fdw_disconnect() a bit more by getting rid of the calculation of hashvalue. That's a good idea. I missed this point. Thanks. +  if ((all || entry->server_hashvalue == hashvalue) && +   entry->conn) I think that it's better to make the check of "entry->conn" independent like other functions in postgres_fdw/connection.c. What about adding the following check before the above? /* Ignore cache entry if no open connection right now */ if (entry->conn == NULL) continue; Done. +  /* +   * If the server has been dropped in the current explicit +   * transaction, then this entry would have been invalidated +   * in pgfdw_inval_callback at the end of drop sever +   * command. Note that this connection would not have been +   * closed in pgfdw_inval_callback because it is still being +   * used in the current explicit transaction. So, assert +   * that here. +   */ +  Assert(entry->invalidated); As this comment explains, even when the connection is used in the transaction, its server can be dropped in the same transaction. The connection can remain until the end of transaction even though its server has been already dropped. I'm now wondering if this behavior itself is problematic and should be forbid. Of course, this is separate topic from this patch, though.. BTW, my just idea for that is; 1. change postgres_fdw_get_connections() return also serverid and xact_depth. 2. make postgres_fdw define the event trigger on DROP SERVER command so that  an error is thrown if the connection to the server is still in use.  The event trigger function uses postgres_fdw_get_connections() to check  if the server connection is still in use or not. I'm not sure if this just idea is really feasible or not, though... I'm not quite sure if we can create such a dependency i.e. blocking "drop foreign server" when at least one session has an in use cached connection on it? Maybe my explanation was not clear... I was thinking to prevent the server whose connection is used *within the current transaction* from being dropped. IOW, I was thinking to forbid the drop of server if xact_depth of its connection is more than one. So one session can drop the server even when its connection is open in other session if it's not used within the transaction (i.e., xact_depth == 0). BTW, for now, if the connection is used within the transaction, other session cannot drop the corresponding server because the transaction holds the lock on the relations that depend on the server. Only the session running that transaction can drop the server. This can cause the issue in discussion. So, my just idea is to disallow even that session running the transaction to drop the server. This means that no session can drop the server while its connection is used within the transaction (xact_depth > 0). What if a user wants to drop a server from one session, all other sessions one after the other keep having in-use connections related to that server, (though this use case sounds impractical) will the drop server ever be successful? Since we can have hundreds of sessions in real world postgres environment, I don't know if it's a good idea to create such dependency. As you suggested, this point can be discussed in a separate thread and if any of the approaches proposed by you above is finalized we can extend postgres_fdw_get_connections anytime. Thoughts? I will consider more before starting separate discussion! Attaching v16 patch set, addressing above review comments and also added a test case suggested upthread that postgres_fdw_disconnect() with existing server name returns false that is when the cache doesn't have active connection. Please review the v16 patch set further. Thanks! Will review that later. + /* +* For the given server, if we closed connection or it
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/22 1:17, Bharath Rupireddy wrote: On Thu, Jan 21, 2021 at 8:58 PM Fujii Masao wrote: My opinion is to check "!all", but if others prefer using such boolean flag, I'd withdraw my opinion. I'm really sorry, actually if (!all) is enough there, my earlier understanding was wrong. + if ((all || entry->server_hashvalue == hashvalue) && What about making disconnect_cached_connections() accept serverid instead of hashvalue, and perform the above comparison based on serverid? That is, I'm thinking "if (all || entry->serverid == serverid)". If we do that, we can simplify postgres_fdw_disconnect() a bit more by getting rid of the calculation of hashvalue. That's a good idea. I missed this point. Thanks. + if ((all || entry->server_hashvalue == hashvalue) && +entry->conn) I think that it's better to make the check of "entry->conn" independent like other functions in postgres_fdw/connection.c. What about adding the following check before the above? /* Ignore cache entry if no open connection right now */ if (entry->conn == NULL) continue; Done. + /* +* If the server has been dropped in the current explicit +* transaction, then this entry would have been invalidated +* in pgfdw_inval_callback at the end of drop sever +* command. Note that this connection would not have been +* closed in pgfdw_inval_callback because it is still being +* used in the current explicit transaction. So, assert +* that here. +*/ + Assert(entry->invalidated); As this comment explains, even when the connection is used in the transaction, its server can be dropped in the same transaction. The connection can remain until the end of transaction even though its server has been already dropped. I'm now wondering if this behavior itself is problematic and should be forbid. Of course, this is separate topic from this patch, though.. BTW, my just idea for that is; 1. change postgres_fdw_get_connections() return also serverid and xact_depth. 2. make postgres_fdw define the event trigger on DROP SERVER command so that an error is thrown if the connection to the server is still in use. The event trigger function uses postgres_fdw_get_connections() to check if the server connection is still in use or not. I'm not sure if this just idea is really feasible or not, though... I'm not quite sure if we can create such a dependency i.e. blocking "drop foreign server" when at least one session has an in use cached connection on it? Maybe my explanation was not clear... I was thinking to prevent the server whose connection is used *within the current transaction* from being dropped. IOW, I was thinking to forbid the drop of server if xact_depth of its connection is more than one. So one session can drop the server even when its connection is open in other session if it's not used within the transaction (i.e., xact_depth == 0). BTW, for now, if the connection is used within the transaction, other session cannot drop the corresponding server because the transaction holds the lock on the relations that depend on the server. Only the session running that transaction can drop the server. This can cause the issue in discussion. So, my just idea is to disallow even that session running the transaction to drop the server. This means that no session can drop the server while its connection is used within the transaction (xact_depth > 0). What if a user wants to drop a server from one session, all other sessions one after the other keep having in-use connections related to that server, (though this use case sounds impractical) will the drop server ever be successful? Since we can have hundreds of sessions in real world postgres environment, I don't know if it's a good idea to create such dependency. As you suggested, this point can be discussed in a separate thread and if any of the approaches proposed by you above is finalized we can extend postgres_fdw_get_connections anytime. Thoughts? I will consider more before starting separate discussion! Attaching v16 patch set, addressing above review comments and also added a test case suggested upthread that postgres_fdw_disconnect() with existing server name returns false that is when the cache doesn't have active connection. Please review the v16 patch set further. Thanks! Will review that later. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Thu, Jan 21, 2021 at 8:58 PM Fujii Masao wrote: > My opinion is to check "!all", but if others prefer using such boolean flag, > I'd withdraw my opinion. I'm really sorry, actually if (!all) is enough there, my earlier understanding was wrong. > + if ((all || entry->server_hashvalue == hashvalue) && > > What about making disconnect_cached_connections() accept serverid instead > of hashvalue, and perform the above comparison based on serverid? That is, > I'm thinking "if (all || entry->serverid == serverid)". If we do that, we can > simplify postgres_fdw_disconnect() a bit more by getting rid of the > calculation > of hashvalue. That's a good idea. I missed this point. Thanks. > + if ((all || entry->server_hashvalue == hashvalue) && > +entry->conn) > > I think that it's better to make the check of "entry->conn" independent > like other functions in postgres_fdw/connection.c. What about adding > the following check before the above? > > /* Ignore cache entry if no open connection right now */ > if (entry->conn == NULL) > continue; Done. > + /* > +* If the server has been dropped in > the current explicit > +* transaction, then this entry would > have been invalidated > +* in pgfdw_inval_callback at the end > of drop sever > +* command. Note that this connection > would not have been > +* closed in pgfdw_inval_callback > because it is still being > +* used in the current explicit > transaction. So, assert > +* that here. > +*/ > + Assert(entry->invalidated); > > As this comment explains, even when the connection is used in the transaction, > its server can be dropped in the same transaction. The connection can remain > until the end of transaction even though its server has been already dropped. > I'm now wondering if this behavior itself is problematic and should be forbid. > Of course, this is separate topic from this patch, though.. > > BTW, my just idea for that is; > 1. change postgres_fdw_get_connections() return also serverid and xact_depth. > 2. make postgres_fdw define the event trigger on DROP SERVER command so that > an error is thrown if the connection to the server is still in use. > The event trigger function uses postgres_fdw_get_connections() to check > if the server connection is still in use or not. > > I'm not sure if this just idea is really feasible or not, though... I'm not quite sure if we can create such a dependency i.e. blocking "drop foreign server" when at least one session has an in use cached connection on it? What if a user wants to drop a server from one session, all other sessions one after the other keep having in-use connections related to that server, (though this use case sounds impractical) will the drop server ever be successful? Since we can have hundreds of sessions in real world postgres environment, I don't know if it's a good idea to create such dependency. As you suggested, this point can be discussed in a separate thread and if any of the approaches proposed by you above is finalized we can extend postgres_fdw_get_connections anytime. Thoughts? Attaching v16 patch set, addressing above review comments and also added a test case suggested upthread that postgres_fdw_disconnect() with existing server name returns false that is when the cache doesn't have active connection. Please review the v16 patch set further. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v16-0001-postgres_fdw-function-to-discard-cached-connecti.patch Description: Binary data v16-0002-postgres_fdw-add-keep_connections-GUC-to-not-cac.patch Description: Binary data v16-0003-postgres_fdw-server-level-option-keep_connection.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/21 16:16, Bharath Rupireddy wrote: On Thu, Jan 21, 2021 at 12:17 PM Fujii Masao wrote: On 2021/01/21 14:46, Bharath Rupireddy wrote: On Thu, Jan 21, 2021 at 10:06 AM Fujii Masao wrote: > >> + if (entry->server_hashvalue == hashvalue && + (entry->xact_depth > 0 || result)) + { + hash_seq_term(&scan); + break; entry->server_hashvalue can be 0? If yes, since postgres_fdw_disconnect_all() specifies 0 as hashvalue, ISTM that the above condition can be true unexpectedly. Can we replace this condition with just "if (!all)"? I don't think so entry->server_hashvalue can be zero, because GetSysCacheHashValue1/CatalogCacheComputeHashValue will not return 0 as hash value. I have not seen someone comparing hashvalue with an expectation that it has 0 value, for instance see if (hashvalue == 0 || riinfo->oidHashValue == hashvalue). Having if(!all) something like below there doesn't suffice because we might call hash_seq_term, when some connection other than the given foreign server connection is in use. No because we check the following condition before reaching that code. No? + if ((all || entry->server_hashvalue == hashvalue) && I was thinking that "(entry->xact_depth > 0 || result))" condition is not necessary because "result" is set to true when xact_depth <= 0 and that condition always indicates true. I think that condition is too confusing. How about having a boolean can_terminate_scan like below? Thanks for thinking this. But at least for me, "if (!all)" looks not so confusing. And the comment seems to explain why we can end the scan. May I know if it's okay to have the boolean can_terminate_scan as shown in [1]? My opinion is to check "!all", but if others prefer using such boolean flag, I'd withdraw my opinion. + if ((all || entry->server_hashvalue == hashvalue) && What about making disconnect_cached_connections() accept serverid instead of hashvalue, and perform the above comparison based on serverid? That is, I'm thinking "if (all || entry->serverid == serverid)". If we do that, we can simplify postgres_fdw_disconnect() a bit more by getting rid of the calculation of hashvalue. + if ((all || entry->server_hashvalue == hashvalue) && +entry->conn) I think that it's better to make the check of "entry->conn" independent like other functions in postgres_fdw/connection.c. What about adding the following check before the above? /* Ignore cache entry if no open connection right now */ if (entry->conn == NULL) continue; + /* +* If the server has been dropped in the current explicit +* transaction, then this entry would have been invalidated +* in pgfdw_inval_callback at the end of drop sever +* command. Note that this connection would not have been +* closed in pgfdw_inval_callback because it is still being +* used in the current explicit transaction. So, assert +* that here. +*/ + Assert(entry->invalidated); As this comment explains, even when the connection is used in the transaction, its server can be dropped in the same transaction. The connection can remain until the end of transaction even though its server has been already dropped. I'm now wondering if this behavior itself is problematic and should be forbid. Of course, this is separate topic from this patch, though.. BTW, my just idea for that is; 1. change postgres_fdw_get_connections() return also serverid and xact_depth. 2. make postgres_fdw define the event trigger on DROP SERVER command so that an error is thrown if the connection to the server is still in use. The event trigger function uses postgres_fdw_get_connections() to check if the server connection is still in use or not. I'm not sure if this just idea is really feasible or not, though... Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Thu, Jan 21, 2021 at 12:17 PM Fujii Masao wrote: > On 2021/01/21 14:46, Bharath Rupireddy wrote: > > On Thu, Jan 21, 2021 at 10:06 AM Fujii Masao > > wrote: > > > >> + if (entry->server_hashvalue == hashvalue && > + (entry->xact_depth > 0 || result)) > + { > + hash_seq_term(&scan); > + break; > > entry->server_hashvalue can be 0? If yes, since > postgres_fdw_disconnect_all() > specifies 0 as hashvalue, ISTM that the above condition can be true > unexpectedly. Can we replace this condition with just "if (!all)"? > >>> > >>> I don't think so entry->server_hashvalue can be zero, because > >>> GetSysCacheHashValue1/CatalogCacheComputeHashValue will not return 0 > >>> as hash value. I have not seen someone comparing hashvalue with an > >>> expectation that it has 0 value, for instance see if (hashvalue == 0 > >>> || riinfo->oidHashValue == hashvalue). > >>> > >>>Having if(!all) something like below there doesn't suffice because we > >>> might call hash_seq_term, when some connection other than the given > >>> foreign server connection is in use. > >> > >> No because we check the following condition before reaching that code. No? > >> > >> + if ((all || entry->server_hashvalue == hashvalue) && > >> > >> > >> I was thinking that "(entry->xact_depth > 0 || result))" condition is not > >> necessary because "result" is set to true when xact_depth <= 0 and that > >> condition always indicates true. > > > > I think that condition is too confusing. How about having a boolean > > can_terminate_scan like below? > > Thanks for thinking this. But at least for me, "if (!all)" looks not so > confusing. > And the comment seems to explain why we can end the scan. May I know if it's okay to have the boolean can_terminate_scan as shown in [1]? [1] - https://www.postgresql.org/message-id/flat/CALj2ACVx0%2BiOsrAA-wXbo3RLAKqUoNvvEd7foJ0vLwOdu8XjXw%40mail.gmail.com With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/21 14:46, Bharath Rupireddy wrote: On Thu, Jan 21, 2021 at 10:06 AM Fujii Masao wrote: > >> + if (entry->server_hashvalue == hashvalue && + (entry->xact_depth > 0 || result)) + { + hash_seq_term(&scan); + break; entry->server_hashvalue can be 0? If yes, since postgres_fdw_disconnect_all() specifies 0 as hashvalue, ISTM that the above condition can be true unexpectedly. Can we replace this condition with just "if (!all)"? I don't think so entry->server_hashvalue can be zero, because GetSysCacheHashValue1/CatalogCacheComputeHashValue will not return 0 as hash value. I have not seen someone comparing hashvalue with an expectation that it has 0 value, for instance see if (hashvalue == 0 || riinfo->oidHashValue == hashvalue). Having if(!all) something like below there doesn't suffice because we might call hash_seq_term, when some connection other than the given foreign server connection is in use. No because we check the following condition before reaching that code. No? + if ((all || entry->server_hashvalue == hashvalue) && I was thinking that "(entry->xact_depth > 0 || result))" condition is not necessary because "result" is set to true when xact_depth <= 0 and that condition always indicates true. I think that condition is too confusing. How about having a boolean can_terminate_scan like below? Thanks for thinking this. But at least for me, "if (!all)" looks not so confusing. And the comment seems to explain why we can end the scan. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
RE: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
> > > Attaching v15 patch set. Please consider it for further review. > > > > Hi > > > > I have some comments for the 0001 patch > > > > In v15-0001-postgres_fdw-function-to-discard-cached-connecti > > > > 1. > > + If there is no open connection to the given foreign server, > false > > + is returned. If no foreign server with the given name is found, > > + an error > > > > Do you think it's better add some testcases about: > > call postgres_fdw_disconnect and postgres_fdw_disconnect_all > > when there is no open connection to the given foreign server > > Do you mean a test case where foreign server exists but > postgres_fdw_disconnect() returns false because there's no connection for > that server? Yes, I read this from the doc, so I think it's better to test this. > > 2. > > + /* > > +* For the given server, if we closed connection > or it is still in > > +* use, then no need of scanning the cache > further. > > +*/ > > + if (entry->server_hashvalue == hashvalue && > > + (entry->xact_depth > 0 || result)) > > + { > > + hash_seq_term(&scan); > > + break; > > + } > > > > If I am not wrong, is the following condition always true ? > > (entry->xact_depth > 0 || result) > > It's not always true. But it seems like it's too confusing, please have > a look at the upthread suggestion to change this with can_terminate_scan > boolean. Thanks for the remind, I will look at that. Best regards, houzj
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Thu, Jan 21, 2021 at 11:15 AM Hou, Zhijie wrote: > > > Attaching v15 patch set. Please consider it for further review. > > Hi > > I have some comments for the 0001 patch > > In v15-0001-postgres_fdw-function-to-discard-cached-connecti > > 1. > + If there is no open connection to the given foreign server, > false > + is returned. If no foreign server with the given name is found, an > error > > Do you think it's better add some testcases about: > call postgres_fdw_disconnect and postgres_fdw_disconnect_all when > there is no open connection to the given foreign server Do you mean a test case where foreign server exists but postgres_fdw_disconnect() returns false because there's no connection for that server? > 2. > + /* > +* For the given server, if we closed connection or > it is still in > +* use, then no need of scanning the cache further. > +*/ > + if (entry->server_hashvalue == hashvalue && > + (entry->xact_depth > 0 || result)) > + { > + hash_seq_term(&scan); > + break; > + } > > If I am not wrong, is the following condition always true ? > (entry->xact_depth > 0 || result) It's not always true. But it seems like it's too confusing, please have a look at the upthread suggestion to change this with can_terminate_scan boolean. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Thu, Jan 21, 2021 at 10:06 AM Fujii Masao wrote: > >> + if (entry->server_hashvalue == hashvalue && > >> + (entry->xact_depth > 0 || result)) > >> + { > >> + hash_seq_term(&scan); > >> + break; > >> > >> entry->server_hashvalue can be 0? If yes, since > >> postgres_fdw_disconnect_all() > >> specifies 0 as hashvalue, ISTM that the above condition can be true > >> unexpectedly. Can we replace this condition with just "if (!all)"? > > > > I don't think so entry->server_hashvalue can be zero, because > > GetSysCacheHashValue1/CatalogCacheComputeHashValue will not return 0 > > as hash value. I have not seen someone comparing hashvalue with an > > expectation that it has 0 value, for instance see if (hashvalue == 0 > > || riinfo->oidHashValue == hashvalue). > > > > Having if(!all) something like below there doesn't suffice because we > > might call hash_seq_term, when some connection other than the given > > foreign server connection is in use. > > No because we check the following condition before reaching that code. No? > > + if ((all || entry->server_hashvalue == hashvalue) && > > > I was thinking that "(entry->xact_depth > 0 || result))" condition is not > necessary because "result" is set to true when xact_depth <= 0 and that > condition always indicates true. I think that condition is too confusing. How about having a boolean can_terminate_scan like below? while ((entry = (ConnCacheEntry *) hash_seq_search(&scan))) { boolcan_terminate_scan = false; /* * Either disconnect given or all the active and not in use cached * connections. */ if ((all || entry->server_hashvalue == hashvalue) && entry->conn) { /* We cannot close connection that's in use, so issue a warning. */ if (entry->xact_depth > 0) { ForeignServer *server; if (!all) can_terminate_scan = true; server = GetForeignServerExtended(entry->serverid, FSV_MISSING_OK); if (!server) { /* * If the server has been dropped in the current explicit * transaction, then this entry would have been invalidated * in pgfdw_inval_callback at the end of drop sever * command. Note that this connection would not have been * closed in pgfdw_inval_callback because it is still being * used in the current explicit transaction. So, assert * that here. */ Assert(entry->invalidated); ereport(WARNING, (errmsg("cannot close dropped server connection because it is still in use"))); } else ereport(WARNING, (errmsg("cannot close connection for server \"%s\" because it is still in use", server->servername))); } else { elog(DEBUG3, "discarding connection %p", entry->conn); disconnect_pg_server(entry); result = true; if (!all) can_terminate_scan = true; } /* * For the given server, if we closed connection or it is still in * use, then no need of scanning the cache further. */ if (can_terminate_scan) { hash_seq_term(&scan); break; } } } With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
RE: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
> Attaching v15 patch set. Please consider it for further review. Hi I have some comments for the 0001 patch In v15-0001-postgres_fdw-function-to-discard-cached-connecti 1. + If there is no open connection to the given foreign server, false + is returned. If no foreign server with the given name is found, an error Do you think it's better add some testcases about: call postgres_fdw_disconnect and postgres_fdw_disconnect_all when there is no open connection to the given foreign server 2. + /* +* For the given server, if we closed connection or it is still in +* use, then no need of scanning the cache further. +*/ + if (entry->server_hashvalue == hashvalue && + (entry->xact_depth > 0 || result)) + { + hash_seq_term(&scan); + break; + } If I am not wrong, is the following condition always true ? (entry->xact_depth > 0 || result) Best regards, houzj
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/21 12:00, Bharath Rupireddy wrote: On Wed, Jan 20, 2021 at 6:58 PM Fujii Masao wrote: + * It checks if the cache has a connection for the given foreign server that's + * not being used within current transaction, then returns true. If the + * connection is in use, then it emits a warning and returns false. The comment also should mention the case where no open connection for the given server is found? What about rewriting this to the following? - If the cached connection for the given foreign server is found and has not been used within current transaction yet, close the connection and return true. Even when it's found, if it's already used, keep the connection, emit a warning and return false. If it's not found, return false. - Done. + * It returns true, if it closes at least one connection, otherwise false. + * + * It returns false, if the cache doesn't exit. The above second comment looks redundant. Yes. "otherwise false" means it. + if (ConnectionHash) + result = disconnect_cached_connections(0, true); Isn't it smarter to make disconnect_cached_connections() check ConnectionHash and return false if it's NULL? If we do that, we can simplify the code of postgres_fdw_disconnect() and _all(). Done. + * current transaction are disconnected. Otherwise, the unused entries with the + * given hashvalue are disconnected. In the above second comment, a singular form should be used instead? Because there must be no multiple entries with the given hashvalue. Rephrased the function comment a bit. Mentioned the _disconnect and _disconnect_all in comments because we have said enough what each of those two functions do. +/* + * Workhorse to disconnect cached connections. + * + * This function disconnects either all unused connections when called from + * postgres_fdw_disconnect_all or a given foreign server unused connection when + * called from postgres_fdw_disconnect. + * + * This function returns true if at least one connection is disconnected, + * otherwise false. + */ + server = GetForeignServer(entry->serverid); This seems to cause an error "cache lookup failed" if postgres_fdw_disconnect_all() is called when there is a connection in use but its server is dropped. To avoid this error, GetForeignServerExtended() with FSV_MISSING_OK should be used instead, like postgres_fdw_get_connections() does? +1. So, I changed it to GetForeignServerExtended, added an assertion for invalidation just like postgres_fdw_get_connections. I also added a test case for this, we now emit a slightly different warning for this case alone that is (errmsg("cannot close dropped server connection because it is still in use")));. This warning looks okay as we cannot show any other server name in the ouput and we know that this rare case can exist when someone drops the server in an explicit transaction. + if (entry->server_hashvalue == hashvalue && + (entry->xact_depth > 0 || result)) + { + hash_seq_term(&scan); + break; entry->server_hashvalue can be 0? If yes, since postgres_fdw_disconnect_all() specifies 0 as hashvalue, ISTM that the above condition can be true unexpectedly. Can we replace this condition with just "if (!all)"? I don't think so entry->server_hashvalue can be zero, because GetSysCacheHashValue1/CatalogCacheComputeHashValue will not return 0 as hash value. I have not seen someone comparing hashvalue with an expectation that it has 0 value, for instance see if (hashvalue == 0 || riinfo->oidHashValue == hashvalue). Having if(!all) something like below there doesn't suffice because we might call hash_seq_term, when some connection other than the given foreign server connection is in use. No because we check the following condition before reaching that code. No? + if ((all || entry->server_hashvalue == hashvalue) && I was thinking that "(entry->xact_depth > 0 || result))" condition is not necessary because "result" is set to true when xact_depth <= 0 and that condition always indicates true. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Wed, Jan 20, 2021 at 6:58 PM Fujii Masao wrote: > + * It checks if the cache has a connection for the given foreign server > that's > + * not being used within current transaction, then returns true. If the > + * connection is in use, then it emits a warning and returns false. > > The comment also should mention the case where no open connection > for the given server is found? What about rewriting this to the following? > > - > If the cached connection for the given foreign server is found and has not > been used within current transaction yet, close the connection and return > true. Even when it's found, if it's already used, keep the connection, emit > a warning and return false. If it's not found, return false. > - Done. > + * It returns true, if it closes at least one connection, otherwise false. > + * > + * It returns false, if the cache doesn't exit. > > The above second comment looks redundant. Yes. "otherwise false" means it. > + if (ConnectionHash) > + result = disconnect_cached_connections(0, true); > > Isn't it smarter to make disconnect_cached_connections() check > ConnectionHash and return false if it's NULL? If we do that, we can > simplify the code of postgres_fdw_disconnect() and _all(). Done. > + * current transaction are disconnected. Otherwise, the unused entries with > the > + * given hashvalue are disconnected. > > In the above second comment, a singular form should be used instead? > Because there must be no multiple entries with the given hashvalue. Rephrased the function comment a bit. Mentioned the _disconnect and _disconnect_all in comments because we have said enough what each of those two functions do. +/* + * Workhorse to disconnect cached connections. + * + * This function disconnects either all unused connections when called from + * postgres_fdw_disconnect_all or a given foreign server unused connection when + * called from postgres_fdw_disconnect. + * + * This function returns true if at least one connection is disconnected, + * otherwise false. + */ > + server = GetForeignServer(entry->serverid); > > This seems to cause an error "cache lookup failed" > if postgres_fdw_disconnect_all() is called when there is > a connection in use but its server is dropped. To avoid this error, > GetForeignServerExtended() with FSV_MISSING_OK should be used > instead, like postgres_fdw_get_connections() does? +1. So, I changed it to GetForeignServerExtended, added an assertion for invalidation just like postgres_fdw_get_connections. I also added a test case for this, we now emit a slightly different warning for this case alone that is (errmsg("cannot close dropped server connection because it is still in use")));. This warning looks okay as we cannot show any other server name in the ouput and we know that this rare case can exist when someone drops the server in an explicit transaction. > + if (entry->server_hashvalue == hashvalue && > + (entry->xact_depth > 0 || result)) > + { > + hash_seq_term(&scan); > + break; > > entry->server_hashvalue can be 0? If yes, since postgres_fdw_disconnect_all() > specifies 0 as hashvalue, ISTM that the above condition can be true > unexpectedly. Can we replace this condition with just "if (!all)"? I don't think so entry->server_hashvalue can be zero, because GetSysCacheHashValue1/CatalogCacheComputeHashValue will not return 0 as hash value. I have not seen someone comparing hashvalue with an expectation that it has 0 value, for instance see if (hashvalue == 0 || riinfo->oidHashValue == hashvalue). Having if(!all) something like below there doesn't suffice because we might call hash_seq_term, when some connection other than the given foreign server connection is in use. Our intention to call hash_seq_term is only when a given server is found and either it's in use or is closed. if (!all && (entry->xact_depth > 0 || result)) { hash_seq_term(&scan); break; } Given the above points, the existing check looks good to me. > +-- Closes loopback connection, returns true and issues a warning as loopback2 > +-- connection is still in use and can not be closed. > +SELECT * FROM postgres_fdw_disconnect_all(); > +WARNING: cannot close connection for server "loopback2" because it is still > in use > + postgres_fdw_disconnect_all > +- > + t > +(1 row) > > After the above test, isn't it better to call postgres_fdw_get_connections() > to check that loopback is not output? +1. > +WARNING: cannot close connection for server "loopback" because it is still > in use > +WARNING: cannot close connection for server "loopback2" because it is still > in use > > Just in the case please let me confirm that the order of these warning > me
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/20 19:17, Bharath Rupireddy wrote: On Wed, Jan 20, 2021 at 3:24 PM Fujii Masao wrote: Keeping above in mind, I feel we can do hash_seq_search(), as we do currently, even when the server name is given as input. This way, we don't need to bother much on the above points. Thoughts? Thanks for explaining this! You're right. I'd withdraw my suggestion. Attaching v14 patch set with review comments addressed. Please review it further. Thanks for updating the patch! + * It checks if the cache has a connection for the given foreign server that's + * not being used within current transaction, then returns true. If the + * connection is in use, then it emits a warning and returns false. The comment also should mention the case where no open connection for the given server is found? What about rewriting this to the following? - If the cached connection for the given foreign server is found and has not been used within current transaction yet, close the connection and return true. Even when it's found, if it's already used, keep the connection, emit a warning and return false. If it's not found, return false. - + * It returns true, if it closes at least one connection, otherwise false. + * + * It returns false, if the cache doesn't exit. The above second comment looks redundant. + if (ConnectionHash) + result = disconnect_cached_connections(0, true); Isn't it smarter to make disconnect_cached_connections() check ConnectionHash and return false if it's NULL? If we do that, we can simplify the code of postgres_fdw_disconnect() and _all(). + * current transaction are disconnected. Otherwise, the unused entries with the + * given hashvalue are disconnected. In the above second comment, a singular form should be used instead? Because there must be no multiple entries with the given hashvalue. + server = GetForeignServer(entry->serverid); This seems to cause an error "cache lookup failed" if postgres_fdw_disconnect_all() is called when there is a connection in use but its server is dropped. To avoid this error, GetForeignServerExtended() with FSV_MISSING_OK should be used instead, like postgres_fdw_get_connections() does? + if (entry->server_hashvalue == hashvalue && + (entry->xact_depth > 0 || result)) + { + hash_seq_term(&scan); + break; entry->server_hashvalue can be 0? If yes, since postgres_fdw_disconnect_all() specifies 0 as hashvalue, ISTM that the above condition can be true unexpectedly. Can we replace this condition with just "if (!all)"? +-- Closes loopback connection, returns true and issues a warning as loopback2 +-- connection is still in use and can not be closed. +SELECT * FROM postgres_fdw_disconnect_all(); +WARNING: cannot close connection for server "loopback2" because it is still in use + postgres_fdw_disconnect_all +- + t +(1 row) After the above test, isn't it better to call postgres_fdw_get_connections() to check that loopback is not output? +WARNING: cannot close connection for server "loopback" because it is still in use +WARNING: cannot close connection for server "loopback2" because it is still in use Just in the case please let me confirm that the order of these warning messages is always stable? + +postgres_fdw_disconnect(IN servername text) returns boolean I think that "IN" of "IN servername text" is not necessary. I'd like to replace "servername" with "server_name" because postgres_fdw_get_connections() uses "server_name" as the output column name. + + + When called in local session with foreign server name as input, it + discards the unused open connection previously made to the foreign server + and returns true. "unused open connection" sounds confusing to me. What about the following? - This function discards the open connection that postgres_fdw established from the local session to the foriegn server with the given name if it's not used in the current local transaction yet, and then returns true. If it's already used, the function doesn't discard the connection, emits a warning and then returns false. If there is no open connection to the given foreign server, false is returned. If no foreign server with the given name is found, an error is emitted. Example usage of the function: - +postgres=# SELECT * FROM postgres_fdw_disconnect('loopback1'); "SELECT postgres_fdw_disconnect('loopback1')" is more common? Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Wed, Jan 20, 2021 at 3:24 PM Fujii Masao wrote: > > Keeping above in mind, I feel we can do hash_seq_search(), as we do > > currently, even when the server name is given as input. This way, we > > don't need to bother much on the above points. > > > > Thoughts? > > Thanks for explaining this! You're right. I'd withdraw my suggestion. Attaching v14 patch set with review comments addressed. Please review it further. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v14-0001-postgres_fdw-function-to-discard-cached-connecti.patch Description: Binary data v14-0002-postgres_fdw-add-keep_connections-GUC-to-not-cac.patch Description: Binary data v14-0003-postgres_fdw-server-level-option-keep_connection.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/20 17:41, Bharath Rupireddy wrote: On Wed, Jan 20, 2021 at 11:53 AM Fujii Masao wrote: So, furthermore, we can use hash_search() to find the target cached connection, instead of using hash_seq_search(), when the server name is given. This would simplify the code a bit more? Of course, hash_seq_search() is necessary when closing all the connections, though. Note that the cache entry key is user mapping oid and to use hash_search() we need the user mapping oid. But in postgres_fdw_disconnect we can get server oid and we can also get user mapping id using GetUserMapping, but it requires GetUserId()/CurrentUserId as an input, I doubt we will have problems if CurrentUserId is changed somehow with the change of current user in the session. And user mapping may be dropped but still the connection can exist if it's in use, in that case GetUserMapping fails in cache lookup. And yes, disconnecting all connections requires hash_seq_search(). Keeping above in mind, I feel we can do hash_seq_search(), as we do currently, even when the server name is given as input. This way, we don't need to bother much on the above points. Thoughts? Thanks for explaining this! You're right. I'd withdraw my suggestion. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Wed, Jan 20, 2021 at 11:53 AM Fujii Masao wrote: > So, furthermore, we can use hash_search() to find the target cached > connection, instead of using hash_seq_search(), when the server name > is given. This would simplify the code a bit more? Of course, > hash_seq_search() is necessary when closing all the connections, though. Note that the cache entry key is user mapping oid and to use hash_search() we need the user mapping oid. But in postgres_fdw_disconnect we can get server oid and we can also get user mapping id using GetUserMapping, but it requires GetUserId()/CurrentUserId as an input, I doubt we will have problems if CurrentUserId is changed somehow with the change of current user in the session. And user mapping may be dropped but still the connection can exist if it's in use, in that case GetUserMapping fails in cache lookup. And yes, disconnecting all connections requires hash_seq_search(). Keeping above in mind, I feel we can do hash_seq_search(), as we do currently, even when the server name is given as input. This way, we don't need to bother much on the above points. Thoughts? > + * 2) If no input argument is provided, then it tries to disconnect all > the > + *connections. > > I'm concerned that users can easily forget to specify the argument and > accidentally discard all the connections. So, IMO, to alleviate this > situation, > what about changing the function name (only when closing all the connections) > to something postgres_fdw_disconnect_all(), like we have > pg_advisory_unlock_all() against pg_advisory_unlock()? +1. We will have two functions postgres_fdw_disconnect(server name), postgres_fdw_disconnect_all. > + if (result) > + { > + /* We closed at least one connection, others > are in use. */ > + ereport(WARNING, > + (errmsg("cannot close all > connections because some of them are still in use"))); > + } > > Sorry if this was already discussed upthread. Isn't it more helpful to > emit a warning for every connections that fail to be closed? For example, > > WARNING: cannot close connection for server "loopback1" because it is still > in use > WARNING: cannot close connection for server "loopback2" because it is still > in use > WARNING: cannot close connection for server "loopback3" because it is still > in use > ... > > This enables us to identify easily which server connections cannot be > closed for now. +1. Looks like pg_advisory_unlock is doing that. Given the fact that still in use connections are possible only in explicit txns, we might not have many still in use connections in the real world use case, so I'm okay to change that way. I will address all these comments and post an updated patch set soon. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/19 12:09, Bharath Rupireddy wrote: On Mon, Jan 18, 2021 at 9:11 PM Fujii Masao wrote: Attaching v12 patch set. 0001 is for postgres_fdw_disconnect() function, 0002 is for keep_connections GUC and 0003 is for keep_connection server level option. Thanks! Please review it further. + server = GetForeignServerByName(servername, true); + + if (!server) + ereport(ERROR, + (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST), +errmsg("foreign server \"%s\" does not exist", servername))); ISTM we can simplify this code as follows. server = GetForeignServerByName(servername, false); Done. + hash_seq_init(&scan, ConnectionHash); + while ((entry = (ConnCacheEntry *) hash_seq_search(&scan))) When the server name is specified, even if its connection is successfully closed, postgres_fdw_disconnect() scans through all the entries to check whether there are active connections. But if "result" is true and active_conn_exists is true, we can get out of this loop to avoid unnecessary scans. My initial thought was that it's possible to have two entries with the same foreign server name but with different user mappings, looks like it's not possible. I tried associating a foreign server with two different user mappings [1], then the cache entry is getting associated initially with the user mapping that comes first in the pg_user_mappings, if this user mapping is dropped then the cache entry gets invalidated, so next time the second user mapping is used. Since there's no way we can have two cache entries with the same foreign server name, we can get out of the loop when we find the cache entry match with the given server. I made the changes. So, furthermore, we can use hash_search() to find the target cached connection, instead of using hash_seq_search(), when the server name is given. This would simplify the code a bit more? Of course, hash_seq_search() is necessary when closing all the connections, though. [1] postgres=# select * from pg_user_mappings ; umid | srvid | srvname | umuser | usename | umoptions ---+---+---++-+--- 16395 | 16394 | loopback1 | 10 | bharath |-> cache entry is initially made with this user mapping. 16399 | 16394 | loopback1 | 0 | public | -> if the above user mapping is dropped, then the cache entry is made with this user mapping. + /* +* Destroy the cache if we discarded all active connections i.e. if there +* is no single active connection, which we can know while scanning the +* cached entries in the above loop. Destroying the cache is better than to +* keep it in the memory with all inactive entries in it to save some +* memory. Cache can get initialized on the subsequent queries to foreign +* server. How much memory is assumed to be saved by destroying the cache in many cases? I'm not sure if it's really worth destroying the cache to save the memory. I removed the cache destroying code, if somebody complains in future(after the feature commit), we can really revisit then. + a warning is issued and false is returned. false + is returned when there are no open connections. When there are some open + connections, but there is no connection for the given foreign server, + then false is returned. When no foreign server exists + with the given name, an error is emitted. Example usage of the function: When a non-existent server name is specified, postgres_fdw_disconnect() emits an error if there is at least one open connection, but just returns false otherwise. At least for me, this behavior looks inconsitent and strange. In that case, IMO the function always should emit an error. Done. Attaching v13 patch set, please review it further. Thanks! + * 2) If no input argument is provided, then it tries to disconnect all the + *connections. I'm concerned that users can easily forget to specify the argument and accidentally discard all the connections. So, IMO, to alleviate this situation, what about changing the function name (only when closing all the connections) to something postgres_fdw_disconnect_all(), like we have pg_advisory_unlock_all() against pg_advisory_unlock()? + if (result) + { + /* We closed at least one connection, others are in use. */ + ereport(WARNING, + (errmsg("cannot close all connections because some of them are still in use"))); + } Sorry if this was already discussed upthread. Isn't it more helpful to emit a warning for every connections that fail to be closed? For example, WARNING: cannot close connection for server "loopback1" because it is still in
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/19 9:53, Hou, Zhijie wrote: +1 to add it after "dropped (Note )", how about as follows with slight changes? dropped (Note that server name of an invalid connection can be NULL if the server is dropped), and then such . Yes, I like this one. One question is; "should" or "is" is better than "can" in this case because the server name of invalid connection is always NULL when its server is dropped? I think "dropped (Note that server name of an invalid connection will be NULL if the server is dropped), and then such ." Sounds good to me. So patch attached. +1 Thanks! I pushed the patch. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Mon, Jan 18, 2021 at 9:11 PM Fujii Masao wrote: > > Attaching v12 patch set. 0001 is for postgres_fdw_disconnect() > > function, 0002 is for keep_connections GUC and 0003 is for > > keep_connection server level option. > > Thanks! > > > > > Please review it further. > > + server = GetForeignServerByName(servername, true); > + > + if (!server) > + ereport(ERROR, > + > (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST), > +errmsg("foreign server \"%s\" does > not exist", servername))); > > ISTM we can simplify this code as follows. > > server = GetForeignServerByName(servername, false); Done. > + hash_seq_init(&scan, ConnectionHash); > + while ((entry = (ConnCacheEntry *) hash_seq_search(&scan))) > > When the server name is specified, even if its connection is successfully > closed, postgres_fdw_disconnect() scans through all the entries to check > whether there are active connections. But if "result" is true and > active_conn_exists is true, we can get out of this loop to avoid unnecessary > scans. My initial thought was that it's possible to have two entries with the same foreign server name but with different user mappings, looks like it's not possible. I tried associating a foreign server with two different user mappings [1], then the cache entry is getting associated initially with the user mapping that comes first in the pg_user_mappings, if this user mapping is dropped then the cache entry gets invalidated, so next time the second user mapping is used. Since there's no way we can have two cache entries with the same foreign server name, we can get out of the loop when we find the cache entry match with the given server. I made the changes. [1] postgres=# select * from pg_user_mappings ; umid | srvid | srvname | umuser | usename | umoptions ---+---+---++-+--- 16395 | 16394 | loopback1 | 10 | bharath |-> cache entry is initially made with this user mapping. 16399 | 16394 | loopback1 | 0 | public | -> if the above user mapping is dropped, then the cache entry is made with this user mapping. > + /* > +* Destroy the cache if we discarded all active connections i.e. if > there > +* is no single active connection, which we can know while scanning > the > +* cached entries in the above loop. Destroying the cache is better > than to > +* keep it in the memory with all inactive entries in it to save some > +* memory. Cache can get initialized on the subsequent queries to > foreign > +* server. > > How much memory is assumed to be saved by destroying the cache in > many cases? I'm not sure if it's really worth destroying the cache to save > the memory. I removed the cache destroying code, if somebody complains in future(after the feature commit), we can really revisit then. > + a warning is issued and false is returned. > false > + is returned when there are no open connections. When there are some > open > + connections, but there is no connection for the given foreign server, > + then false is returned. When no foreign server > exists > + with the given name, an error is emitted. Example usage of the > function: > > When a non-existent server name is specified, postgres_fdw_disconnect() > emits an error if there is at least one open connection, but just returns > false otherwise. At least for me, this behavior looks inconsitent and strange. > In that case, IMO the function always should emit an error. Done. Attaching v13 patch set, please review it further. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com From 0731c6244ac228818916d62cc51ea1434178c5be Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Tue, 19 Jan 2021 08:23:55 +0530 Subject: [PATCH v13] postgres_fdw function to discard cached connections This patch introduces a new function postgres_fdw_disconnect(). When called with a foreign server name, it discards the associated connection with the server. When called without any argument, it discards all the existing cached connections. --- contrib/postgres_fdw/connection.c | 147 ++ .../postgres_fdw/expected/postgres_fdw.out| 93 +++ .../postgres_fdw/postgres_fdw--1.0--1.1.sql | 10 ++ contrib/postgres_fdw/sql/postgres_fdw.sql | 35 + doc/src/sgml/postgres-fdw.sgml| 59 +++ 5 files changed, 344 insertions(+) diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c index a1404cb6bb..287a047c80 100644 --- a/contrib/postgres_fdw/connection.c +++ b/contrib/postgres_fdw/connection.c @@ -80,6 +80,7 @@ static bool xact_got_connection = false; * SQL functions */ PG_FUNCTION_INFO_V1(postgres_fdw_get_connections); +PG_FUNCTION_INFO_V1(postgres_fdw_disconnect); /* pr
RE: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
> >>> +1 to add it after "dropped (Note )", how about as follows > >>> with slight changes? > >>> > >>> dropped (Note that server name of an invalid connection can be NULL > >>> if the server is dropped), and then such . > >> > >> Yes, I like this one. One question is; "should" or "is" is better > >> than "can" in this case because the server name of invalid connection > >> is always NULL when its server is dropped? > > > > I think "dropped (Note that server name of an invalid connection will > > be NULL if the server is dropped), and then such ." > > Sounds good to me. So patch attached. +1 Best regards, houzj
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/18 22:03, Bharath Rupireddy wrote: On Mon, Jan 18, 2021 at 6:17 PM Fujii Masao wrote: +1 to add it after "dropped (Note )", how about as follows with slight changes? dropped (Note that server name of an invalid connection can be NULL if the server is dropped), and then such . Yes, I like this one. One question is; "should" or "is" is better than "can" in this case because the server name of invalid connection is always NULL when its server is dropped? I think "dropped (Note that server name of an invalid connection will be NULL if the server is dropped), and then such ." Sounds good to me. So patch attached. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION From cbe84856899f23a810fe4d42cf1cd5e46b3d6870 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Tue, 19 Jan 2021 00:56:10 +0900 Subject: [PATCH] doc: Add note about the server name of postgres_fdw_get_connections() returns. Previously the document didn't mention the case where postgres_fdw_get_connections() returns NULL in server_name column. Users might be confused about why NULL was returned. This commit adds the note that, in postgres_fdw_get_connections(), the server name of an invalid connection will be NULL if the server is dropped. Suggested-by: Zhijie Hou Author: Bharath Rupireddy Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/e7ddd14e96444fce88e47a709c196537@G08CNEXMBPEKD05.g08.fujitsu.local --- doc/src/sgml/postgres-fdw.sgml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml index 6a91926da8..9adc8d12a9 100644 --- a/doc/src/sgml/postgres-fdw.sgml +++ b/doc/src/sgml/postgres-fdw.sgml @@ -493,7 +493,9 @@ OPTIONS (ADD password_required 'false'); each connection is valid or not. false is returned if the foreign server connection is used in the current local transaction but its foreign server or user mapping is changed or - dropped, and then such invalid connection will be closed at + dropped (Note that server name of an invalid connection will be + NULL if the server is dropped), + and then such invalid connection will be closed at the end of that transaction. true is returned otherwise. If there are no open connections, no record is returned. Example usage of the function: -- 2.27.0
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/18 23:14, Bharath Rupireddy wrote: On Mon, Jan 18, 2021 at 11:44 AM Fujii Masao wrote: I will post patches for the other function postgres_fdw_disconnect, GUC and server level option later. Thanks! Attaching v12 patch set. 0001 is for postgres_fdw_disconnect() function, 0002 is for keep_connections GUC and 0003 is for keep_connection server level option. Thanks! Please review it further. + server = GetForeignServerByName(servername, true); + + if (!server) + ereport(ERROR, + (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST), +errmsg("foreign server \"%s\" does not exist", servername))); ISTM we can simplify this code as follows. server = GetForeignServerByName(servername, false); + hash_seq_init(&scan, ConnectionHash); + while ((entry = (ConnCacheEntry *) hash_seq_search(&scan))) When the server name is specified, even if its connection is successfully closed, postgres_fdw_disconnect() scans through all the entries to check whether there are active connections. But if "result" is true and active_conn_exists is true, we can get out of this loop to avoid unnecessary scans. + /* +* Destroy the cache if we discarded all active connections i.e. if there +* is no single active connection, which we can know while scanning the +* cached entries in the above loop. Destroying the cache is better than to +* keep it in the memory with all inactive entries in it to save some +* memory. Cache can get initialized on the subsequent queries to foreign +* server. How much memory is assumed to be saved by destroying the cache in many cases? I'm not sure if it's really worth destroying the cache to save the memory. + a warning is issued and false is returned. false + is returned when there are no open connections. When there are some open + connections, but there is no connection for the given foreign server, + then false is returned. When no foreign server exists + with the given name, an error is emitted. Example usage of the function: When a non-existent server name is specified, postgres_fdw_disconnect() emits an error if there is at least one open connection, but just returns false otherwise. At least for me, this behavior looks inconsitent and strange. In that case, IMO the function always should emit an error. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Mon, Jan 18, 2021 at 11:44 AM Fujii Masao wrote: > > I will post patches for the other function postgres_fdw_disconnect, > > GUC and server level option later. > > Thanks! Attaching v12 patch set. 0001 is for postgres_fdw_disconnect() function, 0002 is for keep_connections GUC and 0003 is for keep_connection server level option. Please review it further. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v12-0001-postgres_fdw-function-to-discard-cached-connecti.patch Description: Binary data v12-0002-postgres_fdw-add-keep_connections-GUC-to-not-cac.patch Description: Binary data v12-0003-postgres_fdw-server-level-option-keep_connection.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Mon, Jan 18, 2021 at 6:17 PM Fujii Masao wrote: > > +1 to add it after "dropped (Note )", how about as follows > > with slight changes? > > > > dropped (Note that server name of an invalid connection can be NULL if > > the server is dropped), and then such . > > Yes, I like this one. One question is; "should" or "is" is better than > "can" in this case because the server name of invalid connection is > always NULL when its server is dropped? I think "dropped (Note that server name of an invalid connection will be NULL if the server is dropped), and then such ." With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/18 15:37, Bharath Rupireddy wrote: On Mon, Jan 18, 2021 at 11:58 AM Fujii Masao wrote: On 2021/01/18 15:02, Hou, Zhijie wrote: We need to create the loopback3 with user mapping public, otherwise the test might become unstable as shown below. Note that loopback and loopback2 are not dropped in the test, so no problem with them. ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); DROP SERVER loopback3 CASCADE; NOTICE: drop cascades to 2 other objects -DETAIL: drop cascades to user mapping for postgres on server loopback3 +DETAIL: drop cascades to user mapping for bharath on server loopback3 Attaching v2 patch for postgres_fdw_get_connections. Please have a look. Hi I have a comment for the doc about postgres_fdw_get_connections. +postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record + + + This function returns the foreign server names of all the open + connections that postgres_fdw established from + the local session to the foreign servers. It also returns whether + each connection is valid or not. false is returned + if the foreign server connection is used in the current local + transaction but its foreign server or user mapping is changed or + dropped, and then such invalid connection will be closed at + the end of that transaction. true is returned + otherwise. If there are no open connections, no record is returned. + Example usage of the function: The doc seems does not memtion the case when the function returns NULL in server_name. Users may be a little confused about why NULL was returned. Yes, so what about adding (Note that the returned server name of invalid connection is NULL if its server is dropped) into the following (just after "dropped")? + if the foreign server connection is used in the current local + transaction but its foreign server or user mapping is changed or + dropped Or better description? +1 to add it after "dropped (Note )", how about as follows with slight changes? dropped (Note that server name of an invalid connection can be NULL if the server is dropped), and then such . Yes, I like this one. One question is; "should" or "is" is better than "can" in this case because the server name of invalid connection is always NULL when its server is dropped? Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Mon, Jan 18, 2021 at 11:58 AM Fujii Masao wrote: > > > > On 2021/01/18 15:02, Hou, Zhijie wrote: > >> We need to create the loopback3 with user mapping public, otherwise the > >> test might become unstable as shown below. Note that loopback and > >> loopback2 are not dropped in the test, so no problem with them. > >> > >> ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); DROP > >> SERVER loopback3 CASCADE; > >> NOTICE: drop cascades to 2 other objects > >> -DETAIL: drop cascades to user mapping for postgres on server loopback3 > >> +DETAIL: drop cascades to user mapping for bharath on server loopback3 > >> > >> Attaching v2 patch for postgres_fdw_get_connections. Please have a look. > > Hi > > > > I have a comment for the doc about postgres_fdw_get_connections. > > > > +postgres_fdw_get_connections(OUT server_name text, OUT > > valid boolean) returns setof record > > + > > + > > + This function returns the foreign server names of all the open > > + connections that postgres_fdw established from > > + the local session to the foreign servers. It also returns whether > > + each connection is valid or not. false is returned > > + if the foreign server connection is used in the current local > > + transaction but its foreign server or user mapping is changed or > > + dropped, and then such invalid connection will be closed at > > + the end of that transaction. true is returned > > + otherwise. If there are no open connections, no record is returned. > > + Example usage of the function: > > > > The doc seems does not memtion the case when the function returns NULL in > > server_name. > > Users may be a little confused about why NULL was returned. > > Yes, so what about adding > > (Note that the returned server name of invalid connection is NULL if its > server is dropped) > > into the following (just after "dropped")? > > + if the foreign server connection is used in the current local > + transaction but its foreign server or user mapping is changed or > + dropped > > Or better description? +1 to add it after "dropped (Note )", how about as follows with slight changes? dropped (Note that server name of an invalid connection can be NULL if the server is dropped), and then such . With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/18 15:02, Hou, Zhijie wrote: We need to create the loopback3 with user mapping public, otherwise the test might become unstable as shown below. Note that loopback and loopback2 are not dropped in the test, so no problem with them. ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); DROP SERVER loopback3 CASCADE; NOTICE: drop cascades to 2 other objects -DETAIL: drop cascades to user mapping for postgres on server loopback3 +DETAIL: drop cascades to user mapping for bharath on server loopback3 Attaching v2 patch for postgres_fdw_get_connections. Please have a look. Hi I have a comment for the doc about postgres_fdw_get_connections. +postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record + + + This function returns the foreign server names of all the open + connections that postgres_fdw established from + the local session to the foreign servers. It also returns whether + each connection is valid or not. false is returned + if the foreign server connection is used in the current local + transaction but its foreign server or user mapping is changed or + dropped, and then such invalid connection will be closed at + the end of that transaction. true is returned + otherwise. If there are no open connections, no record is returned. + Example usage of the function: The doc seems does not memtion the case when the function returns NULL in server_name. Users may be a little confused about why NULL was returned. Yes, so what about adding (Note that the returned server name of invalid connection is NULL if its server is dropped) into the following (just after "dropped")? + if the foreign server connection is used in the current local + transaction but its foreign server or user mapping is changed or + dropped Or better description? Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/18 13:46, Bharath Rupireddy wrote: On Mon, Jan 18, 2021 at 9:38 AM Fujii Masao wrote: Please review v11 further. Thanks for updating the patch! The patch for postgres_fdw_get_connections() basically looks good to me. So at first I'd like to push it. Attached is the patch that I extracted postgres_fdw_get_connections() part from 0001 patch and tweaked. Thought? Thanks. We need to create the loopback3 with user mapping public, otherwise the test might become unstable as shown below. Note that loopback and loopback2 are not dropped in the test, so no problem with them. ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); DROP SERVER loopback3 CASCADE; NOTICE: drop cascades to 2 other objects -DETAIL: drop cascades to user mapping for postgres on server loopback3 +DETAIL: drop cascades to user mapping for bharath on server loopback3 Attaching v2 patch for postgres_fdw_get_connections. Please have a look. Thanks! You're right. I pushed the v2 patch. I will post patches for the other function postgres_fdw_disconnect, GUC and server level option later. Thanks! Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
RE: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
> We need to create the loopback3 with user mapping public, otherwise the > test might become unstable as shown below. Note that loopback and > loopback2 are not dropped in the test, so no problem with them. > > ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); DROP > SERVER loopback3 CASCADE; > NOTICE: drop cascades to 2 other objects > -DETAIL: drop cascades to user mapping for postgres on server loopback3 > +DETAIL: drop cascades to user mapping for bharath on server loopback3 > > Attaching v2 patch for postgres_fdw_get_connections. Please have a look. Hi I have a comment for the doc about postgres_fdw_get_connections. +postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record + + + This function returns the foreign server names of all the open + connections that postgres_fdw established from + the local session to the foreign servers. It also returns whether + each connection is valid or not. false is returned + if the foreign server connection is used in the current local + transaction but its foreign server or user mapping is changed or + dropped, and then such invalid connection will be closed at + the end of that transaction. true is returned + otherwise. If there are no open connections, no record is returned. + Example usage of the function: The doc seems does not memtion the case when the function returns NULL in server_name. Users may be a little confused about why NULL was returned. Best regards, houzj
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Mon, Jan 18, 2021 at 9:38 AM Fujii Masao wrote: > > Please review v11 further. > > Thanks for updating the patch! > > The patch for postgres_fdw_get_connections() basically looks good to me. > So at first I'd like to push it. Attached is the patch that I extracted > postgres_fdw_get_connections() part from 0001 patch and tweaked. > Thought? Thanks. We need to create the loopback3 with user mapping public, otherwise the test might become unstable as shown below. Note that loopback and loopback2 are not dropped in the test, so no problem with them. ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); DROP SERVER loopback3 CASCADE; NOTICE: drop cascades to 2 other objects -DETAIL: drop cascades to user mapping for postgres on server loopback3 +DETAIL: drop cascades to user mapping for bharath on server loopback3 Attaching v2 patch for postgres_fdw_get_connections. Please have a look. I will post patches for the other function postgres_fdw_disconnect, GUC and server level option later. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com postgres_fdw_get_connections_v2.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/18 12:33, Bharath Rupireddy wrote: On Sun, Jan 17, 2021 at 11:30 PM Zhihong Yu wrote: This patch introduces new function postgres_fdw_disconnect() when called with a foreign server name discards the associated connections with the server name. I think the following would read better: This patch introduces a new function postgres_fdw_disconnect(). When called with a foreign server name, it discards the associated connections with the server. Thanks. I corrected the commit message. Please note the removal of the 'name' at the end - connection is with server, not server name. + if (is_in_use) + ereport(WARNING, + (errmsg("cannot close the connection because it is still in use"))); It would be better to include servername in the message. User would have provided the servername in postgres_fdw_disconnect('myserver'), I don't think we need to emit the warning again with the servername. The existing warning seems fine. + ereport(WARNING, + (errmsg("cannot close all connections because some of them are still in use"))); I think showing the number of active connections would be more informative. This can be achieved by changing active_conn_exists from bool to int (named active_conns, e.g.): + if (entry->conn && !active_conn_exists) + active_conn_exists = true; Instead of setting the bool value, active_conns can be incremented. IMO, the number of active connections is not informative, because users can not do anything with them. What's actually more informative would be to list all the server names for which the connections are active, instead of the warning - "cannot close all connections because some of them are still in use". Having said that, I feel like it's an overkill for now to do that. If required, we can enhance the warnings in future. Thoughts? Attaching v11 patch set, with changes only in 0001. The changes are commit message correction and moved the warning related code to disconnect_cached_connections from postgres_fdw_disconnect. Please review v11 further. Thanks for updating the patch! The patch for postgres_fdw_get_connections() basically looks good to me. So at first I'd like to push it. Attached is the patch that I extracted postgres_fdw_get_connections() part from 0001 patch and tweaked. Thought? Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION diff --git a/contrib/postgres_fdw/Makefile b/contrib/postgres_fdw/Makefile index ee8a80a392..c1b0cad453 100644 --- a/contrib/postgres_fdw/Makefile +++ b/contrib/postgres_fdw/Makefile @@ -14,7 +14,7 @@ PG_CPPFLAGS = -I$(libpq_srcdir) SHLIB_LINK_INTERNAL = $(libpq) EXTENSION = postgres_fdw -DATA = postgres_fdw--1.0.sql +DATA = postgres_fdw--1.0.sql postgres_fdw--1.0--1.1.sql REGRESS = postgres_fdw diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c index eaedfea9f2..a1404cb6bb 100644 --- a/contrib/postgres_fdw/connection.c +++ b/contrib/postgres_fdw/connection.c @@ -16,12 +16,14 @@ #include "access/xact.h" #include "catalog/pg_user_mapping.h" #include "commands/defrem.h" +#include "funcapi.h" #include "mb/pg_wchar.h" #include "miscadmin.h" #include "pgstat.h" #include "postgres_fdw.h" #include "storage/fd.h" #include "storage/latch.h" +#include "utils/builtins.h" #include "utils/datetime.h" #include "utils/hsearch.h" #include "utils/inval.h" @@ -74,6 +76,11 @@ static unsigned int prep_stmt_number = 0; /* tracks whether any work is needed in callback functions */ static bool xact_got_connection = false; +/* + * SQL functions + */ +PG_FUNCTION_INFO_V1(postgres_fdw_get_connections); + /* prototypes of private functions */ static void make_new_connection(ConnCacheEntry *entry, UserMapping *user); static PGconn *connect_pg_server(ForeignServer *server, UserMapping *user); @@ -1335,3 +1342,131 @@ exit: ; *result = last_res; return timed_out; } + +/* + * List active foreign server connections. + * + * This function takes no input parameter and returns setof record made of + * following values: + * - server_name - server name of active connection. In case the foreign server + * is dropped but still the connection is active, then the server name will + * be NULL in output. + * - valid - true/false representing whether the connection is valid or not. + * Note that the connections can get invalidated in pgfdw_inval_callback. + * + * No records are returned when there are no cached connections at all. + */ +Datum +postgres_fdw_get_connections(PG_FUNCTION_ARGS) +{ +#define POSTGRES_FDW_GET_CONNECTIONS_COLS 2 + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + TupleDesc tupdesc; + Tuplestorestate *tupstore; + MemoryContext per_query_ctx; + MemoryContext oldcontext; + HASH_SEQ_STATUS scan; + ConnCacheEntry *entry; +
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Sun, Jan 17, 2021 at 11:30 PM Zhihong Yu wrote: > This patch introduces new function postgres_fdw_disconnect() when > called with a foreign server name discards the associated > connections with the server name. > > I think the following would read better: > > This patch introduces a new function postgres_fdw_disconnect(). When > called with a foreign server name, it discards the associated > connections with the server. Thanks. I corrected the commit message. > Please note the removal of the 'name' at the end - connection is with server, > not server name. > > + if (is_in_use) > + ereport(WARNING, > + (errmsg("cannot close the connection because it is still > in use"))); > > It would be better to include servername in the message. User would have provided the servername in postgres_fdw_disconnect('myserver'), I don't think we need to emit the warning again with the servername. The existing warning seems fine. > + ereport(WARNING, > + (errmsg("cannot close all connections because some of > them are still in use"))); > > I think showing the number of active connections would be more informative. > This can be achieved by changing active_conn_exists from bool to int (named > active_conns, e.g.): > > + if (entry->conn && !active_conn_exists) > + active_conn_exists = true; > > Instead of setting the bool value, active_conns can be incremented. IMO, the number of active connections is not informative, because users can not do anything with them. What's actually more informative would be to list all the server names for which the connections are active, instead of the warning - "cannot close all connections because some of them are still in use". Having said that, I feel like it's an overkill for now to do that. If required, we can enhance the warnings in future. Thoughts? Attaching v11 patch set, with changes only in 0001. The changes are commit message correction and moved the warning related code to disconnect_cached_connections from postgres_fdw_disconnect. Please review v11 further. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v11-0001-postgres_fdw-functions-to-show-and-discard-cache.patch Description: Binary data v11-0002-postgres_fdw-add-keep_connections-GUC-to-not-cac.patch Description: Binary data v11-0003-postgres_fdw-server-level-option-keep_connection.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
Hi, This patch introduces new function postgres_fdw_disconnect() when called with a foreign server name discards the associated connections with the server name. I think the following would read better: This patch introduces *a* new function postgres_fdw_disconnect(). When called with a foreign server name, it discards the associated connections with the server. Please note the removal of the 'name' at the end - connection is with server, not server name. + if (is_in_use) + ereport(WARNING, + (errmsg("cannot close the connection because it is still in use"))); It would be better to include servername in the message. + ereport(WARNING, + (errmsg("cannot close all connections because some of them are still in use"))); I think showing the number of active connections would be more informative. This can be achieved by changing active_conn_exists from bool to int (named active_conns, e.g.): + if (entry->conn && !active_conn_exists) + active_conn_exists = true; Instead of setting the bool value, active_conns can be incremented. Cheers On Sat, Jan 16, 2021 at 11:39 PM Bharath Rupireddy < bharath.rupireddyforpostg...@gmail.com> wrote: > On Sat, Jan 16, 2021 at 10:36 AM Bharath Rupireddy > wrote: > > > > Please consider the v9 patch set for further review. > > > > > > Thanks for updating the patch! I reviewed only 0001 patch. > > I addressed the review comments and attached v10 patch set. Please > consider it for further review. > > > With Regards, > Bharath Rupireddy. > EnterpriseDB: http://www.enterprisedb.com >
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Sat, Jan 16, 2021 at 10:36 AM Bharath Rupireddy wrote: > > > Please consider the v9 patch set for further review. > > > > Thanks for updating the patch! I reviewed only 0001 patch. I addressed the review comments and attached v10 patch set. Please consider it for further review. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com From 3cf7d7d4d7241460997530ed01c2a53508257786 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Sun, 17 Jan 2021 12:30:22 +0530 Subject: [PATCH v10 1/3] postgres_fdw function to discard cached connections This patch introduces new function postgres_fdw_disconnect() when called with a foreign server name discards the associated connections with the server name. When called without any argument, discards all the existing cached connections. This patch also adds another function postgres_fdw_get_connections() to get the list of all cached connections by corresponding foreign server names. --- contrib/postgres_fdw/Makefile | 2 +- contrib/postgres_fdw/connection.c | 330 +- .../postgres_fdw/expected/postgres_fdw.out| 414 +- .../postgres_fdw/postgres_fdw--1.0--1.1.sql | 20 + contrib/postgres_fdw/postgres_fdw.control | 2 +- contrib/postgres_fdw/sql/postgres_fdw.sql | 160 +++ doc/src/sgml/postgres-fdw.sgml| 90 7 files changed, 999 insertions(+), 19 deletions(-) create mode 100644 contrib/postgres_fdw/postgres_fdw--1.0--1.1.sql diff --git a/contrib/postgres_fdw/Makefile b/contrib/postgres_fdw/Makefile index ee8a80a392..c1b0cad453 100644 --- a/contrib/postgres_fdw/Makefile +++ b/contrib/postgres_fdw/Makefile @@ -14,7 +14,7 @@ PG_CPPFLAGS = -I$(libpq_srcdir) SHLIB_LINK_INTERNAL = $(libpq) EXTENSION = postgres_fdw -DATA = postgres_fdw--1.0.sql +DATA = postgres_fdw--1.0.sql postgres_fdw--1.0--1.1.sql REGRESS = postgres_fdw diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c index eaedfea9f2..b6da4899ea 100644 --- a/contrib/postgres_fdw/connection.c +++ b/contrib/postgres_fdw/connection.c @@ -16,12 +16,14 @@ #include "access/xact.h" #include "catalog/pg_user_mapping.h" #include "commands/defrem.h" +#include "funcapi.h" #include "mb/pg_wchar.h" #include "miscadmin.h" #include "pgstat.h" #include "postgres_fdw.h" #include "storage/fd.h" #include "storage/latch.h" +#include "utils/builtins.h" #include "utils/datetime.h" #include "utils/hsearch.h" #include "utils/inval.h" @@ -66,6 +68,7 @@ typedef struct ConnCacheEntry * Connection cache (initialized on first use) */ static HTAB *ConnectionHash = NULL; +static bool conn_cache_destroyed = false; /* for assigning cursor numbers and prepared statement numbers */ static unsigned int cursor_number = 0; @@ -74,6 +77,12 @@ static unsigned int prep_stmt_number = 0; /* tracks whether any work is needed in callback functions */ static bool xact_got_connection = false; +/* + * SQL functions + */ +PG_FUNCTION_INFO_V1(postgres_fdw_get_connections); +PG_FUNCTION_INFO_V1(postgres_fdw_disconnect); + /* prototypes of private functions */ static void make_new_connection(ConnCacheEntry *entry, UserMapping *user); static PGconn *connect_pg_server(ForeignServer *server, UserMapping *user); @@ -95,6 +104,8 @@ static bool pgfdw_exec_cleanup_query(PGconn *conn, const char *query, static bool pgfdw_get_cleanup_result(PGconn *conn, TimestampTz endtime, PGresult **result); static bool UserMappingPasswordRequired(UserMapping *user); +static bool disconnect_cached_connections(uint32 hashvalue, bool all, + bool *is_in_use); /* * Get a PGconn which can be used to execute queries on the remote PostgreSQL @@ -127,15 +138,20 @@ GetConnection(UserMapping *user, bool will_prep_stmt) HASH_ELEM | HASH_BLOBS); /* - * Register some callback functions that manage connection cleanup. - * This should be done just once in each backend. + * Register callback functions that manage connection cleanup. This + * should be done just once in each backend. We don't register the + * callbacks again, if the connection cache is destroyed at least once + * in the backend. */ - RegisterXactCallback(pgfdw_xact_callback, NULL); - RegisterSubXactCallback(pgfdw_subxact_callback, NULL); - CacheRegisterSyscacheCallback(FOREIGNSERVEROID, - pgfdw_inval_callback, (Datum) 0); - CacheRegisterSyscacheCallback(USERMAPPINGOID, - pgfdw_inval_callback, (Datum) 0); + if (!conn_cache_destroyed) + { + RegisterXactCallback(pgfdw_xact_callback, NULL); + RegisterSubXactCallback(pgfdw_subxact_callback, NULL); + CacheRegisterSyscacheCallback(FOREIGNSERVEROID, + pgfdw_inval_callback, (Datum) 0); + CacheRegisterSyscacheCallback(USERMAPPINGOID, + pgfdw_inval_callback, (Datum) 0); + } } /* Set flag that we did GetConnection during the current transaction */ @@ -1095,6 +,13 @@ pgfdw_inval_callba
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Thu, Jan 14, 2021 at 3:52 PM Fujii Masao wrote: > On 2021/01/09 10:12, Bharath Rupireddy wrote: > > On Fri, Jan 8, 2021 at 9:55 AM Bharath Rupireddy > > wrote: > >> I will make the changes and post a new patch set soon. > > > > Attaching v9 patch set that has addressed the review comments on the > > disconnect function returning setof records, documentation changes, > > and postgres_fdw--1.0-1.1.sql changes. > > > > Please consider the v9 patch set for further review. > > Thanks for updating the patch! I reviewed only 0001 patch. > > + /* > +* Quick exit if the cache has been destroyed in > +* disconnect_cached_connections. > +*/ > + if (!ConnectionHash) > + return; > > This code is not necessary at least in pgfdw_xact_callback() and > pgfdw_subxact_callback()? Because those functions check > "if (!xact_got_connection)" before checking the above condition. Yes, if xact_got_connection is true, then ConnectionHash wouldn't have been cleaned up in disconnect_cached_connections. +1 to remove that in pgfdw_xact_callback and pgfdw_subxact_callback. But we need that check in pgfdw_inval_callback, because we may reach there after ConnectionHash is destroyed and set to NULL in disconnect_cached_connections. > + server = GetForeignServerExtended(entry->serverid, true); > > Since the type of second argument in GetForeignServerExtended() is bits16, > it's invalid to specify "true" there? Yeah. I will change it to be something like below: bits16flags = FSV_MISSING_OK; server = GetForeignServerExtended(entry->serverid, flags); > + if (no_server_conn_cnt > 0) > + { > + ereport(WARNING, > + (errmsg_plural("found an active connection > for which the foreign server would have been dropped", > + "found some active > connections for which the foreign servers would have been dropped", > + > no_server_conn_cnt), > +no_server_conn_cnt > 1 ? > +errdetail("Such connections are discarded at > the end of remote transaction.") > +: errdetail("Such connection is discarded at > the end of remote transaction."))); > > At least for me, I like returning such connections with "NULL" in server_name > column and "false" in valid column, rather than emitting a warning. Because > which would enable us to count the number of actual foreign connections > easily by using SQL, for example. +1. I was also of the similar opinion about this initially. I will change this. > +* During the first call, we initialize the function context, get the > list > +* of active connections using get_connections and store this in the > +* function's memory context so that it can live multiple calls. > +*/ > + if (SRF_IS_FIRSTCALL()) > > I guess that you used value-per-call mode to make the function return > a set result since you refered to dblink_get_pkey(). But isn't it better to > use materialize mode like dblink_get_notify() does rather than > value-per-call because this function returns not so many records? ISTM > that we can simplify postgres_fdw_get_connections() by using materialize mode. Yeah. +1 I will change it to use materialize mode. > + hash_destroy(ConnectionHash); > + ConnectionHash = NULL; > > If GetConnection() is called after ConnectionHash is destroyed, > it initialize the hashtable and registers some callback functions again > even though the same function have already been registered. This causes > same function to be registered as a callback more than once. This is > a bug. Yeah, we will register the same callbacks many times. I'm thinking to have something like below: static bool conn_cache_destroyed = false; if (!active_conn_exists) { hash_destroy(ConnectionHash); ConnectionHash = NULL; conn_cache_destroyed = true; } /* * Register callback functions that manage connection cleanup. This * should be done just once in each backend. We don't register the * callbacks again, if the connection cache is destroyed at least once * in the backend. */ if (!conn_cache_destroyed) { RegisterXactCallback(pgfdw_xact_callback, NULL); RegisterSubXactCallback(pgfdw_subxact_callback, NULL); CacheRegisterSyscacheCallback(FOREIGNSERVEROID, pgfdw_inval_callback, (Datum) 0); CacheRegisterSyscacheCallback(USERMAPPINGOID, pgfdw_inval_callback, (Datum) 0); } Thoughts? > +CREATE FUNCTION postgres_fdw_disconnect () > > Do we really want postgres_fdw_disconnect() with no argument? > IMO postgres_fdw_disconnect(
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/14 20:36, Bharath Rupireddy wrote: On Thu, Jan 14, 2021 at 3:52 PM Fujii Masao wrote: - if (!HeapTupleIsValid(tup)) - elog(ERROR, "cache lookup failed for user mapping %u", entry->key); - umform = (Form_pg_user_mapping) GETSTRUCT(tup); - server = GetForeignServer(umform->umserver); - ReleaseSysCache(tup); + server = GetForeignServer(entry->serverid); What about applying only the change about serverid, as a separate patch at first? This change itself is helpful to get rid of error "cache lookup failed" in pgfdw_reject_incomplete_xact_state_change(). Patch attached. Right, we can get rid of the "cache lookup failed for user mapping" error and also storing server oid in the cache entry is helpful for the new functions we are going to introduce. serverid_v1.patch looks good to me. Both make check and make check-world passes on my system. Thanks for the check! I pushed the patch. I will respond to other comments soon. Thanks! Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Thu, Jan 14, 2021 at 3:52 PM Fujii Masao wrote: > - if (!HeapTupleIsValid(tup)) > - elog(ERROR, "cache lookup failed for user mapping %u", > entry->key); > - umform = (Form_pg_user_mapping) GETSTRUCT(tup); > - server = GetForeignServer(umform->umserver); > - ReleaseSysCache(tup); > + server = GetForeignServer(entry->serverid); > > What about applying only the change about serverid, as a separate patch at > first? This change itself is helpful to get rid of error "cache lookup failed" > in pgfdw_reject_incomplete_xact_state_change(). Patch attached. Right, we can get rid of the "cache lookup failed for user mapping" error and also storing server oid in the cache entry is helpful for the new functions we are going to introduce. serverid_v1.patch looks good to me. Both make check and make check-world passes on my system. I will respond to other comments soon. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/09 10:12, Bharath Rupireddy wrote: On Fri, Jan 8, 2021 at 9:55 AM Bharath Rupireddy wrote: I will make the changes and post a new patch set soon. Attaching v9 patch set that has addressed the review comments on the disconnect function returning setof records, documentation changes, and postgres_fdw--1.0-1.1.sql changes. Please consider the v9 patch set for further review. Thanks for updating the patch! I reviewed only 0001 patch. + /* +* Quick exit if the cache has been destroyed in +* disconnect_cached_connections. +*/ + if (!ConnectionHash) + return; This code is not necessary at least in pgfdw_xact_callback() and pgfdw_subxact_callback()? Because those functions check "if (!xact_got_connection)" before checking the above condition. - if (!HeapTupleIsValid(tup)) - elog(ERROR, "cache lookup failed for user mapping %u", entry->key); - umform = (Form_pg_user_mapping) GETSTRUCT(tup); - server = GetForeignServer(umform->umserver); - ReleaseSysCache(tup); + server = GetForeignServer(entry->serverid); What about applying only the change about serverid, as a separate patch at first? This change itself is helpful to get rid of error "cache lookup failed" in pgfdw_reject_incomplete_xact_state_change(). Patch attached. + server = GetForeignServerExtended(entry->serverid, true); Since the type of second argument in GetForeignServerExtended() is bits16, it's invalid to specify "true" there? + if (no_server_conn_cnt > 0) + { + ereport(WARNING, + (errmsg_plural("found an active connection for which the foreign server would have been dropped", + "found some active connections for which the foreign servers would have been dropped", + no_server_conn_cnt), +no_server_conn_cnt > 1 ? +errdetail("Such connections are discarded at the end of remote transaction.") +: errdetail("Such connection is discarded at the end of remote transaction."))); At least for me, I like returning such connections with "NULL" in server_name column and "false" in valid column, rather than emitting a warning. Because which would enable us to count the number of actual foreign connections easily by using SQL, for example. +* During the first call, we initialize the function context, get the list +* of active connections using get_connections and store this in the +* function's memory context so that it can live multiple calls. +*/ + if (SRF_IS_FIRSTCALL()) I guess that you used value-per-call mode to make the function return a set result since you refered to dblink_get_pkey(). But isn't it better to use materialize mode like dblink_get_notify() does rather than value-per-call because this function returns not so many records? ISTM that we can simplify postgres_fdw_get_connections() by using materialize mode. + hash_destroy(ConnectionHash); + ConnectionHash = NULL; If GetConnection() is called after ConnectionHash is destroyed, it initialize the hashtable and registers some callback functions again even though the same function have already been registered. This causes same function to be registered as a callback more than once. This is a bug. +CREATE FUNCTION postgres_fdw_disconnect () Do we really want postgres_fdw_disconnect() with no argument? IMO postgres_fdw_disconnect() with the server name specified is enough. But I'd like to hear the opinion about that. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c index 266f66cc62..eaedfea9f2 100644 --- a/contrib/postgres_fdw/connection.c +++ b/contrib/postgres_fdw/connection.c @@ -57,6 +57,7 @@ typedef struct ConnCacheEntry boolhave_error; /* have any subxacts aborted in this xact? */ boolchanging_xact_state;/* xact state change in process */ boolinvalidated;/* true if reconnect is pending */ + Oid serverid; /* foreign server OID used to get server name */ uint32 server_hashvalue; /* hash value of foreign server OID */ uint32 mapping_hashvalue; /* hash value of user mapping OID */ } ConnCacheEntry; @@ -273,6 +274,7 @@ make_new_connection(ConnCacheEntry *entry, UserMapping *user) entry->have_error = false; entry->changing_xact_state = false; entry->invalidated = false; + entry->serverid = server->serverid; entry->server_hashvalue = GetSysCacheHashValue1(FO
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 8, 2021 at 9:55 AM Bharath Rupireddy wrote: > I will make the changes and post a new patch set soon. Attaching v9 patch set that has addressed the review comments on the disconnect function returning setof records, documentation changes, and postgres_fdw--1.0-1.1.sql changes. Please consider the v9 patch set for further review. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v9-0001-postgres_fdw-function-to-discard-cached-connectio.patch Description: Binary data v9-0002-postgres_fdw-add-keep_connections-GUC-to-not-cach.patch Description: Binary data v9-0003-postgres_fdw-server-level-option-keep_connection-.patch Description: Binary data
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Fri, Jan 8, 2021 at 7:29 AM Fujii Masao wrote: > On 2021/01/07 17:21, Bharath Rupireddy wrote: > > On Thu, Jan 7, 2021 at 9:49 AM Fujii Masao > > wrote: > >> On 2021/01/05 16:56, Bharath Rupireddy wrote: > >>> Attaching v8 patch set. Hopefully, cf bot will be happy with v8. > >>> > >>> Please consider the v8 patch set for further review. > >> -DATA = postgres_fdw--1.0.sql > >> +DATA = postgres_fdw--1.1.sql postgres_fdw--1.0--1.1.sql > >> > >> Shouldn't we leave 1.0.sql as it is and create 1.0--1.1.sql so that > >> we can run the followings? > >> > >> CREATE EXTENSION postgres_fdw VERSION "1.0"; > >> ALTER EXTENSION postgres_fdw UPDATE TO "1.1"; > > > > Yes we can. In that case, to use the new functions users have to > > update postgres_fdw to 1.1, in that case, do we need to mention in the > > documentation that to make use of the new functions, update > > postgres_fdw to version 1.1? > > But since postgres_fdw.control indicates that the default version is 1.1, > "CREATE EXTENSION postgres_fdw" installs v1.1. So basically the users > don't need to update postgres_fdw from v1.0 to v1.1. Only the users of > v1.0 need to update that to v1.1 to use new functions. No? It works this way: scenario 1: 1) create extension postgres_fdw; --> this is run before our feature i.e default_version 1.0 2) after the feature i..e default_version 1.1, users can run alter extension postgres_fdw update to "1.1"; which gets the new functions from postgres_fdw--1.0--1.1.sql. scenario 2: 1) create extension postgres_fdw; --> this is run after our feature i.e default_version 1.1, then the new functions will be installed with create extension itself, no need to run alter update to get the functions, I will make the changes and post a new patch set soon. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/07 17:21, Bharath Rupireddy wrote: On Thu, Jan 7, 2021 at 9:49 AM Fujii Masao wrote: On 2021/01/05 16:56, Bharath Rupireddy wrote: Attaching v8 patch set. Hopefully, cf bot will be happy with v8. Please consider the v8 patch set for further review. -DATA = postgres_fdw--1.0.sql +DATA = postgres_fdw--1.1.sql postgres_fdw--1.0--1.1.sql Shouldn't we leave 1.0.sql as it is and create 1.0--1.1.sql so that we can run the followings? CREATE EXTENSION postgres_fdw VERSION "1.0"; ALTER EXTENSION postgres_fdw UPDATE TO "1.1"; Yes we can. In that case, to use the new functions users have to update postgres_fdw to 1.1, in that case, do we need to mention in the documentation that to make use of the new functions, update postgres_fdw to version 1.1? But since postgres_fdw.control indicates that the default version is 1.1, "CREATE EXTENSION postgres_fdw" installs v1.1. So basically the users don't need to update postgres_fdw from v1.0 to v1.1. Only the users of v1.0 need to update that to v1.1 to use new functions. No? With the above change, the contents of postgres_fdw--1.0.sql remain as is and in postgres_fdw--1.0--1.1.sql we will have only the new function statements: Yes. /* contrib/postgres_fdw/postgres_fdw--1.0--1.1.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION postgres_fdw UPDATE TO '1.1'" to load this file. \quit CREATE FUNCTION postgres_fdw_get_connections () RETURNS text[] AS 'MODULE_PATHNAME','postgres_fdw_get_connections' LANGUAGE C STRICT PARALLEL RESTRICTED; CREATE FUNCTION postgres_fdw_disconnect () RETURNS bool AS 'MODULE_PATHNAME','postgres_fdw_disconnect' LANGUAGE C STRICT PARALLEL RESTRICTED; CREATE FUNCTION postgres_fdw_disconnect (text) RETURNS bool AS 'MODULE_PATHNAME','postgres_fdw_disconnect' LANGUAGE C STRICT PARALLEL RESTRICTED; + + Functions The document format for functions should be consistent with that in other contrib module like pgstattuple? pgstattuple has so many columns to show up in output because of that they have a table listing all the output columns and their types. The new functions introduced here have only one or none input and an output. I think, we don't need a table listing the input and output names and types. IMO, we can have something similar to what pg_visibility_map has for functions, and also an example for each function showing how it can be used. Thoughts? Sounds good. + When called in the local session, it returns an array with each element as a + pair of the foreign server names of all the open connections that are + previously made to the foreign servers and true or + false to show whether or not the connection is valid. We thought that the information about whether the connection is valid or not was useful to, for example, identify and close explicitly the long-living invalid connections because they were useless. But thanks to the recent bug fix for connection leak issue, that information would be no longer so helpful for us? False is returned only when the connection is used in this local transaction but it's marked as invalidated. In this case that connection cannot be explicitly closed because it's used in this transaction. It will be closed at the end of transaction. Thought? Yes, connection's validity can be false only when the connection gets invalidated and postgres_fdw_get_connections is called within an explicit txn i.e. begin; commit;. In implicit txn, since the invalidated connections get closed either during invalidation callback or at the end of txn, postgres_fdw_get_connections will always show valid connections. Having said that, I still feel we need the true/false for valid/invalid in the output of the postgres_fdw_get_connections, otherwise we might miss giving connection validity information to the user in a very narrow use case of explicit txn. Understood. I withdraw my suggestion and am fine to display valid/invalid information. If required, we can issue a warning whenever we see an invalid connection saying "invalid connections connections are discarded at the end of remote transaction". Thoughts? IMO it's overkill to emit such warinng message because that situation is normal one. OTOH, it seems worth documenting that. I guess that you made postgres_fdw_get_connections() return the array because the similar function dblink_get_connections() does that. But isn't it more convenient to make that return the set of records? Yes, for postgres_fdw_get_connections we can return a set of records of (server_name, valid). To do so, I can refer to dblink_get_pkey. Thoughts? Yes. Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Thu, Jan 7, 2021 at 9:49 AM Fujii Masao wrote: > On 2021/01/05 16:56, Bharath Rupireddy wrote: > > Attaching v8 patch set. Hopefully, cf bot will be happy with v8. > > > > Please consider the v8 patch set for further review. > -DATA = postgres_fdw--1.0.sql > +DATA = postgres_fdw--1.1.sql postgres_fdw--1.0--1.1.sql > > Shouldn't we leave 1.0.sql as it is and create 1.0--1.1.sql so that > we can run the followings? > > CREATE EXTENSION postgres_fdw VERSION "1.0"; > ALTER EXTENSION postgres_fdw UPDATE TO "1.1"; Yes we can. In that case, to use the new functions users have to update postgres_fdw to 1.1, in that case, do we need to mention in the documentation that to make use of the new functions, update postgres_fdw to version 1.1? With the above change, the contents of postgres_fdw--1.0.sql remain as is and in postgres_fdw--1.0--1.1.sql we will have only the new function statements: /* contrib/postgres_fdw/postgres_fdw--1.0--1.1.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION postgres_fdw UPDATE TO '1.1'" to load this file. \quit CREATE FUNCTION postgres_fdw_get_connections () RETURNS text[] AS 'MODULE_PATHNAME','postgres_fdw_get_connections' LANGUAGE C STRICT PARALLEL RESTRICTED; CREATE FUNCTION postgres_fdw_disconnect () RETURNS bool AS 'MODULE_PATHNAME','postgres_fdw_disconnect' LANGUAGE C STRICT PARALLEL RESTRICTED; CREATE FUNCTION postgres_fdw_disconnect (text) RETURNS bool AS 'MODULE_PATHNAME','postgres_fdw_disconnect' LANGUAGE C STRICT PARALLEL RESTRICTED; > + > + Functions > > The document format for functions should be consistent with > that in other contrib module like pgstattuple? pgstattuple has so many columns to show up in output because of that they have a table listing all the output columns and their types. The new functions introduced here have only one or none input and an output. I think, we don't need a table listing the input and output names and types. IMO, we can have something similar to what pg_visibility_map has for functions, and also an example for each function showing how it can be used. Thoughts? > + When called in the local session, it returns an array with each element > as a > + pair of the foreign server names of all the open connections that are > + previously made to the foreign servers and true or > + false to show whether or not the connection is valid. > > We thought that the information about whether the connection is valid or > not was useful to, for example, identify and close explicitly the long-living > invalid connections because they were useless. But thanks to the recent > bug fix for connection leak issue, that information would be no longer > so helpful for us? False is returned only when the connection is used in > this local transaction but it's marked as invalidated. In this case that > connection cannot be explicitly closed because it's used in this transaction. > It will be closed at the end of transaction. Thought? Yes, connection's validity can be false only when the connection gets invalidated and postgres_fdw_get_connections is called within an explicit txn i.e. begin; commit;. In implicit txn, since the invalidated connections get closed either during invalidation callback or at the end of txn, postgres_fdw_get_connections will always show valid connections. Having said that, I still feel we need the true/false for valid/invalid in the output of the postgres_fdw_get_connections, otherwise we might miss giving connection validity information to the user in a very narrow use case of explicit txn. If required, we can issue a warning whenever we see an invalid connection saying "invalid connections connections are discarded at the end of remote transaction". Thoughts? > I guess that you made postgres_fdw_get_connections() return the array > because the similar function dblink_get_connections() does that. But > isn't it more convenient to make that return the set of records? Yes, for postgres_fdw_get_connections we can return a set of records of (server_name, valid). To do so, I can refer to dblink_get_pkey. Thoughts? With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On 2021/01/05 16:56, Bharath Rupireddy wrote: On Sat, Jan 2, 2021 at 11:19 AM Bharath Rupireddy wrote: I'm sorry for the mess. I missed adding the new files into the v6-0001 patch. Please ignore the v6 patch set and consder the v7 patch set for further review. Note that 0002 and 0003 patches have no difference from v5 patch set. It seems like cf bot was failing on v7 patches. On Linux, it fails while building documentation in 0001 patch, I corrected that. On FreeBSD, it fails in one of the test cases I added, since it was unstable, I corrected it now. Attaching v8 patch set. Hopefully, cf bot will be happy with v8. Please consider the v8 patch set for further review. Thanks for the patch! -DATA = postgres_fdw--1.0.sql +DATA = postgres_fdw--1.1.sql postgres_fdw--1.0--1.1.sql Shouldn't we leave 1.0.sql as it is and create 1.0--1.1.sql so that we can run the followings? CREATE EXTENSION postgres_fdw VERSION "1.0"; ALTER EXTENSION postgres_fdw UPDATE TO "1.1"; + + Functions The document format for functions should be consistent with that in other contrib module like pgstattuple? + When called in the local session, it returns an array with each element as a + pair of the foreign server names of all the open connections that are + previously made to the foreign servers and true or + false to show whether or not the connection is valid. We thought that the information about whether the connection is valid or not was useful to, for example, identify and close explicitly the long-living invalid connections because they were useless. But thanks to the recent bug fix for connection leak issue, that information would be no longer so helpful for us? False is returned only when the connection is used in this local transaction but it's marked as invalidated. In this case that connection cannot be explicitly closed because it's used in this transaction. It will be closed at the end of transaction. Thought? I guess that you made postgres_fdw_get_connections() return the array because the similar function dblink_get_connections() does that. But isn't it more convenient to make that return the set of records? Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Sat, Jan 2, 2021 at 11:19 AM Bharath Rupireddy wrote: > I'm sorry for the mess. I missed adding the new files into the v6-0001 > patch. Please ignore the v6 patch set and consder the v7 patch set for > further review. Note that 0002 and 0003 patches have no difference > from v5 patch set. It seems like cf bot was failing on v7 patches. On Linux, it fails while building documentation in 0001 patch, I corrected that. On FreeBSD, it fails in one of the test cases I added, since it was unstable, I corrected it now. Attaching v8 patch set. Hopefully, cf bot will be happy with v8. Please consider the v8 patch set for further review. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com From f784809cd81ed18ecbd1b3c7e87818a00b671fa0 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Tue, 5 Jan 2021 12:36:16 +0530 Subject: [PATCH v8 1/3] postgres_fdw function to discard cached connections This patch introduces new function postgres_fdw_disconnect() when called with a foreign server name discards the associated connections with the server name. When called without any argument, discards all the existing cached connections. This patch also adds another function postgres_fdw_get_connections() to get the list of all cached connections by corresponding foreign server names. --- contrib/postgres_fdw/Makefile | 2 +- contrib/postgres_fdw/connection.c | 313 - .../postgres_fdw/expected/postgres_fdw.out| 424 +- ...dw--1.0.sql => postgres_fdw--1.0--1.1.sql} | 6 +- contrib/postgres_fdw/postgres_fdw--1.1.sql| 33 ++ contrib/postgres_fdw/postgres_fdw.control | 2 +- contrib/postgres_fdw/sql/postgres_fdw.sql | 171 +++ doc/src/sgml/postgres-fdw.sgml| 54 +++ 8 files changed, 982 insertions(+), 23 deletions(-) rename contrib/postgres_fdw/{postgres_fdw--1.0.sql => postgres_fdw--1.0--1.1.sql} (60%) create mode 100644 contrib/postgres_fdw/postgres_fdw--1.1.sql diff --git a/contrib/postgres_fdw/Makefile b/contrib/postgres_fdw/Makefile index ee8a80a392..52d3dac0bd 100644 --- a/contrib/postgres_fdw/Makefile +++ b/contrib/postgres_fdw/Makefile @@ -14,7 +14,7 @@ PG_CPPFLAGS = -I$(libpq_srcdir) SHLIB_LINK_INTERNAL = $(libpq) EXTENSION = postgres_fdw -DATA = postgres_fdw--1.0.sql +DATA = postgres_fdw--1.1.sql postgres_fdw--1.0--1.1.sql REGRESS = postgres_fdw diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c index 266f66cc62..64e1d71514 100644 --- a/contrib/postgres_fdw/connection.c +++ b/contrib/postgres_fdw/connection.c @@ -22,6 +22,7 @@ #include "postgres_fdw.h" #include "storage/fd.h" #include "storage/latch.h" +#include "utils/builtins.h" #include "utils/datetime.h" #include "utils/hsearch.h" #include "utils/inval.h" @@ -57,6 +58,8 @@ typedef struct ConnCacheEntry bool have_error; /* have any subxacts aborted in this xact? */ bool changing_xact_state; /* xact state change in process */ bool invalidated; /* true if reconnect is pending */ + /* Server oid to get the associated foreign server name. */ + Oid serverid; uint32 server_hashvalue; /* hash value of foreign server OID */ uint32 mapping_hashvalue; /* hash value of user mapping OID */ } ConnCacheEntry; @@ -73,6 +76,12 @@ static unsigned int prep_stmt_number = 0; /* tracks whether any work is needed in callback functions */ static bool xact_got_connection = false; +/* + * SQL functions + */ +PG_FUNCTION_INFO_V1(postgres_fdw_get_connections); +PG_FUNCTION_INFO_V1(postgres_fdw_disconnect); + /* prototypes of private functions */ static void make_new_connection(ConnCacheEntry *entry, UserMapping *user); static PGconn *connect_pg_server(ForeignServer *server, UserMapping *user); @@ -94,6 +103,8 @@ static bool pgfdw_exec_cleanup_query(PGconn *conn, const char *query, static bool pgfdw_get_cleanup_result(PGconn *conn, TimestampTz endtime, PGresult **result); static bool UserMappingPasswordRequired(UserMapping *user); +static bool disconnect_cached_connections(uint32 hashvalue, bool all, + bool *is_in_use); /* * Get a PGconn which can be used to execute queries on the remote PostgreSQL @@ -273,6 +284,7 @@ make_new_connection(ConnCacheEntry *entry, UserMapping *user) entry->have_error = false; entry->changing_xact_state = false; entry->invalidated = false; + entry->serverid = server->serverid; entry->server_hashvalue = GetSysCacheHashValue1(FOREIGNSERVEROID, ObjectIdGetDatum(server->serverid)); @@ -789,6 +801,13 @@ pgfdw_xact_callback(XactEvent event, void *arg) if (!xact_got_connection) return; + /* + * Quick exit if the cache has been destroyed in + * disconnect_cached_connections. + */ + if (!ConnectionHash) + return; + /* * Scan all connection cache entries to find open remote transactions, and * close them. @@ -985,6 +1004,13 @@ pgfdw_subxact_callback(SubXactEvent event, SubTransactionId mySubid, if (!x
Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit
On Sat, Jan 2, 2021 at 10:53 AM Bharath Rupireddy wrote: > Thanks for taking a look at the patches. > > On Fri, Jan 1, 2021 at 9:35 PM Zhihong Yu wrote: > > Happy new year. > > > > + appendStringInfo(&buf, "(%s, %s)", server->servername, > > +entry->invalidated ? "false" : "true"); > > > > Is it better to use 'invalidated' than 'false' in the string ? > > This point was earlier discussed in [1] and [2], but the agreement was > on having true/false [2] because of a simple reason specified in [1], > that is when some users have foreign server names as invalid or valid, > then the output is difficult to interpret which one is what. With > having true/false, it's easier. IMO, let's keep the true/false as is, > since it's also suggested in [2]. > > [1] - > https://www.postgresql.org/message-id/CALj2ACUv%3DArQXs0U9PM3YXKCeSzJ1KxRokDY0g_0aGy--kDScA%40mail.gmail.com > [2] - > https://www.postgresql.org/message-id/6da38393-6ae5-4d87-2690-11c932123403%40oss.nttdata.com > > > For the first if block of postgres_fdw_disconnect(): > > > > +* Check if the connection associated with the given foreign server > > is > > +* in use i.e. entry->xact_depth > 0. Since we can not close it, so > > +* error out. > > +*/ > > + if (is_in_use) > > + ereport(WARNING, > > > > since is_in_use is only set in the if (server) block, I think the above > > warning can be moved into that block. > > Modified that a bit. Since we error out when no server object is > found, then no need of keeping the code in else part. We could save on > some indentation > > +if (!server) > +ereport(ERROR, > +(errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST), > + errmsg("foreign server \"%s\" does not exist", > servername))); > + > +hashvalue = GetSysCacheHashValue1(FOREIGNSERVEROID, > + > ObjectIdGetDatum(server->serverid)); > +result = disconnect_cached_connections(hashvalue, false, &is_in_use); > + > +/* > + * Check if the connection associated with the given foreign server > is > + * in use i.e. entry->xact_depth > 0. Since we can not close it, so > + * error out. > + */ > +if (is_in_use) > +ereport(WARNING, > +(errmsg("cannot close the connection because it > is still in use"))); > > Attaching v6 patch set. Please have a look. I'm sorry for the mess. I missed adding the new files into the v6-0001 patch. Please ignore the v6 patch set and consder the v7 patch set for further review. Note that 0002 and 0003 patches have no difference from v5 patch set. With Regards, Bharath Rupireddy. EnterpriseDB: http://www.enterprisedb.com v7-0001-postgres_fdw-function-to-discard-cached-connectio.patch Description: Binary data v7-0002-postgres_fdw-add-keep_connections-GUC-to-not-cach.patch Description: Binary data v7-0003-postgres_fdw-server-level-option-keep_connection-.patch Description: Binary data