diff --git a/src/backend/access/transam/twophase_rmgr.c b/src/backend/access/transam/twophase_rmgr.c
index c8564468bc938dcfa5cb7d6d9387d539ebf19852..49c485a966bd586fba5218032ed918ab581535db 100644
--- a/src/backend/access/transam/twophase_rmgr.c
+++ b/src/backend/access/transam/twophase_rmgr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/transam/twophase_rmgr.c,v 1.8 2009/01/01 17:23:36 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/transam/twophase_rmgr.c,v 1.9 2009/09/01 02:54:51 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,7 +18,6 @@
 #include "commands/async.h"
 #include "pgstat.h"
 #include "storage/lock.h"
-#include "utils/flatfiles.h"
 #include "utils/inval.h"
 
 
@@ -27,7 +26,6 @@ const TwoPhaseCallback twophase_recover_callbacks[TWOPHASE_RM_MAX_ID + 1] =
 	NULL,						/* END ID */
 	lock_twophase_recover,		/* Lock */
 	NULL,						/* Inval */
-	NULL,						/* flat file update */
 	NULL,						/* notify/listen */
 	NULL						/* pgstat */
 };
@@ -37,7 +35,6 @@ const TwoPhaseCallback twophase_postcommit_callbacks[TWOPHASE_RM_MAX_ID + 1] =
 	NULL,						/* END ID */
 	lock_twophase_postcommit,	/* Lock */
 	inval_twophase_postcommit,	/* Inval */
-	flatfile_twophase_postcommit,		/* flat file update */
 	notify_twophase_postcommit, /* notify/listen */
 	pgstat_twophase_postcommit	/* pgstat */
 };
@@ -47,7 +44,6 @@ const TwoPhaseCallback twophase_postabort_callbacks[TWOPHASE_RM_MAX_ID + 1] =
 	NULL,						/* END ID */
 	lock_twophase_postabort,	/* Lock */
 	NULL,						/* Inval */
-	NULL,						/* flat file update */
 	NULL,						/* notify/listen */
 	pgstat_twophase_postabort	/* pgstat */
 };
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 2b6a22247753f2de4778eab5f114c0cb6ae60ed7..4bf980dbd5fd336cb36f4b07a3fbe7e8e5ab8297 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.274 2009/06/11 14:48:54 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.275 2009/09/01 02:54:51 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -43,7 +43,6 @@
 #include "storage/sinvaladt.h"
 #include "storage/smgr.h"
 #include "utils/combocid.h"
-#include "utils/flatfiles.h"
 #include "utils/guc.h"
 #include "utils/inval.h"
 #include "utils/memutils.h"
@@ -1608,12 +1607,6 @@ CommitTransaction(void)
 	/* NOTIFY commit must come before lower-level cleanup */
 	AtCommit_Notify();
 
-	/*
-	 * Update flat files if we changed pg_database, pg_authid or
-	 * pg_auth_members.  This should be the last step before commit.
-	 */
-	AtEOXact_UpdateFlatFiles(true);
-
 	/* Prevent cancel/die interrupt while cleaning up */
 	HOLD_INTERRUPTS();
 
@@ -1797,7 +1790,7 @@ PrepareTransaction(void)
 	/* close large objects before lower-level cleanup */
 	AtEOXact_LargeObject(true);
 
-	/* NOTIFY and flatfiles will be handled below */
+	/* NOTIFY will be handled below */
 
 	/*
 	 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
@@ -1860,7 +1853,6 @@ PrepareTransaction(void)
 	StartPrepare(gxact);
 
 	AtPrepare_Notify();
-	AtPrepare_UpdateFlatFiles();
 	AtPrepare_Inval();
 	AtPrepare_Locks();
 	AtPrepare_PgStat();
@@ -1909,7 +1901,7 @@ PrepareTransaction(void)
 	/* Clean up the snapshot manager */
 	AtEarlyCommit_Snapshot();
 
-	/* notify and flatfiles don't need a postprepare call */
+	/* notify doesn't need a postprepare call */
 
 	PostPrepare_PgStat();
 
@@ -2036,7 +2028,6 @@ AbortTransaction(void)
 	AtAbort_Portals();
 	AtEOXact_LargeObject(false);	/* 'false' means it's abort */
 	AtAbort_Notify();
-	AtEOXact_UpdateFlatFiles(false);
 
 	/*
 	 * Advertise the fact that we aborted in pg_clog (assuming that we got as
@@ -3764,8 +3755,6 @@ CommitSubTransaction(void)
 	AtEOSubXact_LargeObject(true, s->subTransactionId,
 							s->parent->subTransactionId);
 	AtSubCommit_Notify();
-	AtEOSubXact_UpdateFlatFiles(true, s->subTransactionId,
-								s->parent->subTransactionId);
 
 	CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
 						 s->parent->subTransactionId);
@@ -3885,8 +3874,6 @@ AbortSubTransaction(void)
 		AtEOSubXact_LargeObject(false, s->subTransactionId,
 								s->parent->subTransactionId);
 		AtSubAbort_Notify();
-		AtEOSubXact_UpdateFlatFiles(false, s->subTransactionId,
-									s->parent->subTransactionId);
 
 		/* Advertise the fact that we aborted in pg_clog. */
 		(void) RecordTransactionAbort(true);
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 7f675a985cb8d8a93289532db3ee551ad8bf0fa3..f401dbd0f7a02b0163a0e64836e2c71e88d345d4 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.350 2009/08/31 02:23:22 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.351 2009/09/01 02:54:51 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -49,7 +49,6 @@
 #include "storage/smgr.h"
 #include "storage/spin.h"
 #include "utils/builtins.h"
-#include "utils/flatfiles.h"
 #include "utils/guc.h"
 #include "utils/ps_status.h"
 #include "pg_trace.h"
@@ -8077,8 +8076,6 @@ StartupProcessMain(void)
 
 	StartupXLOG();
 
-	BuildFlatFiles(false);
-
 	/*
 	 * Exit normally. Exit code 0 tells postmaster that we completed recovery
 	 * successfully.
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 1ea84fdbb2dbbefd376e7dea7bcf104b90177b6a..2e6edc4832e2fbbc6ba2eed8d756623ea5769ffd 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.225 2009/06/11 14:48:55 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.226 2009/09/01 02:54:51 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -49,7 +49,6 @@
 #include "storage/smgr.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
-#include "utils/flatfiles.h"
 #include "utils/fmgroids.h"
 #include "utils/guc.h"
 #include "utils/lsyscache.h"
@@ -691,19 +690,17 @@ createdb(const CreatedbStmt *stmt)
 		RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT);
 
 		/*
-		 * Close pg_database, but keep lock till commit (this is important to
-		 * prevent any risk of deadlock failure while updating flat file)
+		 * Close pg_database, but keep lock till commit.
 		 */
 		heap_close(pg_database_rel, NoLock);
 
 		/*
-		 * Set flag to update flat database file at commit.  Note: this also
-		 * forces synchronous commit, which minimizes the window between
+		 * Force synchronous commit, thus minimizing the window between
 		 * creation of the database files and commital of the transaction. If
 		 * we crash before committing, we'll have a DB that's taking up disk
 		 * space but is not in pg_database, which is not good.
 		 */
