diff --git a/src/backend/access/brin/brin_pageops.c b/src/backend/access/brin/brin_pageops.c
index 17257919dbf..daed8ba3bc8 100644
--- a/src/backend/access/brin/brin_pageops.c
+++ b/src/backend/access/brin/brin_pageops.c
@@ -190,6 +190,8 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
 
 			xlrec.offnum = oldoff;
 
+			maybe_crash_on_wal("SAMEPAGE_UPDATE");
+
 			XLogBeginInsert();
 			XLogRegisterData((char *) &xlrec, SizeOfBrinSamepageUpdate);
 
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index c9516e03fae..562192dc514 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -84,6 +84,8 @@ bool		XactDeferrable;
 
 int			synchronous_commit = SYNCHRONOUS_COMMIT_ON;
 
+char	   *crash_on_wal_message;
+
 /*
  * CheckXidAlive is a xid value pointing to a possibly ongoing (sub)
  * transaction.  Currently, it is used in logical decoding.  It's possible
@@ -6157,3 +6159,17 @@ xact_redo(XLogReaderState *record)
 	else
 		elog(PANIC, "xact_redo: unknown op code %u", info);
 }
+
+void
+maybe_crash_on_wal(char *msg)
+{
+	/* GUC not set or not the right message */
+	if (strcmp(crash_on_wal_message, msg) != 0)
+		return;
+
+	/* flush whatever was generated in this xact so far */
+	XLogFlush(XactLastRecEnd);
+
+	elog(PANIC, "crashing before '%s' WAL message", msg);
+}
+
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 4c94f09c645..37bf20e7f04 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -139,6 +139,7 @@ extern char *temp_tablespaces;
 extern bool ignore_checksum_failure;
 extern bool ignore_invalid_pages;
 extern bool synchronize_seqscans;
+extern char *crash_on_wal_message;
 
 #ifdef TRACE_SYNCSCAN
 extern bool trace_syncscan;
@@ -4070,6 +4071,17 @@ static struct config_string ConfigureNamesString[] =
 		check_default_tablespace, NULL, NULL
 	},
 
+	{
+		{"crash_on_wal_message", PGC_USERSET, CLIENT_CONN_STATEMENT,
+			gettext_noop("crash on this WAL message"),
+			NULL,
+			GUC_IS_NAME
+		},
+		&crash_on_wal_message,
+		"",
+		NULL, NULL, NULL
+	},
+
 	{
 		{"temp_tablespaces", PGC_USERSET, CLIENT_CONN_STATEMENT,
 			gettext_noop("Sets the tablespace(s) to use for temporary tables and sort files."),
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 02276d3edd5..fa13c60da32 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -487,4 +487,6 @@ extern void CancelBackup(void);
 /* in executor/nodeHash.c */
 extern size_t get_hash_memory_limit(void);
 
+extern void maybe_crash_on_wal(char *msg);
+
 #endif							/* MISCADMIN_H */
