diff options
Diffstat (limited to 'contrib/dblink/dblink.c')
-rw-r--r-- | contrib/dblink/dblink.c | 53 |
1 files changed, 53 insertions, 0 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); |