diff --git a/contrib/lo/lo_test.sql b/contrib/lo/lo_test.sql
index e22a8889b31b850e91c721f66ee9587873f1b9fd..73022b2535a68b24e121e81c037d4c2386169feb 100644
--- a/contrib/lo/lo_test.sql
+++ b/contrib/lo/lo_test.sql
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/contrib/lo/lo_test.sql,v 1.5 2007/11/13 04:24:28 momjian Exp $ */
+/* $PostgreSQL: pgsql/contrib/lo/lo_test.sql,v 1.6 2009/12/14 00:39:10 itagaki Exp $ */
 
 -- Adjust this setting to control where the objects get created.
 SET search_path = public;
@@ -12,7 +12,7 @@ SET search_path = public;
 --
 
 -- Check what is in pg_largeobject
-SELECT count(DISTINCT loid) FROM pg_largeobject;
+SELECT count(oid) FROM pg_largeobject_metadata;
 
 -- ignore any errors here - simply drop the table if it already exists
 DROP TABLE a;
@@ -74,6 +74,6 @@ DELETE FROM a;
 DROP TABLE a;
 
 -- Check what is in pg_largeobject ... if different from original, trouble
-SELECT count(DISTINCT loid) FROM pg_largeobject;
+SELECT count(oid) FROM pg_largeobject_metadata;
 
 -- end of tests
diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c
index a0a7d57922b1e41642e850388dcf18742dcddfcc..196688ce0090cc5c2b74534ce3803bae5b1ca849 100644
--- a/contrib/vacuumlo/vacuumlo.c
+++ b/contrib/vacuumlo/vacuumlo.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/contrib/vacuumlo/vacuumlo.c,v 1.42 2009/07/13 22:56:30 momjian Exp $
+ *	  $PostgreSQL: pgsql/contrib/vacuumlo/vacuumlo.c,v 1.43 2009/12/14 00:39:10 itagaki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -142,7 +142,10 @@ vacuumlo(char *database, struct _param * param)
 	 */
 	buf[0] = '\0';
 	strcat(buf, "CREATE TEMP TABLE vacuum_l AS ");
-	strcat(buf, "SELECT DISTINCT loid AS lo FROM pg_largeobject ");
+	if (PQserverVersion(conn) >= 80500)
+		strcat(buf, "SELECT oid AS lo FROM pg_largeobject_metadata");
+	else
+		strcat(buf, "SELECT DISTINCT loid AS lo FROM pg_largeobject");
 	res = PQexec(conn, buf);
 	if (PQresultStatus(res) != PGRES_COMMAND_OK)
 	{
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index e15e4dbdb9e4bf1e6c120ca34ab478cfb754d08a..54f0bc4b6df27d23494f9f7b9c48e394ed432ca7 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.176 2009/10/05 19:24:45 tgl Exp $
+ *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.177 2009/12/14 00:39:10 itagaki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -914,8 +914,7 @@ StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop)
 	ahlog(AH, 2, "restoring large object with OID %u\n", oid);
 
 	if (drop)
-		ahprintf(AH, "SELECT CASE WHEN EXISTS(SELECT 1 FROM pg_catalog.pg_largeobject WHERE loid = '%u') THEN pg_catalog.lo_unlink('%u') END;\n",
-				 oid, oid);
+		DropBlobIfExists(AH, oid);
 
 	if (AH->connection)
 	{
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index fa6db407f2b003195dad53ddd893eedf72831eb4..b3eb8b7b106317eaea1ade3b3e2959c82b7de6d4 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -17,7 +17,7 @@
  *
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.82 2009/08/07 22:48:34 tgl Exp $
+ *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.83 2009/12/14 00:39:11 itagaki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -371,6 +371,7 @@ extern void InitArchiveFmt_Tar(ArchiveHandle *AH);
 extern bool isValidTarHeader(char *header);
 
 extern int	ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser);
+extern void	DropBlobIfExists(ArchiveHandle *AH, Oid oid);
 
 int			ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH);
 int			ahprintf(ArchiveHandle *AH, const char *fmt,...) __attribute__((format(printf, 2, 3)));
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index 836b02cb936558b74cc5dc82badecc894b9c0755..1d72d6dd7e2470e8aa1f66b66c6f512cc21a08bd 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -5,7 +5,7 @@
  *	Implements the basic DB functions used by the archiver.
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.84 2009/06/11 14:49:07 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.85 2009/12/14 00:39:11 itagaki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -652,6 +652,23 @@ CommitTransaction(ArchiveHandle *AH)
 	ExecuteSqlCommand(AH, "COMMIT", "could not commit database transaction");
 }
 
