diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
new file mode 100644
index 6def748..a19b3df
*** a/contrib/pg_upgrade/pg_upgrade.h
--- b/contrib/pg_upgrade/pg_upgrade.h
***************
*** 64,69 ****
--- 64,75 ----
  #define TABLE_SPACE_SUBDIRS_CAT_VER 201001111
  /* postmaster/postgres -b (binary_upgrade) flag added during PG 9.1 development */
  #define BINARY_UPGRADE_SERVER_FLAG_CAT_VER 201104251
+ /*
+  * 	Visibility map changed with this 9.2 commit,
+  *	8f9fe6edce358f7904e0db119416b4d1080a83aa; pick later catalog version.
+  */
+ #define VISIBILITY_MAP_CRASHSAFE_CAT_VER 201107031
+ 
  
  /*
   * Each relation is represented by a relinfo structure.
diff --git a/contrib/pg_upgrade/relfilenode.c b/contrib/pg_upgrade/relfilenode.c
new file mode 100644
index d4a420f..df752c5
*** a/contrib/pg_upgrade/relfilenode.c
--- b/contrib/pg_upgrade/relfilenode.c
*************** transfer_single_new_db(pageCnvCtx *pageC
*** 120,128 ****
  	int			numFiles = 0;
  	int			mapnum;
  	int			fileno;
! 
  	old_dir[0] = '\0';
  
  	for (mapnum = 0; mapnum < size; mapnum++)
  	{
  		char		old_file[MAXPGPATH];
--- 120,134 ----
  	int			numFiles = 0;
  	int			mapnum;
  	int			fileno;
! 	bool		vm_crashsafe_change = false;
! 	
  	old_dir[0] = '\0';
  
+ 	/* Do not copy non-crashsafe vm files for binaries that assume crashsafety */
+ 	if (old_cluster.controldata.cat_ver < VISIBILITY_MAP_CRASHSAFE_CAT_VER &&
+ 		new_cluster.controldata.cat_ver >= VISIBILITY_MAP_CRASHSAFE_CAT_VER)
+ 		vm_crashsafe_change = true;
+ 	
  	for (mapnum = 0; mapnum < size; mapnum++)
  	{
  		char		old_file[MAXPGPATH];
*************** transfer_single_new_db(pageCnvCtx *pageC
*** 168,175 ****
  
  			for (fileno = 0; fileno < numFiles; fileno++)
  			{
  				if (strncmp(namelist[fileno]->d_name, scandir_file_pattern,
! 							strlen(scandir_file_pattern)) == 0)
  				{
  					snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir,
  							 namelist[fileno]->d_name);
--- 174,189 ----
  
  			for (fileno = 0; fileno < numFiles; fileno++)
  			{
+ 				char *vm_offset = strstr(namelist[fileno]->d_name, "_vm");
+ 				bool is_vm_file = false;
+ 
+ 				/* Is a visibility map file? (name ends with _vm) */
+ 				if (vm_offset && strlen(vm_offset) == strlen("_vm"))
+ 					is_vm_file = true;
+ 
  				if (strncmp(namelist[fileno]->d_name, scandir_file_pattern,
! 							strlen(scandir_file_pattern)) == 0 &&
! 					(!is_vm_file || !vm_crashsafe_change))
  				{
  					snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir,
  							 namelist[fileno]->d_name);