-		database_file_update_needed();
+		ForceSyncCommit();
 	}
 	PG_END_ENSURE_ERROR_CLEANUP(createdb_failure_callback,
 								PointerGetDatum(&fparms));
@@ -862,19 +859,17 @@ dropdb(const char *dbname, bool missing_ok)
 	remove_dbtablespaces(db_id);
 
 	/*
-	 * Close pg_database, but keep lock till commit (this is important to
-	 * prevent any risk of deadlock failure while updating flat file)
+	 * Close pg_database, but keep lock till commit.
 	 */
 	heap_close(pgdbrel, NoLock);
 
 	/*
-	 * Set flag to update flat database file at commit.  Note: this also
-	 * forces synchronous commit, which minimizes the window between removal
+	 * Force synchronous commit, thus minimizing the window between removal
 	 * of the database files and commital of the transaction. If we crash
 	 * before committing, we'll have a DB that's gone on disk but still there
 	 * according to pg_database, which is not good.
 	 */
-	database_file_update_needed();
+	ForceSyncCommit();
 }
 
 
@@ -957,15 +952,9 @@ RenameDatabase(const char *oldname, const char *newname)
 	CatalogUpdateIndexes(rel, newtup);
 
 	/*
-	 * Close pg_database, but keep lock till commit (this is important to
-	 * prevent any risk of deadlock failure while updating flat file)
+	 * Close pg_database, but keep lock till commit.
 	 */
 	heap_close(rel, NoLock);
-
-	/*
-	 * Set flag to update flat database file at commit.
-	 */
-	database_file_update_needed();
 }
 
 
@@ -1212,17 +1201,15 @@ movedb(const char *dbname, const char *tblspcname)
 		RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT);
 
 		/*
-		 * Set flag to update flat database file at commit.  Note: this also
-		 * forces synchronous commit, which minimizes the window between
+		 * Force synchronous commit, thus minimizing the window between
 		 * copying the database files and commital of the transaction. If we
 		 * crash before committing, we'll leave an orphaned set of files on
 		 * disk, which is not fatal but not good either.
 		 */
-		database_file_update_needed();
+		ForceSyncCommit();
 
 		/*
-		 * Close pg_database, but keep lock till commit (this is important to
-		 * prevent any risk of deadlock failure while updating flat file)
+		 * Close pg_database, but keep lock till commit.
 		 */
 		heap_close(pgdbrel, NoLock);
 	}
@@ -1401,11 +1388,6 @@ AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
 
 	/* Close pg_database, but keep lock till commit */
 	heap_close(rel, NoLock);
-
-	/*
-	 * We don't bother updating the flat file since the existing options for
-	 * ALTER DATABASE don't affect it.
-	 */
 }
 
 
@@ -1494,11 +1476,6 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
 
 	/* Close pg_database, but keep lock till commit */
 	heap_close(rel, NoLock);
-
-	/*
-	 * We don't bother updating the flat file since ALTER DATABASE SET doesn't
-	 * affect it.
-	 */
 }
 
 
@@ -1608,11 +1585,6 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
 
 	/* Close pg_database, but keep lock till commit */
 	heap_close(rel, NoLock);
-
-	/*
-	 * We don't bother updating the flat file since ALTER DATABASE OWNER
-	 * doesn't affect it.
-	 */
 }
 
 
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 6796a1f5e29e04a7f72dee8f7f39fec21cc7381d..c157ead4726e7eaf34e6a53d8b8ec70e7a4302d2 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.187 2009/06/11 14:48:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.188 2009/09/01 02:54:51 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,7 +26,6 @@
 #include "storage/lmgr.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
-#include "utils/flatfiles.h"
 #include "utils/fmgroids.h"
 #include "utils/guc.h"
 #include "utils/lsyscache.h"
@@ -385,15 +384,9 @@ CreateRole(CreateRoleStmt *stmt)
 				GetUserId(), false);
 
 	/*
-	 * Close pg_authid, but keep lock till commit (this is important to
-	 * prevent any risk of deadlock failure while updating flat file)
+	 * Close pg_authid, but keep lock till commit.
 	 */
 	heap_close(pg_authid_rel, NoLock);
-
-	/*
-	 * Set flag to update flat auth file at commit.
-	 */
-	auth_file_update_needed();
 }
 
 
@@ -710,15 +703,9 @@ AlterRole(AlterRoleStmt *stmt)
 					false);
 
 	/*
-	 * Close pg_authid, but keep lock till commit (this is important to
-	 * prevent any risk of deadlock failure while updating flat file)
+	 * Close pg_authid, but keep lock till commit.
 	 */
 	heap_close(pg_authid_rel, NoLock);
-
-	/*
-	 * Set flag to update flat auth file at commit.
-	 */
-	auth_file_update_needed();
 }
 
 
@@ -808,7 +795,6 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
 	CatalogUpdateIndexes(rel, newtuple);
 
 	ReleaseSysCache(oldtuple);
-	/* needn't keep lock since we won't be updating the flat file */
 	heap_close(rel, RowExclusiveLock);
 }
 
@@ -970,16 +956,10 @@ DropRole(DropRoleStmt *stmt)
 	}
 
 	/*
-	 * Now we can clean up; but keep locks until commit (to avoid possible
-	 * deadlock failure while updating flat file)
+	 * Now we can clean up; but keep locks until commit.
 	 */
 	heap_close(pg_auth_members_rel, NoLock);
 	heap_close(pg_authid_rel, NoLock);
-
-	/*
-	 * Set flag to update flat auth file at commit.
-	 */
-	auth_file_update_needed();
 }
 
 /*
@@ -1092,15 +1072,9 @@ RenameRole(const char *oldname, const char *newname)
 	ReleaseSysCache(oldtuple);
 
 	/*
-	 * Close pg_authid, but keep lock till commit (this is important to
-	 * prevent any risk of deadlock failure while updating flat file)
+	 * Close pg_authid, but keep lock till commit.
 	 */
 	heap_close(rel, NoLock);
-
-	/*
-	 * Set flag to update flat auth file at commit.
-	 */
-	auth_file_update_needed();
 }
 
 /*
@@ -1157,15 +1131,9 @@ GrantRole(GrantRoleStmt *stmt)
 	}
 
 	/*
-	 * Close pg_authid, but keep lock till commit (this is important to
-	 * prevent any risk of deadlock failure while updating flat file)
+	 * Close pg_authid, but keep lock till commit.
 	 */
 	heap_close(pg_authid_rel, NoLock);