+void
+DropBlobIfExists(ArchiveHandle *AH, Oid oid)
+{
+	/* Call lo_unlink only if exists to avoid not-found error. */
+	if (PQserverVersion(AH->connection) >= 80500)
+	{
+		ahprintf(AH, "SELECT pg_catalog.lo_unlink(oid) "
+					 "FROM pg_catalog.pg_largeobject_metadata "
+					 "WHERE oid = %u;\n", oid);
+	}
+	else
+	{
+		ahprintf(AH, "SELECT CASE WHEN EXISTS(SELECT 1 FROM pg_catalog.pg_largeobject WHERE loid = '%u') THEN pg_catalog.lo_unlink('%u') END;\n",
+				 oid, oid);
+	}
+}
+
 static bool
 _isIdentChar(unsigned char c)
 {
diff --git a/src/bin/pg_dump/pg_backup_null.c b/src/bin/pg_dump/pg_backup_null.c
index d9cb02446b3d720a042d4203a90e37f330d5ad03..127ff5721976120c55403940cd125c7cbeb54b90 100644
--- a/src/bin/pg_dump/pg_backup_null.c
+++ b/src/bin/pg_dump/pg_backup_null.c
@@ -17,7 +17,7 @@
  *
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_null.c,v 1.22 2009/08/04 21:56:09 tgl Exp $
+ *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_null.c,v 1.23 2009/12/14 00:39:11 itagaki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -151,8 +151,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
 		die_horribly(AH, NULL, "invalid OID for large object\n");
 
 	if (AH->ropt->dropSchema)
-		ahprintf(AH, "SELECT CASE WHEN EXISTS(SELECT 1 FROM pg_catalog.pg_largeobject WHERE loid = '%u') THEN pg_catalog.lo_unlink('%u') END;\n",
-				 oid, oid);
+		DropBlobIfExists(AH, oid);
 
 	ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n",
 			 oid, INV_WRITE);
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 7af461bd5a65dc544c7b8d7c517238026f9b687f..bb361b33669af047da36b2db511c5716cd61d7c6 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12,7 +12,7 @@
  *	by PostgreSQL
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.555 2009/12/11 03:34:56 itagaki Exp $
+ *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.556 2009/12/14 00:39:11 itagaki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1945,7 +1945,9 @@ hasBlobs(Archive *AH)
 	selectSourceSchema("pg_catalog");
 
 	/* Check for BLOB OIDs */
-	if (AH->remoteVersion >= 70100)
+	if (AH->remoteVersion >= 80500)
+		blobQry = "SELECT oid FROM pg_largeobject_metadata LIMIT 1";
+	else if (AH->remoteVersion >= 70100)
 		blobQry = "SELECT loid FROM pg_largeobject LIMIT 1";
 	else
 		blobQry = "SELECT oid FROM pg_class WHERE relkind = 'l' LIMIT 1";
@@ -1981,7 +1983,9 @@ dumpBlobs(Archive *AH, void *arg)
 	selectSourceSchema("pg_catalog");
 
 	/* Cursor to get all BLOB OIDs */
-	if (AH->remoteVersion >= 70100)
+	if (AH->remoteVersion >= 80500)
+		blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_largeobject_metadata";
+	else if (AH->remoteVersion >= 70100)
 		blobQry = "DECLARE bloboid CURSOR FOR SELECT DISTINCT loid FROM pg_largeobject";
 	else
 		blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_class WHERE relkind = 'l'";
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index 4160cba47dafba97cc4eafd4401f10f1e3a066dc..5cda2302fcf2442066e56babb4bb10770d32a3e9 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -1041,6 +1041,16 @@ SELECT lo_unlink(1002);
 SELECT lo_export(1001, '/dev/null');			-- to be denied
 ERROR:  must be superuser to use server-side lo_export()
 HINT:  Anyone can use the client-side lo_export() provided by libpq.
+-- don't allow unpriv users to access pg_largeobject contents
+\c -
+SELECT * FROM pg_largeobject LIMIT 0;
+ loid | pageno | data 
+------+--------+------
+(0 rows)
+
+SET SESSION AUTHORIZATION regressuser1;
+SELECT * FROM pg_largeobject LIMIT 0;			-- to be denied
+ERROR:  permission denied for relation pg_largeobject
 -- test default ACLs
 \c -
 CREATE SCHEMA testns;
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index 8e8ff70608f6085a26d654a8a714a93c95ea3d0f..a87ce77aa6bd6fdbbc98e4dbcdc72de570cfaba2 100644
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -565,6 +565,13 @@ SELECT lo_truncate(lo_open(1002, x'20000'::int), 10);
 SELECT lo_unlink(1002);
 SELECT lo_export(1001, '/dev/null');			-- to be denied
 
+-- don't allow unpriv users to access pg_largeobject contents
+\c -
+SELECT * FROM pg_largeobject LIMIT 0;
+
+SET SESSION AUTHORIZATION regressuser1;
+SELECT * FROM pg_largeobject LIMIT 0;			-- to be denied
+
 -- test default ACLs
 \c -