*** a/contrib/postgres_fdw/connection.c
--- b/contrib/postgres_fdw/connection.c
***************
*** 53,58 **** typedef struct ConnCacheEntry
--- 53,61 ----
  	bool		have_prep_stmt; /* have we prepared any stmts in this xact? */
  	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 requried */
+ 	uint32		server_hashvalue;	/* hash value of foreign server oid */
+ 	uint32		mapping_hashvalue;  /* hash value of user mapping oid */
  } ConnCacheEntry;
  
  /*
***************
*** 150,160 **** GetConnection(UserMapping *user, bool will_prep_stmt)
--- 153,180 ----
  		entry->have_prep_stmt = false;
  		entry->have_error = false;
  		entry->changing_xact_state = false;
+ 		entry->invalidated = false;
+ 		entry->server_hashvalue = 0;
+ 		entry->mapping_hashvalue = 0;
  	}
  
  	/* Reject further use of connections which failed abort cleanup. */
  	pgfdw_reject_incomplete_xact_state_change(entry);
  
+ 
+ 	/*
+ 	 * This connection is no longer valid. Disconnect such connections if no
+ 	 * transaction is running. We could avoid suporious disconnection by
+ 	 * examining individual option values but it would be too-much for the
+ 	 * gain.
+ 	 */
+ 	if (entry->conn != NULL && entry->invalidated && entry->xact_depth == 0)
+ 	{
+ 		PQfinish(entry->conn);
+ 		entry->conn = NULL;
+ 		entry->invalidated = false;
+ 	}
+ 
  	/*
  	 * We don't check the health of cached connection here, because it would
  	 * require some overhead.  Broken connection will be detected when the
***************
*** 173,178 **** GetConnection(UserMapping *user, bool will_prep_stmt)
--- 193,202 ----
  		entry->xact_depth = 0;	/* just to be sure */
  		entry->have_prep_stmt = false;
  		entry->have_error = false;
+ 		entry->server_hashvalue =
+ 			GetSysCacheHashValue1(FOREIGNSERVEROID, server->serverid);
+ 		entry->mapping_hashvalue =
+ 			GetSysCacheHashValue1(USERMAPPINGOID, user->umid);
  		entry->conn = connect_pg_server(server, user);
  
  		elog(DEBUG3, "new postgres_fdw connection %p for server \"%s\" (user mapping oid %u, userid %u)",
***************
*** 429,434 **** ReleaseConnection(PGconn *conn)
--- 453,514 ----
  }
  
  /*
+  * Connection invalidation functions.
+  *
+  * Changes of some options of foreign server or user mapping that a connection
+  * depends on requires the connection to be disconnected at an oppotunity. The
+  * parameter is the hash value of target syscache entry given through syscache
+  * invalidation.
+  */
+ 
+ /* Connection invalidation by modifying foreign server options. */
+ void
+ InvalidateConnectionForServer(uint32 server_hashvalue)
+ {
+ 	HASH_SEQ_STATUS scan;
+ 	ConnCacheEntry *entry;
+ 
+ 	if (!ConnectionHash)
+ 		return;
+ 
+ 	hash_seq_init(&scan, ConnectionHash);
+ 	while ((entry = (ConnCacheEntry *) hash_seq_search(&scan)))
+ 	{
+ 		if (entry->conn != NULL &&
+ 			entry->server_hashvalue == server_hashvalue)
+ 		{
+ 			entry->invalidated = true;
+ 			hash_seq_term(&scan);
+ 			break;
+ 		}
+ 	}
+ }
+ 
+ /* Connection invalidation by modifying user mapping options. */
+ void
+ InvalidateConnectionForMapping(uint32 mapping_hashvalue)
+ {
+ 	HASH_SEQ_STATUS scan;
+ 	ConnCacheEntry *entry;
+ 
+ 	if (!ConnectionHash)
+ 		return;
+ 
+ 	hash_seq_init(&scan, ConnectionHash);
+ 	while ((entry = (ConnCacheEntry *) hash_seq_search(&scan)))
+ 	{
+ 		if (entry->conn != NULL &&
+ 			entry->mapping_hashvalue == mapping_hashvalue)
+ 		{
+ 			entry->invalidated = true;
+ 			hash_seq_term(&scan);
+ 			break;
+ 		}
+ 	}
+ }
+ 
+ 
+ /*
   * Assign a "unique" number for a cursor.
   *
   * These really only need to be unique per connection within a transaction.
*** a/contrib/postgres_fdw/postgres_fdw.c
--- b/contrib/postgres_fdw/postgres_fdw.c
***************
*** 36,41 ****
--- 36,43 ----
  #include "parser/parsetree.h"
  #include "utils/builtins.h"
  #include "utils/guc.h"
+ #include "utils/inval.h"
+ #include "utils/syscache.h"
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
  #include "utils/rel.h"
***************
*** 420,425 **** static void merge_fdw_options(PgFdwRelationInfo *fpinfo,
--- 422,429 ----
  				  const PgFdwRelationInfo *fpinfo_o,
  				  const PgFdwRelationInfo *fpinfo_i);
  
+ void		_PG_init(void);
+ void		_PG_fini(void);
  
  /*
   * Foreign-data wrapper handler function: return a struct with pointers
***************
*** 476,481 **** postgres_fdw_handler(PG_FUNCTION_ARGS)
--- 480,514 ----
  }
  
  /*
+  *  Callback functions for connection invalidation by syscache invalidation
+  */
+ static void
+ postgresServerSysCallback(Datum arg, int cacheid, uint32 hashvalue)
+ {
+ 	InvalidateConnectionForServer(hashvalue);
+ }
+ 
+ static void
+ postgresMappingSysCallback(Datum arg, int cacheid, uint32 hashvalue)
+ {
+ 	InvalidateConnectionForMapping(hashvalue);
+ }
+ 
+ void
+ _PG_init(void)
+ {
+ 	CacheRegisterSyscacheCallback(FOREIGNSERVEROID,
+ 								  postgresServerSysCallback, (Datum)0);
+ 	CacheRegisterSyscacheCallback(USERMAPPINGOID,
+ 								  postgresMappingSysCallback, (Datum)0);
+ }
+ 
+ void
+ _PG_fini(void)
+ {
+ }
+ 
+ /*
   * postgresGetForeignRelSize
   *		Estimate # of rows and width of the result of the scan
   *
*** a/contrib/postgres_fdw/postgres_fdw.h
--- b/contrib/postgres_fdw/postgres_fdw.h
***************
*** 117,122 **** extern void reset_transmission_modes(int nestlevel);
--- 117,124 ----
  /* in connection.c */
  extern PGconn *GetConnection(UserMapping *user, bool will_prep_stmt);
  extern void ReleaseConnection(PGconn *conn);
+ extern void InvalidateConnectionForServer(uint32 server_hashvalue);
+ extern void InvalidateConnectionForMapping(uint32 mapping_hashvalue);
  extern unsigned int GetCursorNumber(PGconn *conn);
  extern unsigned int GetPrepStmtNumber(PGconn *conn);
  extern PGresult *pgfdw_get_result(PGconn *conn, const char *query);
