diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 7d7aba7aeef77f188326bb2c00c8626e20a1ff9b..ff9b8b0853e2ddb229c902d733828d8667f7e93d 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -14979,6 +14979,11 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
     the table name.
    </para>
 
+   <para>
+    If an OID that does not represent an existing object is passed as
+    argument to one of the above functions, NULL is returned.
+   </para>
+
    <para>
     The functions shown in <xref linkend="functions-admin-dblocation"> assist
     in identifying the specific disk files associated with database objects.
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index cff061c891d9eb3881120d696bb7d12d3f8b5b2d..26a8c01432c7048c0d15af798d401f49906f03a9 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -120,12 +120,6 @@ calculate_database_size(Oid dbOid)
 
 	FreeDir(dirdesc);
 
-	/* Complain if we found no trace of the DB at all */
-	if (!totalsize)
-		ereport(ERROR,
-				(ERRCODE_UNDEFINED_DATABASE,
-				 errmsg("database with OID %u does not exist", dbOid)));
-
 	return totalsize;
 }
 
@@ -133,8 +127,14 @@ Datum
 pg_database_size_oid(PG_FUNCTION_ARGS)
 {
 	Oid			dbOid = PG_GETARG_OID(0);
+	int64		size;
 
-	PG_RETURN_INT64(calculate_database_size(dbOid));
+	size = calculate_database_size(dbOid);
+
+	if (size == 0)
+		PG_RETURN_NULL();
+
+	PG_RETURN_INT64(size);
 }
 
 Datum
@@ -142,13 +142,20 @@ pg_database_size_name(PG_FUNCTION_ARGS)
 {
 	Name		dbName = PG_GETARG_NAME(0);
 	Oid			dbOid = get_database_oid(NameStr(*dbName), false);
+	int64		size;
+
+	size = calculate_database_size(dbOid);
 
-	PG_RETURN_INT64(calculate_database_size(dbOid));
+	if (size == 0)
+		PG_RETURN_NULL();
+
+	PG_RETURN_INT64(size);
 }
 
 
 /*
- * calculate total size of tablespace
+ * Calculate total size of tablespace. Returns -1 if the tablespace directory
+ * cannot be found.
  */
 static int64
 calculate_tablespace_size(Oid tblspcOid)
@@ -184,10 +191,7 @@ calculate_tablespace_size(Oid tblspcOid)
 	dirdesc = AllocateDir(tblspcPath);
 
 	if (!dirdesc)
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not open tablespace directory \"%s\": %m",
-						tblspcPath)));
+		return -1;
 
 	while ((direntry = ReadDir(dirdesc, tblspcPath)) != NULL)
 	{
@@ -226,8 +230,14 @@ Datum
 pg_tablespace_size_oid(PG_FUNCTION_ARGS)
 {
 	Oid			tblspcOid = PG_GETARG_OID(0);
+	int64		size;
+
+	size = calculate_tablespace_size(tblspcOid);
 
-	PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));
+	if (size < 0)
+		PG_RETURN_NULL();
+
+	PG_RETURN_INT64(size);
 }
 
 Datum
@@ -235,8 +245,14 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS)
 {
 	Name		tblspcName = PG_GETARG_NAME(0);
 	Oid			tblspcOid = get_tablespace_oid(NameStr(*tblspcName), false);
+	int64		size;
 
-	PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));
+	size = calculate_tablespace_size(tblspcOid);
+
+	if (size < 0)
+		PG_RETURN_NULL();
+
+	PG_RETURN_INT64(size);
 }
 
 
@@ -289,7 +305,17 @@ pg_relation_size(PG_FUNCTION_ARGS)
 	Relation	rel;
 	int64		size;
 
-	rel = relation_open(relOid, AccessShareLock);
+	rel = try_relation_open(relOid, AccessShareLock);
+
+	/*
+	 * Before 9.2, we used to throw an error if the relation didn't exist, but
+	 * that makes queries like "SELECT pg_relation_size(oid) FROM pg_class"
+	 * less robust, because while we scan pg_class with an MVCC snapshot,
+	 * someone else might drop the table. It's better to return NULL for
+	 * alread-dropped tables than throw an error and abort the whole query.
+	 */
+	if (rel == NULL)
+		PG_RETURN_NULL();
 
 	size = calculate_relation_size(&(rel->rd_node), rel->rd_backend,
 							  forkname_to_number(text_to_cstring(forkName)));
