diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml
index 0c60077e1f..2c0827a440 100644
--- a/doc/src/sgml/ref/pgbench.sgml
+++ b/doc/src/sgml/ref/pgbench.sgml
@@ -326,13 +326,25 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>--extra-indexes</option></term>
+      <listitem>
+       <para>
+        Create extra indexes on the standard tables for referenced FK columns.
+        (This option adds the <literal>i</literal> step to the initialization
+        step sequence, if it is not already present.)
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>--foreign-keys</option></term>
       <listitem>
        <para>
         Create foreign key constraints between the standard tables.
         (This option adds the <literal>f</literal> step to the initialization
-        step sequence, if it is not already present.)
+        step sequence, if it is not already present.)  Also implies
+        <option>--extra-indexes</option>.
        </para>
       </listitem>
      </varlistentry>
@@ -410,7 +422,7 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
       <listitem>
        <para>
         Add the specified built-in script to the list of scripts to be executed.
-        Available built-in scripts are: <literal>tpcb-like</literal>,
+        Available built-in scripts are: <literal>tpcb-like</literal>, <literal>insert-only</literal>,
         <literal>simple-update</literal> and <literal>select-only</literal>.
         Unambiguous prefixes of built-in names are accepted.
         With the special name <literal>list</literal>, show the list of built-in scripts
@@ -489,6 +501,16 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>--insert-only</option></term>
+      <listitem>
+       <para>
+        Run built-in insert-only script.
+        Shorthand for <option>-b insert-only</option>.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>-j</option> <replaceable>threads</replaceable></term>
       <term><option>--jobs=</option><replaceable>threads</replaceable></term>
@@ -986,6 +1008,11 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
    If you select the <literal>select-only</literal> built-in (also <option>-S</option>),
    only the <command>SELECT</command> is issued.
   </para>
+
+  <para>
+   If you select the <literal>insert-only</literal> built-in, 
+   only the <command>INSERT</command> is issued.
+  </para>
  </refsect2>
 
  <refsect2>
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 4aeccd93af..cb30082c58 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -85,6 +85,12 @@
 #define MM2_MUL_TIMES_8		UINT64CONST(0x35253c9ade8f4ca8)
 #define MM2_ROT				47
 
+/* Filler strings of indicated lenghts */
+#define FILLER_ACCOUNTS_PADDING "123456789012345678901234567890123456789012345678901234567890123456789012345678901234"
+#define FILLER_BRANCHES_PADDING "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678"
+#define FILLER_HISTORY_PADDING "1234567890123456789012"
+#define FILLER_TELLERS_PADDING "123456789012345678901234567890123456789012345678901234567890123456789012345678901234"
+
 /*
  * Multi-platform socket set implementations
  */
@@ -616,7 +622,7 @@ static const BuiltinScript builtin_script[] =
 		"SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
 		"UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;\n"
 		"UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;\n"
-		"INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
+		"INSERT INTO pgbench_history (tid, bid, aid, delta, mtime, filler) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP, " FILLER_HISTORY_PADDING ");\n"
 		"END;\n"
 	},
 	{
@@ -629,7 +635,7 @@ static const BuiltinScript builtin_script[] =
 		"BEGIN;\n"
 		"UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
 		"SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
-		"INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
+		"INSERT INTO pgbench_history (tid, bid, aid, delta, mtime, filler) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP, " FILLER_HISTORY_PADDING ");\n"
 		"END;\n"
 	},
 	{
@@ -637,6 +643,15 @@ static const BuiltinScript builtin_script[] =
 		"<builtin: select only>",
 		"\\set aid random(1, " CppAsString2(naccounts) " * :scale)\n"
 		"SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
+	},
+	{
+		"insert-only",
+		"<builtin: insert only>",
+		"\\set aid random(1, " CppAsString2(naccounts) " * :scale)\n"
+		"\\set bid random(1, " CppAsString2(nbranches) " * :scale)\n"
+		"\\set tid random(1, " CppAsString2(ntellers) " * :scale)\n"
+		"\\set delta random(-5000, 5000)\n"
+		"INSERT INTO pgbench_history (tid, bid, aid, delta, mtime, filler) VALUES (:tid, :bid, :aid, :delta,	CURRENT_TIMESTAMP, " FILLER_HISTORY_PADDING ");\n"
 	}
 };
 
@@ -703,6 +718,7 @@ usage(void)
 		   "  -n, --no-vacuum          do not run VACUUM during initialization\n"
 		   "  -q, --quiet              quiet logging (one message each 5 seconds)\n"
 		   "  -s, --scale=NUM          scaling factor\n"
+		   "  --extra-indexes          create additional indexes on the tables\n"
 		   "  --foreign-keys           create foreign key constraints between tables\n"
 		   "  --index-tablespace=TABLESPACE\n"
 		   "                           create indexes in the specified tablespace\n"
@@ -719,6 +735,8 @@ usage(void)
 		   "                           (same as \"-b simple-update\")\n"
 		   "  -S, --select-only        perform SELECT-only transactions\n"
 		   "                           (same as \"-b select-only\")\n"
+		   "  --insert-only            perform INSERT-only transactions\n"
+		   "                           (same as \"-b insert-only\")\n"
 		   "\nBenchmarking options:\n"
 		   "  -c, --client=NUM         number of concurrent database clients (default: 1)\n"
 		   "  -C, --connect            establish new connection for each transaction\n"
@@ -4009,14 +4027,12 @@ initCreateTables(PGconn *con)
 {
 	/*
 	 * Note: TPC-B requires at least 100 bytes per row, and the "filler"
-	 * fields in these table declarations were intended to comply with that.
-	 * The pgbench_accounts table complies with that because the "filler"
-	 * column is set to blank-padded empty string. But for all other tables
-	 * the columns default to NULL and so don't actually take any space.  We
-	 * could fix that by giving them non-null default values.  However, that
-	 * would completely break comparability of pgbench results with prior
-	 * versions. Since pgbench has never pretended to be fully TPC-B compliant
-	 * anyway, we stick with the historical behavior.
+	 * fields in these table declarations comply with that.  This does change
+	 * how "pgbench" has traditionally handled this, which in versions prior
+	 * to 15 used NULL values for this field for every table but the accounts
+	 * table.  It was determined that having this timing data be comparable to
+	 * other benchmarking tools was more important than compatibility with
+	 * previous runs of pgbench.
 	 */
 	struct ddlinfo
 	{
@@ -4146,18 +4162,16 @@ initGenerateDataClientSide(PGconn *con)
 	 */
 	for (i = 0; i < nbranches * scale; i++)
 	{
-		/* "filler" column defaults to NULL */
 		printfPQExpBuffer(&sql,
-						  "insert into pgbench_branches(bid,bbalance) values(%d,0)",
+						  "insert into pgbench_branches(bid,bbalance,filler) values(%d,0,'" FILLER_BRANCHES_PADDING "')",
 						  i + 1);
 		executeStatement(con, sql.data);
 	}
 
 	for (i = 0; i < ntellers * scale; i++)
 	{
-		/* "filler" column defaults to NULL */
 		printfPQExpBuffer(&sql,
-						  "insert into pgbench_tellers(tid,bid,tbalance) values (%d,%d,0)",
+						  "insert into pgbench_tellers(tid,bid,tbalance,filler) values (%d,%d,0,'" FILLER_TELLERS_PADDING "')",
 						  i + 1, i / ntellers + 1);
 		executeStatement(con, sql.data);
 	}
@@ -4181,7 +4195,7 @@ initGenerateDataClientSide(PGconn *con)
 
 		/* "filler" column defaults to blank padded empty string */
 		printfPQExpBuffer(&sql,
-						  INT64_FORMAT "\t" INT64_FORMAT "\t%d\t\n",
+						  INT64_FORMAT "\t" INT64_FORMAT "\t%d\t" FILLER_ACCOUNTS_PADDING "\n",
 						  j, k / naccounts + 1, 0);
 		if (PQputline(con, sql.data))
 		{
@@ -4248,8 +4262,8 @@ initGenerateDataClientSide(PGconn *con)
  * Fill the standard tables with some data generated on the server
  *
  * As already the case with the client-side data generation, the filler
- * column defaults to NULL in pgbench_branches and pgbench_tellers,
- * and is a blank-padded string in pgbench_accounts.
+ * columns default to blank-padded strings, so bring the record size up to
+ * 100.
  */
 static void
 initGenerateDataServerSide(PGconn *con)
@@ -4270,20 +4284,20 @@ initGenerateDataServerSide(PGconn *con)
 	initPQExpBuffer(&sql);
 
 	printfPQExpBuffer(&sql,
-					  "insert into pgbench_branches(bid,bbalance) "
-					  "select bid, 0 "
+					  "insert into pgbench_branches(bid,bbalance,filler) "
+					  "select bid, 0, '" FILLER_BRANCHES_PADDING "' "
 					  "from generate_series(1, %d) as bid", nbranches * scale);
 	executeStatement(con, sql.data);
 
 	printfPQExpBuffer(&sql,
-					  "insert into pgbench_tellers(tid,bid,tbalance) "
-					  "select tid, (tid - 1) / %d + 1, 0 "
+					  "insert into pgbench_tellers(tid,bid,tbalance,filler) "
+					  "select tid, (tid - 1) / %d + 1, 0, '" FILLER_TELLERS_PADDING "' "
 					  "from generate_series(1, %d) as tid", ntellers, ntellers * scale);
 	executeStatement(con, sql.data);
 
 	printfPQExpBuffer(&sql,
 					  "insert into pgbench_accounts(aid,bid,abalance,filler) "
-					  "select aid, (aid - 1) / %d + 1, 0, '' "
+					  "select aid, (aid - 1) / %d + 1, 0, '" FILLER_ACCOUNTS_PADDING "' "
 					  "from generate_series(1, " INT64_FORMAT ") as aid",
 					  naccounts, (int64) naccounts * scale);
 	executeStatement(con, sql.data);
@@ -4366,6 +4380,28 @@ initCreateFKeys(PGconn *con)
 	}
 }
 
+/*
+ * Create extra indexes on the standard tables
+ */
+static void
+initCreateExtraIndexes(PGconn *con)
+{
+	static const char *const DDLKEYs[] = {
+		"create index pgbench_tellers_bid_idx on pgbench_tellers (bid)",
+		"create index pgbench_accounts_bid_idx on pgbench_accounts (bid)",
+		"create index pgbench_history_aid_idx on pgbench_history (aid)",
+		"create index pgbench_history_bid_idx on pgbench_history (bid)",
+		"create index pgbench_history_tid_idx on pgbench_history (tid)"
+	};
+	int			i;
+
+	fprintf(stderr, "creating extra indexes...\n");
+	for (i = 0; i < lengthof(DDLKEYs); i++)
+	{
+		executeStatement(con, DDLKEYs[i]);
+	}
+}
+
 /*
  * Validate an initialization-steps string
  *
@@ -4448,6 +4484,10 @@ runInitSteps(const char *initialize_steps)
 				op = "foreign keys";
 				initCreateFKeys(con);
 				break;
+			case 'i':
+				op = "extra indexes";
+				initCreateExtraIndexes(con);
+				break;
 			case ' ':
 				break;			/* ignore */
 			default:
@@ -5769,6 +5809,8 @@ main(int argc, char **argv)
 		{"show-script", required_argument, NULL, 10},
 		{"partitions", required_argument, NULL, 11},
 		{"partition-method", required_argument, NULL, 12},
+		{"insert-only", no_argument, NULL, 13},
+		{"extra-indexes", no_argument, NULL, 14},
 		{NULL, 0, NULL, 0}
 	};
 
@@ -5776,6 +5818,7 @@ main(int argc, char **argv)
 	bool		is_init_mode = false;	/* initialize mode? */
 	char	   *initialize_steps = NULL;
 	bool		foreign_keys = false;
+	bool		extra_indexes = false;
 	bool		is_no_vacuum = false;
 	bool		do_vacuum_accounts = false; /* vacuum accounts table? */
 	int			optindex;
@@ -6137,6 +6180,15 @@ main(int argc, char **argv)
 					exit(1);
 				}
 				break;
+			case 13:			/* insert-only */
+				process_builtin(findBuiltin("insert-only"), 1);
+				benchmarking_option_set = true;
+				internal_script_used = true;
+				break;
+			case 14:			/* indexes */
+				initialization_option_set = true;
+				extra_indexes = true;
+				break;
 			default:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
 				exit(1);
@@ -6252,6 +6304,19 @@ main(int argc, char **argv)
 			}
 		}
 
+		/* foreign_keys always implies extra_indexes */
+		if (extra_indexes || foreign_keys)
+		{
+			/* Add 'i' to end of initialize_steps, if not already there */
+			if (strchr(initialize_steps, 'i') == NULL)
+			{
+				initialize_steps = (char *)
+					pg_realloc(initialize_steps,
+							   strlen(initialize_steps) + 2);
+				strcat(initialize_steps, "i");
+			}
+		}
+
 		runInitSteps(initialize_steps);
 		exit(0);
 	}
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index c2a35a488a..e8cd07e9c9 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -102,15 +102,13 @@ all: all-lib check-libpq-refs
 include $(top_srcdir)/src/Makefile.shlib
 backend_src = $(top_srcdir)/src/backend
 
-# Check for functions that libpq must not call, currently just exit().
-# (Ideally we'd reject abort() too, but there are various scenarios where
-# build toolchains silently insert abort() calls, e.g. when profiling.)
-# If nm doesn't exist or doesn't work on shlibs, this test will do nothing,
-# which is fine.  The exclusion of __cxa_atexit is necessary on OpenBSD,
-# which seems to insert references to that even in pure C code.
+# Check for functions that libpq must not call, currently abort() and exit().
+# If nm doesn't exist or doesn't work on shlibs, this test will silently
+# do nothing, which is fine.  The exclusion of _eprintf.o is to prevent
+# complaining about <assert.h> infrastructure on ancient macOS releases.
 .PHONY: check-libpq-refs
 check-libpq-refs: $(shlib)
-	! nm -A -g -u $< 2>/dev/null | grep -v __cxa_atexit | grep exit
+	! nm -A -g -u $< 2>/dev/null | grep -v '_eprintf\.o:' | grep -e abort -e exit
 
 # Make dependencies on pg_config_paths.h visible in all builds.
 fe-connect.o: fe-connect.c $(top_builddir)/src/port/pg_config_paths.h
