Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit

2021-04-02 Thread Fujii Masao




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

2021-04-01 Thread Fujii Masao




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

2021-04-01 Thread Bharath Rupireddy
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

2021-04-01 Thread Fujii Masao



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

2021-02-21 Thread Bharath Rupireddy
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

2021-02-03 Thread Bharath Rupireddy
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

2021-02-03 Thread Fujii Masao




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

2021-02-02 Thread Bharath Rupireddy
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

2021-02-01 Thread Fujii Masao




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

2021-02-01 Thread Fujii Masao




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

2021-01-31 Thread Bharath Rupireddy
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

2021-01-31 Thread Bharath Rupireddy
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

2021-01-31 Thread Fujii Masao




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

2021-01-31 Thread Fujii Masao




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

2021-01-29 Thread Bharath Rupireddy
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

2021-01-29 Thread Fujii Masao



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

2021-01-29 Thread Bharath Rupireddy
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

2021-01-28 Thread Bharath Rupireddy
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

2021-01-28 Thread Fujii Masao




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

2021-01-28 Thread Bharath Rupireddy
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

2021-01-28 Thread Fujii Masao




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

2021-01-28 Thread Bharath Rupireddy
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

2021-01-28 Thread Fujii Masao




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

2021-01-28 Thread Bharath Rupireddy
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

2021-01-28 Thread Fujii Masao




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

2021-01-28 Thread Bharath Rupireddy
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

2021-01-28 Thread Bharath Rupireddy
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

2021-01-28 Thread Bharath Rupireddy
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

2021-01-28 Thread Fujii Masao




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

2021-01-28 Thread Bharath Rupireddy
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

2021-01-28 Thread Bharath Rupireddy
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

2021-01-28 Thread Fujii Masao




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

2021-01-28 Thread Tom Lane
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

2021-01-28 Thread Bharath Rupireddy
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

2021-01-28 Thread Tom Lane
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

2021-01-26 Thread Bharath Rupireddy
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

2021-01-26 Thread Bharath Rupireddy
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

2021-01-26 Thread Fujii Masao




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

2021-01-26 Thread Bharath Rupireddy
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

2021-01-25 Thread Fujii Masao




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

2021-01-25 Thread Fujii Masao




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

2021-01-25 Thread Bharath Rupireddy
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

2021-01-25 Thread Fujii Masao




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

2021-01-25 Thread Tom Lane
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

2021-01-25 Thread Fujii Masao




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

2021-01-25 Thread Bharath Rupireddy
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

2021-01-25 Thread Fujii Masao



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

2021-01-25 Thread Bharath Rupireddy
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

2021-01-25 Thread Bharath Rupireddy
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

2021-01-25 Thread Fujii Masao




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

2021-01-25 Thread Bharath Rupireddy
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

2021-01-25 Thread Fujii Masao




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

2021-01-25 Thread Bharath Rupireddy
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

2021-01-24 Thread Fujii Masao




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

2021-01-22 Thread Bharath Rupireddy
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

2021-01-22 Thread Fujii Masao




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

2021-01-21 Thread Fujii Masao




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

2021-01-21 Thread Bharath Rupireddy
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

2021-01-21 Thread Fujii Masao




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

2021-01-20 Thread Bharath Rupireddy
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

2021-01-20 Thread Fujii Masao




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

2021-01-20 Thread Hou, Zhijie
> > > 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

2021-01-20 Thread Bharath Rupireddy
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

2021-01-20 Thread Bharath Rupireddy
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

2021-01-20 Thread Hou, Zhijie
> 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

2021-01-20 Thread Fujii Masao




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

2021-01-20 Thread Bharath Rupireddy
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

2021-01-20 Thread Fujii Masao




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

2021-01-20 Thread Bharath Rupireddy
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

2021-01-20 Thread Fujii Masao




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

2021-01-20 Thread Bharath Rupireddy
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

2021-01-19 Thread Fujii Masao




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

2021-01-18 Thread Fujii Masao




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

2021-01-18 Thread Bharath Rupireddy
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

2021-01-18 Thread Hou, Zhijie
> >>> +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

2021-01-18 Thread Fujii Masao



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

2021-01-18 Thread Fujii Masao




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

2021-01-18 Thread Bharath Rupireddy
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

2021-01-18 Thread Bharath Rupireddy
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

2021-01-18 Thread Fujii Masao




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

2021-01-17 Thread Bharath Rupireddy
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

2021-01-17 Thread Fujii Masao




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

2021-01-17 Thread Fujii Masao




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

2021-01-17 Thread Hou, Zhijie
> 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

2021-01-17 Thread Bharath Rupireddy
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

2021-01-17 Thread Fujii Masao



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

2021-01-17 Thread Bharath Rupireddy
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

2021-01-17 Thread Zhihong Yu
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

2021-01-16 Thread Bharath Rupireddy
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

2021-01-15 Thread Bharath Rupireddy
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

2021-01-14 Thread Fujii Masao




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

2021-01-14 Thread Bharath Rupireddy
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

2021-01-14 Thread Fujii Masao



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

2021-01-08 Thread Bharath Rupireddy
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

2021-01-07 Thread Bharath Rupireddy
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

2021-01-07 Thread Fujii Masao




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

2021-01-07 Thread Bharath Rupireddy
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

2021-01-06 Thread Fujii Masao




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

2021-01-04 Thread Bharath Rupireddy
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

2021-01-01 Thread Bharath Rupireddy
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


  1   2   >