Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit411ae64

Browse files
committed
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 discardsthe cached connections to the specified foreign server. The latter discardsall the cached connections. If the connection is used in the currenttransaction, it's not closed and a warning message is emitted.For example, these functions are useful when users want to explicitlyclose the foreign server connections that are no longer necessary andthen to prevent them from eating up the foreign servers connectionscapacity.Author: Bharath Rupireddy, tweaked a bit by Fujii MasaoReviewed-by: Alexey Kondratov, Zhijie Hou, Zhihong Yu, Fujii MasaoDiscussion:https://postgr.es/m/CALj2ACVvrp5=AVp2PupEm+nAC8S4buqR3fJMmaCoc7ftT0aD2A@mail.gmail.com
1 parentee895a6 commit411ae64

File tree

5 files changed

+505
-13
lines changed

5 files changed

+505
-13
lines changed

‎contrib/postgres_fdw/connection.c

Lines changed: 132 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ static bool xact_got_connection = false;
8080
* SQL functions
8181
*/
8282
PG_FUNCTION_INFO_V1(postgres_fdw_get_connections);
83+
PG_FUNCTION_INFO_V1(postgres_fdw_disconnect);
84+
PG_FUNCTION_INFO_V1(postgres_fdw_disconnect_all);
8385

8486
/* prototypes of private functions */
8587
staticvoidmake_new_connection(ConnCacheEntry*entry,UserMapping*user);
@@ -102,6 +104,7 @@ static bool pgfdw_exec_cleanup_query(PGconn *conn, const char *query,
102104
staticboolpgfdw_get_cleanup_result(PGconn*conn,TimestampTzendtime,
103105
PGresult**result);
104106
staticboolUserMappingPasswordRequired(UserMapping*user);
107+
staticbooldisconnect_cached_connections(Oidserverid);
105108

106109
/*
107110
* 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)
14281431
* Even though the server is dropped in the current transaction, the
14291432
* cache can still have associated active connection entry, say we
14301433
* call such connections dangling. Since we can not fetch the server
1431-
* name from system catalogs for dangling connections, instead we
1432-
*showNULL value for server name in output.
1434+
* name from system catalogs for dangling connections, instead we show
1435+
* NULL value for server name in output.
14331436
*
14341437
* We could have done better by storing the server name in the cache
14351438
* 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)
14471450
/*
14481451
* If the server has been dropped in the current explicit
14491452
* transaction, then this entry would have been invalidated in
1450-
* pgfdw_inval_callback at the end of dropsever command. Note
1453+
* pgfdw_inval_callback at the end of dropserver command. Note
14511454
* that this connection would not have been closed in
14521455
* pgfdw_inval_callback because it is still being used in the
14531456
* current explicit transaction. So, assert that here.
@@ -1470,3 +1473,129 @@ postgres_fdw_get_connections(PG_FUNCTION_ARGS)
14701473

14711474
PG_RETURN_VOID();
14721475
}
1476+
1477+
/*
1478+
* Disconnect the specified cached connections.
1479+
*
1480+
* This function discards the open connections that are established by
1481+
* postgres_fdw from the local session to the foreign server with
1482+
* the given name. Note that there can be multiple connections to
1483+
* the given server using different user mappings. If the connections
1484+
* are used in the current local transaction, they are not disconnected
1485+
* and warning messages are reported. This function returns true
1486+
* if it disconnects at least one connection, otherwise false. If no
1487+
* foreign server with the given name is found, an error is reported.
1488+
*/
1489+
Datum
1490+
postgres_fdw_disconnect(PG_FUNCTION_ARGS)
1491+
{
1492+
ForeignServer*server;
1493+
char*servername;
1494+
1495+
servername=text_to_cstring(PG_GETARG_TEXT_PP(0));
1496+
server=GetForeignServerByName(servername, false);
1497+
1498+
PG_RETURN_BOOL(disconnect_cached_connections(server->serverid));
1499+
}
1500+
1501+
/*
1502+
* Disconnect all the cached connections.
1503+
*
1504+
* This function discards all the open connections that are established by
1505+
* postgres_fdw from the local session to the foreign servers.
1506+
* If the connections are used in the current local transaction, they are
1507+
* not disconnected and warning messages are reported. This function
1508+
* returns true if it disconnects at least one connection, otherwise false.
1509+
*/
1510+
Datum
1511+
postgres_fdw_disconnect_all(PG_FUNCTION_ARGS)
1512+
{
1513+
PG_RETURN_BOOL(disconnect_cached_connections(InvalidOid));
1514+
}
1515+
1516+
/*
1517+
* Workhorse to disconnect cached connections.
1518+
*
1519+
* This function scans all the connection cache entries and disconnects
1520+
* the open connections whose foreign server OID matches with
1521+
* the specified one. If InvalidOid is specified, it disconnects all
1522+
* the cached connections.
1523+
*
1524+
* This function emits a warning for each connection that's used in
1525+
* the current transaction and doesn't close it. It returns true if
1526+
* it disconnects at least one connection, otherwise false.
1527+
*
1528+
* Note that this function disconnects even the connections that are
1529+
* established by other users in the same local session using different
1530+
* user mappings. This leads even non-superuser to be able to close
1531+
* the connections established by superusers in the same local session.
1532+
*
1533+
* XXX As of now we don't see any security risk doing this. But we should
1534+
* set some restrictions on that, for example, prevent non-superuser
1535+
* from closing the connections established by superusers even
1536+
* in the same session?
1537+
*/
1538+
staticbool
1539+
disconnect_cached_connections(Oidserverid)
1540+
{
1541+
HASH_SEQ_STATUSscan;
1542+
ConnCacheEntry*entry;
1543+
boolall= !OidIsValid(serverid);
1544+
boolresult= false;
1545+
1546+
/*
1547+
* Connection cache hashtable has not been initialized yet in this
1548+
* session, so return false.
1549+
*/
1550+
if (!ConnectionHash)
1551+
return false;
1552+
1553+
hash_seq_init(&scan,ConnectionHash);
1554+
while ((entry= (ConnCacheEntry*)hash_seq_search(&scan)))
1555+
{
1556+
/* Ignore cache entry if no open connection right now. */
1557+
if (!entry->conn)
1558+
continue;
1559+
1560+
if (all||entry->serverid==serverid)
1561+
{
1562+
/*
1563+
* Emit a warning because the connection to close is used in the
1564+
* current transaction and cannot be disconnected right now.
1565+
*/
1566+
if (entry->xact_depth>0)
1567+
{
1568+
ForeignServer*server;
1569+
1570+
server=GetForeignServerExtended(entry->serverid,
1571+
FSV_MISSING_OK);
1572+
1573+
if (!server)
1574+
{
1575+
/*
1576+
* If the foreign server was dropped while its connection
1577+
* was used in the current transaction, the connection
1578+
* must have been marked as invalid by
1579+
* pgfdw_inval_callback at the end of DROP SERVER command.
1580+
*/
1581+
Assert(entry->invalidated);
1582+
1583+
ereport(WARNING,
1584+
(errmsg("cannot close dropped server connection because it is still in use")));
1585+
}
1586+
else
1587+
ereport(WARNING,
1588+
(errmsg("cannot close connection for server \"%s\" because it is still in use",
1589+
server->servername)));
1590+
}
1591+
else
1592+
{
1593+
elog(DEBUG3,"discarding connection %p",entry->conn);
1594+
disconnect_pg_server(entry);
1595+
result= true;
1596+
}
1597+
}
1598+
}
1599+
1600+
returnresult;
1601+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp