diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 0c6c3ce..f045f2b 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -24,9 +24,13 @@
 /*
  * Connection cache hash table entry
  *
- * The lookup key in this hash table is the foreign server OID plus the user
- * mapping OID.  (We use just one connection per user per foreign server,
- * so that we can ensure all scans use the same snapshot during a query.)
+ * The lookup key in this hash table is the user mapping OID. We use just one
+ * connection per foreign user per foreign server, so that we can ensure that
+ * all the scans use the same snapshot during a query. Multiple local users may
+ * use public user mapping, thus connecting to foreign server as a single
+ * foreign user specified in the public user mapping. Having user mapping OID
+ * as the key avoids creating multiple connections for different local users,
+ * all using public user mapping.
  *
  * The "conn" pointer can be NULL if we don't currently have a live connection.
  * When we do have a connection, xact_depth tracks the current depth of
@@ -35,11 +39,7 @@
  * ourselves, so that rolling back a subtransaction will kill the right
  * queries and not the wrong ones.
  */
-typedef struct ConnCacheKey
-{
-	Oid			serverid;		/* OID of foreign server */
-	Oid			userid;			/* OID of local user whose mapping we use */
-} ConnCacheKey;
+typedef Oid ConnCacheKey;
 
 typedef struct ConnCacheEntry
 {
@@ -127,8 +127,7 @@ GetConnection(ForeignServer *server, UserMapping *user,
 	xact_got_connection = true;
 
 	/* Create hash key for the entry.  Assume no pad bytes in key struct */
-	key.serverid = server->serverid;
-	key.userid = user->userid;
+	key = user->umid;
 
 	/*
 	 * Find or create cached entry for requested connection.
@@ -160,8 +159,9 @@ GetConnection(ForeignServer *server, UserMapping *user,
 		entry->have_prep_stmt = false;
 		entry->have_error = false;
 		entry->conn = connect_pg_server(server, user);
-		elog(DEBUG3, "new postgres_fdw connection %p for server \"%s\"",
-			 entry->conn, server->servername);
+
+		elog(DEBUG3, "new postgres_fdw connection %p for server \"%s\ (user mapping oid %d, userid %d)",
+			 entry->conn, server->servername, user->umid, user->userid);
 	}
 
 	/*
diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c
index 14e082b..73c40af 100644
--- a/src/backend/foreign/foreign.c
+++ b/src/backend/foreign/foreign.c
@@ -195,6 +195,7 @@ GetUserMapping(Oid userid, Oid serverid)
 	um = (UserMapping *) palloc(sizeof(UserMapping));
 	um->userid = userid;
 	um->serverid = serverid;
+	um->umid = HeapTupleGetOid(tp);
 
 	/* Extract the umoptions */
 	datum = SysCacheGetAttr(USERMAPPINGUSERSERVER,
diff --git a/src/include/foreign/foreign.h b/src/include/foreign/foreign.h
index 2c1ada1..7767913 100644
--- a/src/include/foreign/foreign.h
+++ b/src/include/foreign/foreign.h
@@ -57,6 +57,7 @@ typedef struct UserMapping
 {
 	Oid			userid;			/* local user Oid */
 	Oid			serverid;		/* server Oid */
+	Oid			umid;			/* Oid of user mapping */
 	List	   *options;		/* useoptions as DefElem list */
 } UserMapping;
 