-
-	/*
-	 * Set flag to update flat auth file at commit.
-	 */
-	auth_file_update_needed();
 }
 
 /*
@@ -1385,8 +1353,7 @@ AddRoleMems(const char *rolename, Oid roleid,
 	}
 
 	/*
-	 * Close pg_authmem, but keep lock till commit (this is important to
-	 * prevent any risk of deadlock failure while updating flat file)
+	 * Close pg_authmem, but keep lock till commit.
 	 */
 	heap_close(pg_authmem_rel, NoLock);
 }
@@ -1498,8 +1465,7 @@ DelRoleMems(const char *rolename, Oid roleid,
 	}
 
 	/*
-	 * Close pg_authmem, but keep lock till commit (this is important to
-	 * prevent any risk of deadlock failure while updating flat file)
+	 * Close pg_authmem, but keep lock till commit.
 	 */
 	heap_close(pg_authmem_rel, NoLock);
 }
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index d2b3105e0282f52b6f962fa012736df6f617ccda..260eab82d1bda7f61fad60cc777ff35385e335f7 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.391 2009/08/31 02:23:22 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.392 2009/09/01 02:54:51 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -46,7 +46,6 @@
 #include "storage/procarray.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
-#include "utils/flatfiles.h"
 #include "utils/fmgroids.h"
 #include "utils/inval.h"
 #include "utils/lsyscache.h"
@@ -893,15 +892,11 @@ vac_update_datfrozenxid(void)
 	heap_close(relation, RowExclusiveLock);
 
 	/*
-	 * If we were able to advance datfrozenxid, mark the flat-file copy of
-	 * pg_database for update at commit, and see if we can truncate pg_clog.
-	 * Also force update if the shared XID-wrap-limit info is stale.
+	 * If we were able to advance datfrozenxid, see if we can truncate pg_clog.
+	 * Also do it if the shared XID-wrap-limit info is stale.
 	 */
 	if (dirty || !TransactionIdLimitIsValid())
-	{
-		database_file_update_needed();
 		vac_truncate_clog(newFrozenXid);
-	}
 }
 
 
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index dbd61916823436c95e542934f7d6f2b342419e8d..77fe11f05a73c3dee17373524c57833b2b1a50a4 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.189 2009/08/29 19:26:51 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.190 2009/09/01 02:54:51 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1274,51 +1274,6 @@ load_hba(void)
 	return true;
 }
 
-/*
- * Read and parse one line from the flat pg_database file.
- *
- * Returns TRUE on success, FALSE if EOF; bad data causes elog(FATAL).
- *
- * Output parameters:
- *	dbname: gets database name (must be of size NAMEDATALEN bytes)
- *	dboid: gets database OID
- *	dbtablespace: gets database's default tablespace's OID
- *	dbfrozenxid: gets database's frozen XID
- *
- * This is not much related to the other functions in hba.c, but we put it
- * here because it uses the next_token() infrastructure.
- */
-bool
-read_pg_database_line(FILE *fp, char *dbname, Oid *dboid,
-					  Oid *dbtablespace, TransactionId *dbfrozenxid)
-{
-	char		buf[MAX_TOKEN];
-
-	if (feof(fp))
-		return false;
-	if (!next_token(fp, buf, sizeof(buf)))
-		return false;
-	if (strlen(buf) >= NAMEDATALEN)
-		elog(FATAL, "bad data in flat pg_database file");
-	strcpy(dbname, buf);
-	next_token(fp, buf, sizeof(buf));
-	if (!isdigit((unsigned char) buf[0]))
-		elog(FATAL, "bad data in flat pg_database file");
-	*dboid = atooid(buf);
-	next_token(fp, buf, sizeof(buf));
-	if (!isdigit((unsigned char) buf[0]))
-		elog(FATAL, "bad data in flat pg_database file");
-	*dbtablespace = atooid(buf);
-	next_token(fp, buf, sizeof(buf));
-	if (!isdigit((unsigned char) buf[0]))
-		elog(FATAL, "bad data in flat pg_database file");
-	*dbfrozenxid = atoxid(buf);
-	/* expect EOL next */
-	if (next_token(fp, buf, sizeof(buf)))
-		elog(FATAL, "bad data in flat pg_database file");
-	return true;
-}
-
 /*
  *	Process one line from the ident config file.
  *
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 75092fc4a4511dc7608c045ec9f8d6800e0abbea..2371999062a983b66f66997a7764c767fa251281 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.572 2009/09/01 00:09:42 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.573 2009/09/01 02:54:51 alvherre Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -66,7 +66,6 @@
 #include "tcop/pquery.h"
 #include "tcop/tcopprot.h"
 #include "tcop/utility.h"
-#include "utils/flatfiles.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
@@ -3280,12 +3279,6 @@ PostgresMain(int argc, char *argv[], const char *username)
 		 */
 		StartupXLOG();
 		on_shmem_exit(ShutdownXLOG, 0);
-
-		/*
-		 * We have to build the flat file for pg_database, but not for the
-		 * user and group tables, since we won't try to do authentication.
-		 */
-		BuildFlatFiles(true);
 	}
 
 	/*
diff --git a/src/backend/utils/init/Makefile b/src/backend/utils/init/Makefile
index a27ddb7af6dea2ca1b84f743fbe1a920d150b952..24a9ae804fe0e890c42bd860d39b874446ef6994 100644
--- a/src/backend/utils/init/Makefile
+++ b/src/backend/utils/init/Makefile
@@ -4,7 +4,7 @@
 #    Makefile for utils/init
 #
 # IDENTIFICATION
-#    $PostgreSQL: pgsql/src/backend/utils/init/Makefile,v 1.22 2008/02/19 10:30:08 petere Exp $
+#    $PostgreSQL: pgsql/src/backend/utils/init/Makefile,v 1.23 2009/09/01 02:54:51 alvherre Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -12,6 +12,6 @@ subdir = src/backend/utils/init
 top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
-OBJS = flatfiles.o globals.o miscinit.o postinit.o
+OBJS = globals.o miscinit.o postinit.o
 
 include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/utils/init/flatfiles.c b/src/backend/utils/init/flatfiles.c
deleted file mode 100644
index 38271653f6d82f47f65f35db1d85630b74f6b2a0..0000000000000000000000000000000000000000
--- a/src/backend/utils/init/flatfiles.c
+++ /dev/null
@@ -1,931 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * flatfiles.c
- *	  Routines for maintaining "flat file" images of the shared catalogs.
- *
- * We use flat files so that the postmaster and not-yet-fully-started
- * backends can look at the contents of pg_database, pg_authid, and
- * pg_auth_members for authentication purposes.  This module is
- * responsible for keeping the flat-file images as nearly in sync with
- * database reality as possible.
- *
- * The tricky part of the write_xxx_file() routines in this module is that
- * they need to be able to operate in the context of the database startup
- * process (which calls BuildFlatFiles()) as well as a normal backend.
- * This means for example that we can't assume a fully functional relcache
- * and we can't use syscaches at all.  The major restriction imposed by
- * all that is that there's no way to read an out-of-line-toasted datum,
- * because the tuptoaster.c code is not prepared to cope with such an
- * environment.  Fortunately we can design the shared catalogs in such
- * a way that this is OK.
- *
- *
- * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.39 2009/08/31 02:23:22 tgl Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "access/heapam.h"
-#include "access/transam.h"
-#include "access/twophase_rmgr.h"
-#include "access/xact.h"
-#include "access/xlogutils.h"
-#include "catalog/pg_auth_members.h"
-#include "catalog/pg_authid.h"
-#include "catalog/pg_database.h"
-#include "catalog/pg_namespace.h"
-#include "catalog/pg_tablespace.h"
-#include "commands/trigger.h"
-#include "miscadmin.h"
-#include "storage/bufmgr.h"
-#include "storage/fd.h"
-#include "storage/lmgr.h"
-#include "storage/pmsignal.h"
-#include "utils/builtins.h"
-#include "utils/flatfiles.h"
-#include "utils/resowner.h"
-#include "utils/tqual.h"
-
-
-/* Actual names of the flat files (within $PGDATA) */
-#define DATABASE_FLAT_FILE	"global/pg_database"
-#define AUTH_FLAT_FILE		"global/pg_auth"
-
-/* Info bits in a flatfiles 2PC record */
-#define FF_BIT_DATABASE 1
-#define FF_BIT_AUTH		2
-
-
-/*
- * The need-to-update-files flags are SubTransactionIds that show
- * what level of the subtransaction tree requested the update. To register
- * an update, the subtransaction saves its own SubTransactionId in the flag,
- * unless the value was already set to a valid SubTransactionId (which implies
- * that it or a parent level has already requested the same).  If it aborts
- * and the value is its SubTransactionId, it resets the flag to
- * InvalidSubTransactionId. If it commits, it changes the value to its
- * parent's SubTransactionId.  This way the value is propagated up to the
- * top-level transaction, which will update the files if a valid
- * SubTransactionId is seen at top-level commit.
- */
-static SubTransactionId database_file_update_subid = InvalidSubTransactionId;
-static SubTransactionId auth_file_update_subid = InvalidSubTransactionId;
-
-
-/*
- * Mark flat database file as needing an update (because pg_database changed)
- */
-void
-database_file_update_needed(void)
-{
-	if (database_file_update_subid == InvalidSubTransactionId)
-		database_file_update_subid = GetCurrentSubTransactionId();
-}
-
-/*
- * Mark flat auth file as needing an update (because pg_authid or
- * pg_auth_members changed)
- */
-void
-auth_file_update_needed(void)
-{
-	if (auth_file_update_subid == InvalidSubTransactionId)
-		auth_file_update_subid = GetCurrentSubTransactionId();
-}
-
-
-/*
- * database_getflatfilename --- get pathname of database file
- *
- * Note that result string is palloc'd, and should be freed by the caller.
- * (This convention is not really needed anymore, since the relative path
- * is fixed.)
- */
-char *
-database_getflatfilename(void)
-{
-	return pstrdup(DATABASE_FLAT_FILE);
-}
-
-/*
- * auth_getflatfilename --- get pathname of auth file
- *
- * Note that result string is palloc'd, and should be freed by the caller.
- * (This convention is not really needed anymore, since the relative path
- * is fixed.)
- */
-char *
-auth_getflatfilename(void)
-{
-	return pstrdup(AUTH_FLAT_FILE);
-}
-
-
-/*
- *	fputs_quote
- *
- *	Outputs string in quotes, with double-quotes duplicated.
- *	We could use quote_ident(), but that expects a TEXT argument.
- */
-static void
-fputs_quote(const char *str, FILE *fp)
-{
-	fputc('"', fp);
-	while (*str)
-	{
-		fputc(*str, fp);
-		if (*str == '"')
-			fputc('"', fp);
-		str++;
-	}
-	fputc('"', fp);
-}
-
-/*
- * name_okay
- *
- * We must disallow newlines in role names because
- * hba.c's parser won't handle fields split across lines, even if quoted.
- */
-static bool
-name_okay(const char *str)
-{
-	int			i;
-
-	i = strcspn(str, "\r\n");
-	return (str[i] == '\0');
-}
-
-
-/*
- * write_database_file: update the flat database file
- */
-static void
-write_database_file(Relation drel)
-{
-	char	   *filename,
-			   *tempname;
-	int			bufsize;
-	FILE	   *fp;
-	mode_t		oumask;
-	HeapScanDesc scan;
-	HeapTuple	tuple;
-
-	/*
-	 * Create a temporary filename to be renamed later.  This prevents the
-	 * backend from clobbering the flat file while the postmaster might be
-	 * reading from it.
-	 */
-	filename = database_getflatfilename();
-	bufsize = strlen(filename) + 12;
-	tempname = (char *) palloc(bufsize);
-	snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid);
-
-	oumask = umask((mode_t) 077);
-	fp = AllocateFile(tempname, "w");
-	umask(oumask);
-	if (fp == NULL)
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not write to temporary file \"%s\": %m",
-						tempname)));
-
-	/*
-	 * Read pg_database and write the file.
-	 */
-	scan = heap_beginscan(drel, SnapshotNow, 0, NULL);
-	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
-	{
-		Form_pg_database dbform = (Form_pg_database) GETSTRUCT(tuple);
-		char	   *datname;
-		Oid			datoid;
-		Oid			dattablespace;
-		TransactionId datfrozenxid;
-
-		datname = NameStr(dbform->datname);
-		datoid = HeapTupleGetOid(tuple);
-		dattablespace = dbform->dattablespace;
-		datfrozenxid = dbform->datfrozenxid;
-
-		/*
-		 * Check for illegal characters in the database name.
-		 */
-		if (!name_okay(datname))
-		{
-			ereport(LOG,
-					(errmsg("invalid database name \"%s\"", datname)));
-			continue;
-		}
-
-		/*
-		 * The file format is: "dbname" oid tablespace frozenxid
-		 *
-		 * The xids are not needed for backend startup, but are of use to
-		 * autovacuum, and might also be helpful for forensic purposes.
-		 */
-		fputs_quote(datname, fp);
-		fprintf(fp, " %u %u %u\n",
-				datoid, dattablespace, datfrozenxid);
-	}
-	heap_endscan(scan);
-
-	if (FreeFile(fp))
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not write to temporary file \"%s\": %m",
-						tempname)));
-
-	/*
-	 * Rename the temp file to its final name, deleting the old flat file. We
-	 * expect that rename(2) is an atomic action.
-	 */
-	if (rename(tempname, filename))
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not rename file \"%s\" to \"%s\": %m",
-						tempname, filename)));
-}
-
-
-/*
- * Support for write_auth_file
- *
- * The format for the flat auth file is
- *		"rolename" "password" "validuntil" "memberof" "memberof" ...
- * Each role's line lists all the roles (groups) of which it is directly
- * or indirectly a member, except for itself.
- *
- * The postmaster expects the file to be sorted by rolename.  There is not
- * any special ordering of the membership lists.
- *
- * To construct this information, we scan pg_authid and pg_auth_members,
- * and build data structures in-memory before writing the file.
- */
-
-typedef struct
-{
-	Oid			roleid;
-	char	   *rolname;
-	char	   *rolpassword;
-	char	   *rolvaliduntil;
-	List	   *member_of;
-} auth_entry;
-
-typedef struct
-{
-	Oid			roleid;
-	Oid			memberid;
-} authmem_entry;
-
-
-/* qsort comparator for sorting auth_entry array by roleid */
-static int
-oid_compar(const void *a, const void *b)
-{
-	const auth_entry *a_auth = (const auth_entry *) a;
-	const auth_entry *b_auth = (const auth_entry *) b;
-
-	if (a_auth->roleid < b_auth->roleid)
-		return -1;
-	if (a_auth->roleid > b_auth->roleid)
-		return 1;
-	return 0;
-}
-
-/* qsort comparator for sorting auth_entry array by rolname */
-static int
-name_compar(const void *a, const void *b)
-{
-	const auth_entry *a_auth = (const auth_entry *) a;
-	const auth_entry *b_auth = (const auth_entry *) b;
-
-	return strcmp(a_auth->rolname, b_auth->rolname);
-}
-
-/* qsort comparator for sorting authmem_entry array by memberid */
-static int
-mem_compar(const void *a, const void *b)
-{
-	const authmem_entry *a_auth = (const authmem_entry *) a;
-	const authmem_entry *b_auth = (const authmem_entry *) b;
-
-	if (a_auth->memberid < b_auth->memberid)
-		return -1;
-	if (a_auth->memberid > b_auth->memberid)
-		return 1;
-	return 0;
-}
-
-
-/*
- * write_auth_file: update the flat auth file
- */
-static void
-write_auth_file(Relation rel_authid, Relation rel_authmem)
-{
-	char	   *filename,
-			   *tempname;
-	int			bufsize;
-	BlockNumber totalblocks;
-	FILE	   *fp;
-	mode_t		oumask;
-	HeapScanDesc scan;
-	HeapTuple	tuple;
-	int			curr_role = 0;
-	int			total_roles = 0;
-	int			curr_mem = 0;
-	int			total_mem = 0;
-	int			est_rows;
-	auth_entry *auth_info;
-	authmem_entry *authmem_info;
-
-	/*
-	 * Create a temporary filename to be renamed later.  This prevents the
-	 * backend from clobbering the flat file while the postmaster might be
-	 * reading from it.
-	 */
-	filename = auth_getflatfilename();
-	bufsize = strlen(filename) + 12;
-	tempname = (char *) palloc(bufsize);
-	snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid);
-
-	oumask = umask((mode_t) 077);
-	fp = AllocateFile(tempname, "w");
-	umask(oumask);
-	if (fp == NULL)
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not write to temporary file \"%s\": %m",
-						tempname)));
-
-	/*
-	 * Read pg_authid and fill temporary data structures.
-	 */
-	totalblocks = RelationGetNumberOfBlocks(rel_authid);
-	totalblocks = totalblocks ? totalblocks : 1;
-	est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData) + sizeof(FormData_pg_authid)));
-	auth_info = (auth_entry *) palloc(est_rows * sizeof(auth_entry));
-
-	scan = heap_beginscan(rel_authid, SnapshotNow, 0, NULL);
-	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
-	{
-		Form_pg_authid aform = (Form_pg_authid) GETSTRUCT(tuple);
-		HeapTupleHeader tup = tuple->t_data;
-		char	   *tp;			/* ptr to tuple data */
-		long		off;		/* offset in tuple data */
-		bits8	   *bp = tup->t_bits;	/* ptr to null bitmask in tuple */
-		Datum		datum;
-
-		if (curr_role >= est_rows)
-		{
-			est_rows *= 2;
-			auth_info = (auth_entry *)
-				repalloc(auth_info, est_rows * sizeof(auth_entry));
-		}
-
-		auth_info[curr_role].roleid = HeapTupleGetOid(tuple);
-		auth_info[curr_role].rolname = pstrdup(NameStr(aform->rolname));
-		auth_info[curr_role].member_of = NIL;
-
-		/*
-		 * We can't use heap_getattr() here because during startup we will not
-		 * have any tupdesc for pg_authid.	Fortunately it's not too hard to
-		 * work around this.  rolpassword is the first possibly-null field so
-		 * we can compute its offset directly.	Note that this only works
-		 * reliably because the preceding field (rolconnlimit) is int4, and
-		 * therefore rolpassword is always 4-byte-aligned, and will be at the
-		 * same offset no matter whether it uses 1-byte or 4-byte header.
-		 */
-		tp = (char *) tup + tup->t_hoff;
-		off = offsetof(FormData_pg_authid, rolpassword);
-
-		if (HeapTupleHasNulls(tuple) &&
-			att_isnull(Anum_pg_authid_rolpassword - 1, bp))
-		{
-			/* passwd is null, emit as an empty string */
-			auth_info[curr_role].rolpassword = pstrdup("");
-		}
-		else
-		{
-			/* assume passwd is pass-by-ref */
-			datum = PointerGetDatum(tp + off);
-
-			/*
-			 * The password probably shouldn't ever be out-of-line toasted; if
-			 * it is, ignore it, since we can't handle that in startup mode.
-			 *
-			 * It is entirely likely that it's 1-byte format not 4-byte, and
-			 * theoretically possible that it's compressed inline, but
-			 * text_to_cstring should be able to handle those cases even in
-			 * startup mode.
-			 */
-			if (VARATT_IS_EXTERNAL(DatumGetPointer(datum)))
-				auth_info[curr_role].rolpassword = pstrdup("");
-			else
-				auth_info[curr_role].rolpassword = TextDatumGetCString(datum);
-
-			/* assume passwd has attlen -1 */
-			off = att_addlength_pointer(off, -1, tp + off);
-		}
-
-		if (HeapTupleHasNulls(tuple) &&
-			att_isnull(Anum_pg_authid_rolvaliduntil - 1, bp))
-		{
-			/* rolvaliduntil is null, emit as an empty string */
-			auth_info[curr_role].rolvaliduntil = pstrdup("");
-		}
-		else
-		{
-			TimestampTz *rvup;
-
-			/* Assume timestamptz has double alignment */
-			off = att_align_nominal(off, 'd');
-			rvup = (TimestampTz *) (tp + off);
-			auth_info[curr_role].rolvaliduntil =
-				DatumGetCString(DirectFunctionCall1(timestamptz_out,
-												TimestampTzGetDatum(*rvup)));
-		}
-
-		/*
-		 * Check for illegal characters in the user name and password.
-		 */
-		if (!name_okay(auth_info[curr_role].rolname))
-		{
-			ereport(LOG,
-					(errmsg("invalid role name \"%s\"",
-							auth_info[curr_role].rolname)));
-			continue;
-		}
-		if (!name_okay(auth_info[curr_role].rolpassword))
-		{
-			ereport(LOG,
-					(errmsg("invalid role password \"%s\"",
-							auth_info[curr_role].rolpassword)));
-			continue;
-		}
-
-		curr_role++;
-		total_roles++;
-	}
-	heap_endscan(scan);
-
-	/*
-	 * Read pg_auth_members into temporary data structure, too
-	 */
-	totalblocks = RelationGetNumberOfBlocks(rel_authmem);
-	totalblocks = totalblocks ? totalblocks : 1;
-	est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData) + sizeof(FormData_pg_auth_members)));
-	authmem_info = (authmem_entry *) palloc(est_rows * sizeof(authmem_entry));
-
-	scan = heap_beginscan(rel_authmem, SnapshotNow, 0, NULL);
-	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
-	{
-		Form_pg_auth_members memform = (Form_pg_auth_members) GETSTRUCT(tuple);
-
-		if (curr_mem >= est_rows)
-		{
-			est_rows *= 2;
-			authmem_info = (authmem_entry *)
-				repalloc(authmem_info, est_rows * sizeof(authmem_entry));
-		}
-
-		authmem_info[curr_mem].roleid = memform->roleid;
-		authmem_info[curr_mem].memberid = memform->member;
-		curr_mem++;
-		total_mem++;
-	}
-	heap_endscan(scan);
-
-	/*
-	 * Search for memberships.	We can skip all this if pg_auth_members is
-	 * empty.
-	 */
-	if (total_mem > 0)
-	{
-		/*
-		 * Sort auth_info by roleid and authmem_info by memberid.
-		 */
-		qsort(auth_info, total_roles, sizeof(auth_entry), oid_compar);
-		qsort(authmem_info, total_mem, sizeof(authmem_entry), mem_compar);
-
-		/*
-		 * For each role, find what it belongs to.
-		 */
-		for (curr_role = 0; curr_role < total_roles; curr_role++)
-		{
-			List	   *roles_list;
-			List	   *roles_names_list = NIL;
-			ListCell   *mem;
-
-			/*
-			 * This search algorithm is the same as in is_member_of_role; we
-			 * are just working with a different input data structure.
-			 */
-			roles_list = list_make1_oid(auth_info[curr_role].roleid);
-
-			foreach(mem, roles_list)
-			{
-				authmem_entry key;
-				authmem_entry *found_mem;
-				int			first_found,
-							last_found,
-							i;
-
-				key.memberid = lfirst_oid(mem);
-				found_mem = bsearch(&key, authmem_info, total_mem,
-									sizeof(authmem_entry), mem_compar);
-				if (!found_mem)
-					continue;
-
-				/*
-				 * bsearch found a match for us; but if there were multiple
-				 * matches it could have found any one of them. Locate first
-				 * and last match.
-				 */
-				first_found = last_found = (found_mem - authmem_info);
-				while (first_found > 0 &&
-					   mem_compar(&key, &authmem_info[first_found - 1]) == 0)
-					first_found--;
-				while (last_found + 1 < total_mem &&
-					   mem_compar(&key, &authmem_info[last_found + 1]) == 0)
-					last_found++;
-
-				/*
-				 * Now add all the new roles to roles_list.
-				 */
-				for (i = first_found; i <= last_found; i++)
-					roles_list = list_append_unique_oid(roles_list,
-													 authmem_info[i].roleid);
-			}
-
-			/*
-			 * Convert list of role Oids to list of role names. We must do
-			 * this before re-sorting auth_info.
-			 *
-			 * We skip the first list element (curr_role itself) since there
-			 * is no point in writing that a role is a member of itself.
-			 */
-			for_each_cell(mem, lnext(list_head(roles_list)))
-			{
-				auth_entry	key_auth;
-				auth_entry *found_role;
-
-				key_auth.roleid = lfirst_oid(mem);
-				found_role = bsearch(&key_auth, auth_info, total_roles,
-									 sizeof(auth_entry), oid_compar);
-				if (found_role) /* paranoia */
-					roles_names_list = lappend(roles_names_list,
-											   found_role->rolname);
-			}
-			auth_info[curr_role].member_of = roles_names_list;
-			list_free(roles_list);
-		}
-	}
-
-	/*
-	 * Now sort auth_info into rolname order for output, and write the file.
-	 */
-	qsort(auth_info, total_roles, sizeof(auth_entry), name_compar);
-
-	for (curr_role = 0; curr_role < total_roles; curr_role++)
-	{
-		auth_entry *arole = &auth_info[curr_role];
-		ListCell   *mem;
-
-		fputs_quote(arole->rolname, fp);
-		fputs(" ", fp);
-		fputs_quote(arole->rolpassword, fp);
-		fputs(" ", fp);
-		fputs_quote(arole->rolvaliduntil, fp);
-
-		foreach(mem, arole->member_of)
-		{
-			fputs(" ", fp);
-			fputs_quote((char *) lfirst(mem), fp);
-		}
-
-		fputs("\n", fp);
-	}
-
-	if (FreeFile(fp))
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not write to temporary file \"%s\": %m",
-						tempname)));
-
-	/*
-	 * Rename the temp file to its final name, deleting the old flat file. We
-	 * expect that rename(2) is an atomic action.
-	 */
-	if (rename(tempname, filename))
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not rename file \"%s\" to \"%s\": %m",
-						tempname, filename)));
-}
-
-
-/*
- * This routine is called once during database startup, after completing
- * WAL replay if needed.  Its purpose is to sync the flat files with the
- * current state of the database tables.  This is particularly important
- * during PITR operation, since the flat files will come from the
- * base backup which may be far out of sync with the current state.
- *
- * In theory we could skip rebuilding the flat files if no WAL replay
- * occurred, but it seems best to just do it always.  We have to
- * scan pg_database to compute the XID wrap limit anyway.  Also, this
- * policy means we need not force initdb to change the format of the
- * flat files.
- *
- * In a standalone backend we pass database_only = true to skip processing
- * the auth file.  We won't need it, and building it could fail if there's
- * something corrupt in the authid/authmem catalogs.
- */
-void
-BuildFlatFiles(bool database_only)
-{
-	ResourceOwner owner;
-	RelFileNode rnode;
-	Relation	rel_db,
-				rel_authid,
-				rel_authmem;
-
-	/* Need a resowner to keep the heapam and buffer code happy */
-	owner = ResourceOwnerCreate(NULL, "BuildFlatFiles");
-	CurrentResourceOwner = owner;
-
-	/* hard-wired path to pg_database */
-	rnode.spcNode = GLOBALTABLESPACE_OID;
-	rnode.dbNode = 0;
-	rnode.relNode = DatabaseRelationId;
-
-	/*
-	 * We don't have any hope of running a real relcache, but we can use the
-	 * same fake-relcache facility that WAL replay uses.
-	 *
-	 * No locking is needed because no one else is alive yet.
-	 */
-	rel_db = CreateFakeRelcacheEntry(rnode);
-	write_database_file(rel_db);
-	FreeFakeRelcacheEntry(rel_db);
-
-	if (!database_only)
-	{
-		/* hard-wired path to pg_authid */
-		rnode.spcNode = GLOBALTABLESPACE_OID;
-		rnode.dbNode = 0;
-		rnode.relNode = AuthIdRelationId;
-		rel_authid = CreateFakeRelcacheEntry(rnode);
-
-		/* hard-wired path to pg_auth_members */
-		rnode.spcNode = GLOBALTABLESPACE_OID;
-		rnode.dbNode = 0;
-		rnode.relNode = AuthMemRelationId;
-		rel_authmem = CreateFakeRelcacheEntry(rnode);
-
-		write_auth_file(rel_authid, rel_authmem);
-		FreeFakeRelcacheEntry(rel_authid);
-		FreeFakeRelcacheEntry(rel_authmem);
-	}
-
-	CurrentResourceOwner = NULL;
-	ResourceOwnerDelete(owner);
-}
-
-
-/*
- * This routine is called during transaction commit or abort.
- *
- * On commit, if we've written any of the critical database tables during
- * the current transaction, update the flat files and signal the postmaster.
- *
- * On abort, just reset the static flags so we don't try to do it on the
- * next successful commit.
- *
- * NB: this should be the last step before actual transaction commit.
- * If any error aborts the transaction after we run this code, the postmaster
- * will still have received and cached the changed data; so minimize the
- * window for such problems.
- */
-void
-AtEOXact_UpdateFlatFiles(bool isCommit)
-{
-	Relation	drel = NULL;
-	Relation	arel = NULL;
-	Relation	mrel = NULL;
-
-	if (database_file_update_subid == InvalidSubTransactionId &&
-		auth_file_update_subid == InvalidSubTransactionId)
-		return;					/* nothing to do */
-
-	if (!isCommit)
-	{
-		database_file_update_subid = InvalidSubTransactionId;
-		auth_file_update_subid = InvalidSubTransactionId;
-		return;
-	}
-
-	/*
-	 * Advance command counter to be certain we see all effects of the current
-	 * transaction.
-	 */
-	CommandCounterIncrement();
-
-	/*
-	 * Open and lock the needed catalog(s).
-	 *
-	 * Even though we only need AccessShareLock, this could theoretically fail
-	 * due to deadlock.  In practice, however, our transaction already holds
-	 * RowExclusiveLock or better (it couldn't have updated the catalog
-	 * without such a lock).  This implies that dbcommands.c and other places
-	 * that force flat-file updates must not follow the common practice of
-	 * dropping catalog locks before commit.
-	 */
-	if (database_file_update_subid != InvalidSubTransactionId)
-		drel = heap_open(DatabaseRelationId, AccessShareLock);
-
-	if (auth_file_update_subid != InvalidSubTransactionId)
-	{
-		arel = heap_open(AuthIdRelationId, AccessShareLock);
-		mrel = heap_open(AuthMemRelationId, AccessShareLock);
-	}
-
-	/*
-	 * Obtain special locks to ensure that two transactions don't try to write
-	 * the same flat file concurrently.  Quite aside from any direct risks of
-	 * corrupted output, the winning writer probably wouldn't have seen the
-	 * other writer's updates.  By taking a lock and holding it till commit,
-	 * we ensure that whichever updater goes second will see the other
-	 * updater's changes as committed, and thus the final state of the file
-	 * will include all updates.
-	 *
-	 * We use a lock on "database 0" to protect writing the pg_database flat
-	 * file, and a lock on "role 0" to protect the auth file.  This is a bit
-	 * ugly but it's not worth inventing any more-general convention.  (Any
-	 * two locktags that are never used for anything else would do.)
-	 *
-	 * This is safe against deadlock as long as these are the very last locks
-	 * acquired during the transaction.
-	 */
-	if (database_file_update_subid != InvalidSubTransactionId)
-		LockSharedObject(DatabaseRelationId, InvalidOid, 0,
-						 AccessExclusiveLock);
-
-	if (auth_file_update_subid != InvalidSubTransactionId)
-		LockSharedObject(AuthIdRelationId, InvalidOid, 0,
-						 AccessExclusiveLock);
-
-	/* Okay to write the files */
-	if (database_file_update_subid != InvalidSubTransactionId)
-	{
-		database_file_update_subid = InvalidSubTransactionId;
-		write_database_file(drel);
-		heap_close(drel, NoLock);
-	}
-
-	if (auth_file_update_subid != InvalidSubTransactionId)
-	{
-		auth_file_update_subid = InvalidSubTransactionId;
-		write_auth_file(arel, mrel);
-		heap_close(arel, NoLock);
-		heap_close(mrel, NoLock);
-	}
-
-	/*
-	 * Force synchronous commit, to minimize the window between changing the
-	 * flat files on-disk and marking the transaction committed.  It's not
-	 * great that there is any window at all, but definitely we don't want to
-	 * make it larger than necessary.
-	 */
-	ForceSyncCommit();
-}
-
-
-/*
- * This routine is called during transaction prepare.
- *
- * Record which files need to be refreshed if this transaction later
- * commits.
- *
- * Note: it's OK to clear the flags immediately, since if the PREPARE fails
- * further on, we'd only reset the flags anyway. So there's no need for a
- * separate PostPrepare call.
- */
-void
-AtPrepare_UpdateFlatFiles(void)
-{
-	uint16		info = 0;
-
-	if (database_file_update_subid != InvalidSubTransactionId)
-	{
-		database_file_update_subid = InvalidSubTransactionId;
-		info |= FF_BIT_DATABASE;
-	}
-	if (auth_file_update_subid != InvalidSubTransactionId)
-	{
-		auth_file_update_subid = InvalidSubTransactionId;
-		info |= FF_BIT_AUTH;
-	}
-	if (info != 0)
-		RegisterTwoPhaseRecord(TWOPHASE_RM_FLATFILES_ID, info,
-							   NULL, 0);
-}
-
-
-/*
- * AtEOSubXact_UpdateFlatFiles
- *
- * Called at subtransaction end, this routine resets or updates the
- * need-to-update-files flags.
- */
-void
-AtEOSubXact_UpdateFlatFiles(bool isCommit,
-							SubTransactionId mySubid,
-							SubTransactionId parentSubid)
-{
-	if (isCommit)
-	{
-		if (database_file_update_subid == mySubid)
-			database_file_update_subid = parentSubid;
-
-		if (auth_file_update_subid == mySubid)
-			auth_file_update_subid = parentSubid;
-	}
-	else
-	{
-		if (database_file_update_subid == mySubid)
-			database_file_update_subid = InvalidSubTransactionId;
-
-		if (auth_file_update_subid == mySubid)
-			auth_file_update_subid = InvalidSubTransactionId;
-	}
-}
-
-
-/*
- * This trigger is fired whenever someone modifies pg_database, pg_authid
- * or pg_auth_members via general-purpose INSERT/UPDATE/DELETE commands.
- *
- * It is sufficient for this to be a STATEMENT trigger since we don't
- * care which individual rows changed.	It doesn't much matter whether
- * it's a BEFORE or AFTER trigger.
- */
-Datum
-flatfile_update_trigger(PG_FUNCTION_ARGS)
-{
-	TriggerData *trigdata = (TriggerData *) fcinfo->context;
-
-	if (!CALLED_AS_TRIGGER(fcinfo))
-		elog(ERROR,
-			 "flatfile_update_trigger was not called by trigger manager");
-
-	if (RelationGetNamespace(trigdata->tg_relation) != PG_CATALOG_NAMESPACE)
-		elog(ERROR, "flatfile_update_trigger was called for wrong table");
-
-	switch (RelationGetRelid(trigdata->tg_relation))
-	{
-		case DatabaseRelationId:
-			database_file_update_needed();
-			break;
-		case AuthIdRelationId:
-		case AuthMemRelationId:
-			auth_file_update_needed();
-			break;
-		default:
-			elog(ERROR, "flatfile_update_trigger was called for wrong table");
-			break;
-	}
-
-	return PointerGetDatum(NULL);
-}
-
-
-/*
- * 2PC processing routine for COMMIT PREPARED case.
- *
- * (We don't have to do anything for ROLLBACK PREPARED.)
- */
-void
-flatfile_twophase_postcommit(TransactionId xid, uint16 info,
-							 void *recdata, uint32 len)
-{
-	/*
-	 * Set flags to do the needed file updates at the end of my own current
-	 * transaction.  (XXX this has some issues if my own transaction later
-	 * rolls back, or if there is any significant delay before I commit.  OK
-	 * for now because we disallow COMMIT PREPARED inside a transaction
-	 * block.)
-	 */
-	if (info & FF_BIT_DATABASE)
-		database_file_update_needed();
-	if (info & FF_BIT_AUTH)
-		auth_file_update_needed();
-}
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 3fc9b3880efaa5359a242a4c6b5b7d0ba0b2f95f..9f9c3d4997bde3b6ee91b40bd8c497c1a76de96f 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -42,7 +42,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  * Portions taken from FreeBSD.
  *
- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.172 2009/06/11 14:49:07 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.173 2009/09/01 02:54:52 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1404,20 +1404,6 @@ setup_auth(void)
 	PG_CMD_DECL;
 	const char **line;
 	static const char *pg_authid_setup[] = {
-		/*
-		 * Create triggers to ensure manual updates to shared catalogs will be
-		 * reflected into their "flat file" copies.
-		 */
-		"CREATE TRIGGER pg_sync_pg_database "
-		"  AFTER INSERT OR UPDATE OR DELETE ON pg_database "
-		"  FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
-		"CREATE TRIGGER pg_sync_pg_authid "
-		"  AFTER INSERT OR UPDATE OR DELETE ON pg_authid "
-		"  FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
-		"CREATE TRIGGER pg_sync_pg_auth_members "
-		"  AFTER INSERT OR UPDATE OR DELETE ON pg_auth_members "
-		"  FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
-
 		/*
 		 * The authid table shouldn't be readable except through views, to
 		 * ensure passwords are not publicly visible.
diff --git a/src/include/access/twophase_rmgr.h b/src/include/access/twophase_rmgr.h
index dc018005ae7c28d2e87aeecd2216bdb6b6537fd7..5f516b8666cacd1ed0dc5886e2d5fd4d54f57c12 100644
--- a/src/include/access/twophase_rmgr.h
+++ b/src/include/access/twophase_rmgr.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/twophase_rmgr.h,v 1.7 2009/01/01 17:23:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/twophase_rmgr.h,v 1.8 2009/09/01 02:54:52 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -24,9 +24,8 @@ typedef uint8 TwoPhaseRmgrId;
 #define TWOPHASE_RM_END_ID			0
 #define TWOPHASE_RM_LOCK_ID			1
 #define TWOPHASE_RM_INVAL_ID		2
-#define TWOPHASE_RM_FLATFILES_ID	3
-#define TWOPHASE_RM_NOTIFY_ID		4
-#define TWOPHASE_RM_PGSTAT_ID		5
+#define TWOPHASE_RM_NOTIFY_ID		3
+#define TWOPHASE_RM_PGSTAT_ID		4
 #define TWOPHASE_RM_MAX_ID			TWOPHASE_RM_PGSTAT_ID
 
 extern const TwoPhaseCallback twophase_recover_callbacks[];
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index d24f36812193dedc599f55dfd37020982d3a9a08..f6a9a8a838704c259ddf3c66d2a4dd7ffbac0022 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.549 2009/08/04 04:04:12 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.550 2009/09/01 02:54:52 alvherre Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -2182,9 +2182,6 @@ DESCR("matches LIKE expression, case-insensitive");
 DATA(insert OID = 1661 (  bpcharicnlike		PGNSP PGUID 12 1 0 0 f f f t f i 2 0 16 "1042 25" _null_ _null_ _null_ _null_ texticnlike _null_ _null_ _null_ ));
 DESCR("does not match LIKE expression, case-insensitive");
 
-DATA(insert OID = 1689 (  flatfile_update_trigger  PGNSP PGUID 12 1 0 0 f f f t f v 0 0 2279 "" _null_ _null_ _null_ _null_ flatfile_update_trigger _null_ _null_ _null_ ));
-DESCR("update flat-file copy of a shared catalog");
-
 /* Oracle Compatibility Related Functions - By Edmund Mergl <E.Mergl@bawue.de> */
 DATA(insert OID =  868 (  strpos	   PGNSP PGUID 12 1 0 0 f f f t f i 2 0 23 "25 25" _null_ _null_ _null_ _null_ textpos _null_ _null_ _null_ ));
 DESCR("find position of substring");
diff --git a/src/include/utils/flatfiles.h b/src/include/utils/flatfiles.h
deleted file mode 100644
index 6b6a7cec86ea559ebb5514dbfa4a088fa1d0fbea..0000000000000000000000000000000000000000
--- a/src/include/utils/flatfiles.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * flatfiles.h
- *	  Routines for maintaining "flat file" images of the shared catalogs.
- *
- *
- * $PostgreSQL: pgsql/src/include/utils/flatfiles.h,v 1.6 2005/10/15 02:49:46 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#ifndef FLATFILES_H
-#define FLATFILES_H
-
-#include "fmgr.h"
-
-extern void database_file_update_needed(void);
-extern void auth_file_update_needed(void);
-
-extern char *database_getflatfilename(void);
-extern char *auth_getflatfilename(void);
-
-extern void BuildFlatFiles(bool database_only);
-
-extern void AtPrepare_UpdateFlatFiles(void);
-extern void AtEOXact_UpdateFlatFiles(bool isCommit);
-extern void AtEOSubXact_UpdateFlatFiles(bool isCommit,
-							SubTransactionId mySubid,
-							SubTransactionId parentSubid);
-
-extern Datum flatfile_update_trigger(PG_FUNCTION_ARGS);
-
-extern void flatfile_twophase_postcommit(TransactionId xid, uint16 info,
-							 void *recdata, uint32 len);
-
-#endif   /* FLATFILES_H */