summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/dblink/dblink.c53
-rw-r--r--contrib/postgres_fdw/connection.c30
2 files changed, 82 insertions, 1 deletions
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index c1155e3911f..5a370e80b33 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -200,12 +200,33 @@ dblink_get_conn(char *conname_or_str,
if (connstr == NULL)
connstr = conname_or_str;
dblink_connstr_check(connstr);
+
+ /*
+ * We must obey fd.c's limit on non-virtual file descriptors. Assume
+ * that a PGconn represents one long-lived FD. (Doing this here also
+ * ensures that VFDs are closed if needed to make room.)
+ */
+ if (!AcquireExternalFD())
+ ereport(ERROR,
+ (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
+ errmsg("could not establish connection"),
+ errdetail("There are too many open files on the local server."),
+#ifndef WIN32
+ errhint("Raise the server's max_files_per_process and/or \"ulimit -n\" limits.")
+#else
+ errhint("Raise the server's max_files_per_process setting.")
+#endif
+ ));
+
+ /* OK to make connection */
conn = PQconnectdb(connstr);
+
if (PQstatus(conn) == CONNECTION_BAD)
{
char *msg = pchomp(PQerrorMessage(conn));
PQfinish(conn);
+ ReleaseExternalFD();
ereport(ERROR,
(errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
errmsg("could not establish connection"),
@@ -282,12 +303,32 @@ dblink_connect(PG_FUNCTION_ARGS)
/* check password in connection string if not superuser */
dblink_connstr_check(connstr);
+
+ /*
+ * We must obey fd.c's limit on non-virtual file descriptors. Assume that
+ * a PGconn represents one long-lived FD. (Doing this here also ensures
+ * that VFDs are closed if needed to make room.)
+ */
+ if (!AcquireExternalFD())
+ ereport(ERROR,
+ (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
+ errmsg("could not establish connection"),
+ errdetail("There are too many open files on the local server."),
+#ifndef WIN32
+ errhint("Raise the server's max_files_per_process and/or \"ulimit -n\" limits.")
+#else
+ errhint("Raise the server's max_files_per_process setting.")
+#endif
+ ));
+
+ /* OK to make connection */
conn = PQconnectdb(connstr);
if (PQstatus(conn) == CONNECTION_BAD)
{
msg = pchomp(PQerrorMessage(conn));
PQfinish(conn);
+ ReleaseExternalFD();
if (rconn)
pfree(rconn);
@@ -312,7 +353,10 @@ dblink_connect(PG_FUNCTION_ARGS)
else
{
if (pconn->conn)
+ {
PQfinish(pconn->conn);
+ ReleaseExternalFD();
+ }
pconn->conn = conn;
}
@@ -346,6 +390,7 @@ dblink_disconnect(PG_FUNCTION_ARGS)
dblink_conn_not_avail(conname);
PQfinish(conn);
+ ReleaseExternalFD();
if (rconn)
{
deleteConnection(conname);
@@ -780,7 +825,10 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async)
{
/* if needed, close the connection to the database */
if (freeconn)
+ {
PQfinish(conn);
+ ReleaseExternalFD();
+ }
}
PG_END_TRY();
@@ -1458,7 +1506,10 @@ dblink_exec(PG_FUNCTION_ARGS)
{
/* if needed, close the connection to the database */
if (freeconn)
+ {
PQfinish(conn);
+ ReleaseExternalFD();
+ }
}
PG_END_TRY();
@@ -2563,6 +2614,7 @@ createNewConnection(const char *name, remoteConn *rconn)
if (found)
{
PQfinish(rconn->conn);
+ ReleaseExternalFD();
pfree(rconn);
ereport(ERROR,
@@ -2604,6 +2656,7 @@ dblink_security_check(PGconn *conn, remoteConn *rconn)
if (!PQconnectionUsedPassword(conn))
{
PQfinish(conn);
+ ReleaseExternalFD();
if (rconn)
pfree(rconn);
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 29c811a80b4..a151c2c653f 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -20,6 +20,7 @@
#include "miscadmin.h"
#include "pgstat.h"
#include "postgres_fdw.h"
+#include "storage/fd.h"
#include "storage/latch.h"
#include "utils/hsearch.h"
#include "utils/inval.h"
@@ -259,10 +260,33 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
keywords[n] = values[n] = NULL;
- /* verify connection parameters and make connection */
+ /* verify the set of connection parameters */
check_conn_params(keywords, values, user);
+ /*
+ * We must obey fd.c's limit on non-virtual file descriptors. Assume
+ * that a PGconn represents one long-lived FD. (Doing this here also
+ * ensures that VFDs are closed if needed to make room.)
+ */
+ if (!AcquireExternalFD())
+ ereport(ERROR,
+ (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
+ errmsg("could not connect to server \"%s\"",
+ server->servername),
+ errdetail("There are too many open files on the local server."),
+#ifndef WIN32
+ errhint("Raise the server's max_files_per_process and/or \"ulimit -n\" limits.")
+#else
+ errhint("Raise the server's max_files_per_process setting.")
+#endif
+ ));
+
+ /* OK to make connection */
conn = PQconnectdbParams(keywords, values, false);
+
+ if (!conn)
+ ReleaseExternalFD(); /* because the PG_CATCH block won't */
+
if (!conn || PQstatus(conn) != CONNECTION_OK)
ereport(ERROR,
(errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
@@ -294,7 +318,10 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
{
/* Release PGconn data structure if we managed to create one */
if (conn)
+ {
PQfinish(conn);
+ ReleaseExternalFD();
+ }
PG_RE_THROW();
}
PG_END_TRY();
@@ -312,6 +339,7 @@ disconnect_pg_server(ConnCacheEntry *entry)
{
PQfinish(entry->conn);
entry->conn = NULL;
+ ReleaseExternalFD();
}
}