diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml
index b33e59d5e4..db1b3d5e9a 100644
--- a/doc/src/sgml/bki.sgml
+++ b/doc/src/sgml/bki.sgml
@@ -418,11 +418,11 @@
    <para>
     If <filename>genbki.pl</filename> needs to assign an OID to a catalog
     entry that does not have a manually-assigned OID, it will use a value in
-    the range 10000&mdash;12999.  The server's OID counter is set to 13000
+    the range 10000&mdash;11999.  The server's OID counter is set to 12000
     at the start of a bootstrap run.  Thus objects created by regular SQL
     commands during the later phases of bootstrap, such as objects created
     while running the <filename>information_schema.sql</filename> script,
-    receive OIDs of 13000 or above.
+    receive OIDs of 12000 or above.
    </para>
 
    <para>
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index 112b3affdf..e5e774267e 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -167,15 +167,17 @@ foreach my $oid (keys %oidcounts)
 die "found $found duplicate OID(s) in catalog data\n" if $found;
 
 
-# Oids not specified in the input files are automatically assigned,
+# OIDs not specified in the input files are automatically assigned,
 # starting at FirstGenbkiObjectId, extending up to FirstBootstrapObjectId.
+# We allow such OIDs to be assigned independently within each catalog.
 my $FirstGenbkiObjectId =
   Catalog::FindDefinedSymbol('access/transam.h', $include_path,
 	'FirstGenbkiObjectId');
 my $FirstBootstrapObjectId =
   Catalog::FindDefinedSymbol('access/transam.h', $include_path,
 	'FirstBootstrapObjectId');
-my $GenbkiNextOid = $FirstGenbkiObjectId;
+# Hash of next available OID, indexed by catalog name.
+my %GenbkiNextOids;
 
 
 # Fetch some special data that we will substitute into the output file.
@@ -563,8 +565,7 @@ EOM
 			# Assign oid if oid column exists and no explicit assignment in row
 			if ($attname eq "oid" and not defined $bki_values{$attname})
 			{
-				$bki_values{$attname} = $GenbkiNextOid;
-				$GenbkiNextOid++;
+				$bki_values{$attname} = assign_next_oid($catname);
 			}
 
 			# Replace OID synonyms with OIDs per the appropriate lookup rule.
@@ -669,11 +670,6 @@ foreach my $declaration (@index_decls)
 # last command in the BKI file: build the indexes declared above
 print $bki "build indices\n";
 
-# check that we didn't overrun available OIDs
-die
-  "genbki OID counter reached $GenbkiNextOid, overrunning FirstBootstrapObjectId\n"
-  if $GenbkiNextOid > $FirstBootstrapObjectId;
-
 # Now generate system_constraints.sql
 
 foreach my $c (@system_constraints)
@@ -1081,6 +1077,25 @@ sub form_pg_type_symbol
 	return $name . $arraystr . 'OID';
 }
 
+# Assign an unused OID within the specified catalog.
+sub assign_next_oid
+{
+	my $catname = shift;
+
+	# Initialize, if no previous request for this catalog.
+	$GenbkiNextOids{$catname} = $FirstGenbkiObjectId
+	  if !defined($GenbkiNextOids{$catname});
+
+	my $result = $GenbkiNextOids{$catname}++;
+
+	# Check that we didn't overrun available OIDs
+	die
+	  "genbki OID counter for $catname reached $result, overrunning FirstBootstrapObjectId\n"
+	  if $result >= $FirstBootstrapObjectId;
+
+	return $result;
+}
+
 sub usage
 {
 	die <<EOM;
diff --git a/src/include/access/transam.h b/src/include/access/transam.h
index 05c6fbffe4..2fe8a59110 100644
--- a/src/include/access/transam.h
+++ b/src/include/access/transam.h
@@ -161,18 +161,20 @@ FullTransactionIdAdvance(FullTransactionId *dest)
  *		development purposes (such as in-progress patches and forks);
  *		they should not appear in released versions.
  *
- *		OIDs 10000-12999 are reserved for assignment by genbki.pl, for use
+ *		OIDs 10000-11999 are reserved for assignment by genbki.pl, for use
  *		when the .dat files in src/include/catalog/ do not specify an OID
- *		for a catalog entry that requires one.
+ *		for a catalog entry that requires one.  Note that genbki.pl assigns
+ *		these OIDs independently in each catalog, so they're not guaranteed
+ *		to be globally unique.
  *
- *		OIDS 13000-16383 are reserved for assignment during initdb
- *		using the OID generator.  (We start the generator at 13000.)
+ *		OIDS 12000-16383 are reserved for assignment during initdb
+ *		using the OID generator.  (We start the generator at 12000.)
  *
  *		OIDs beginning at 16384 are assigned from the OID generator
  *		during normal multiuser operation.  (We force the generator up to
  *		16384 as soon as we are in normal operation.)
  *
- * The choices of 8000, 10000 and 13000 are completely arbitrary, and can be
+ * The choices of 8000, 10000 and 12000 are completely arbitrary, and can be
  * moved if we run low on OIDs in any category.  Changing the macros below,
  * and updating relevant documentation (see bki.sgml and RELEASE_CHANGES),
  * should be sufficient to do this.  Moving the 16384 boundary between
@@ -186,7 +188,7 @@ FullTransactionIdAdvance(FullTransactionId *dest)
  * ----------
  */
 #define FirstGenbkiObjectId		10000
-#define FirstBootstrapObjectId	13000
+#define FirstBootstrapObjectId	12000
 #define FirstNormalObjectId		16384
 
 /*