@@ -339,14 +365,11 @@ calculate_toast_table_size(Oid toastrelid)
  * those won't have attached toast tables, but they can have multiple forks.
  */
 static int64
-calculate_table_size(Oid relOid)
+calculate_table_size(Relation rel)
 {
 	int64		size = 0;
-	Relation	rel;
 	ForkNumber	forkNum;
 
-	rel = relation_open(relOid, AccessShareLock);
-
 	/*
 	 * heap size, including FSM and VM
 	 */
@@ -360,8 +383,6 @@ calculate_table_size(Oid relOid)
 	if (OidIsValid(rel->rd_rel->reltoastrelid))
 		size += calculate_toast_table_size(rel->rd_rel->reltoastrelid);
 
-	relation_close(rel, AccessShareLock);
-
 	return size;
 }
 
@@ -371,12 +392,9 @@ calculate_table_size(Oid relOid)
  * Can be applied safely to an index, but you'll just get zero.
  */
 static int64
-calculate_indexes_size(Oid relOid)
+calculate_indexes_size(Relation rel)
 {
 	int64		size = 0;
-	Relation	rel;
-
-	rel = relation_open(relOid, AccessShareLock);
 
 	/*
 	 * Aggregate all indexes on the given relation
@@ -405,8 +423,6 @@ calculate_indexes_size(Oid relOid)
 		list_free(index_oids);
 	}
 
-	relation_close(rel, AccessShareLock);
-
 	return size;
 }
 
@@ -414,16 +430,38 @@ Datum
 pg_table_size(PG_FUNCTION_ARGS)
 {
 	Oid			relOid = PG_GETARG_OID(0);
+	Relation	rel;
+	int64		size;
+
+	rel = try_relation_open(relOid, AccessShareLock);
+
+	if (rel == NULL)
+		PG_RETURN_NULL();
 
-	PG_RETURN_INT64(calculate_table_size(relOid));
+	size = calculate_table_size(rel);
+
+	relation_close(rel, AccessShareLock);
+
+	PG_RETURN_INT64(size);
 }
 
 Datum
 pg_indexes_size(PG_FUNCTION_ARGS)
 {
 	Oid			relOid = PG_GETARG_OID(0);
+	Relation	rel;
+	int64		size;
 
-	PG_RETURN_INT64(calculate_indexes_size(relOid));
+	rel = try_relation_open(relOid, AccessShareLock);
+
+	if (rel == NULL)
+		PG_RETURN_NULL();
+
+	size = calculate_indexes_size(rel);
+
+	relation_close(rel, AccessShareLock);
+
+	PG_RETURN_INT64(size);
 }
 
 /*
@@ -431,7 +469,7 @@ pg_indexes_size(PG_FUNCTION_ARGS)
  *	including heap data, index data, toast data, FSM, VM.
  */
 static int64
-calculate_total_relation_size(Oid Relid)
+calculate_total_relation_size(Relation rel)
 {
 	int64		size;
 
@@ -439,12 +477,12 @@ calculate_total_relation_size(Oid Relid)
 	 * Aggregate the table size, this includes size of the heap, toast and
 	 * toast index with free space and visibility map
 	 */
-	size = calculate_table_size(Relid);
+	size = calculate_table_size(rel);
 
 	/*
 	 * Add size of all attached indexes as well
 	 */
-	size += calculate_indexes_size(Relid);
+	size += calculate_indexes_size(rel);
 
 	return size;
 }
@@ -452,9 +490,20 @@ calculate_total_relation_size(Oid Relid)
 Datum
 pg_total_relation_size(PG_FUNCTION_ARGS)
 {
-	Oid			relid = PG_GETARG_OID(0);
+	Oid			relOid = PG_GETARG_OID(0);
+	Relation	rel;
+	int64		size;
+
+	rel = try_relation_open(relOid, AccessShareLock);
+
+	if (rel == NULL)
+		PG_RETURN_NULL();
 
-	PG_RETURN_INT64(calculate_total_relation_size(relid));
+	size = calculate_total_relation_size(rel);
+
+	relation_close(rel, AccessShareLock);
+
+	PG_RETURN_INT64(size);
 }
 
 /*