From 460692de44296f32b9f4b5a2850e75ae47fa448d Mon Sep 17 00:00:00 2001
From: Zsolt Parragi <zsolt.parragi@percona.com>
Date: Tue, 17 Mar 2026 16:20:11 +0000
Subject: [PATCH 3/4] Add explicit padding to WAL record structs and annotate
 with PG_NO_PADDING

Annotate all struct types passed to XLogRegisterData() with PG_NO_PADDING
and add explicit padding fields where the compiler would insert implicit
padding.  This ensures no uninitialized bytes are written to WAL records.

For structs that previously used SizeOfXXXX macros (via offsetof + sizeof
of last field) to skip trailing padding, the macros are replaced with
sizeof() since the explicit padding makes the full struct safe to write.
This is a WAL format change: records now include the previously-skipped
trailing padding bytes, explicitly initialized to zero.

SizeOfXXXX macros for structs with FLEXIBLE_ARRAY_MEMBER are kept, as
they use offsetof() to compute the fixed portion size.
---
 src/backend/access/brin/brin.c                |  2 +-
 src/backend/access/brin/brin_pageops.c        |  6 +-
 src/backend/access/brin/brin_revmap.c         |  4 +-
 src/backend/access/gin/ginbtree.c             |  6 +-
 src/backend/access/gin/gindatapage.c          |  2 +-
 src/backend/access/gin/ginfast.c              |  9 +--
 src/backend/access/gin/ginutil.c              |  2 +-
 src/backend/access/gin/ginvacuum.c            |  2 +-
 src/backend/access/gist/gistxlog.c            | 10 +--
 src/backend/access/hash/hash.c                |  4 +-
 src/backend/access/hash/hashinsert.c          |  4 +-
 src/backend/access/hash/hashovfl.c            |  6 +-
 src/backend/access/hash/hashpage.c            |  8 +-
 src/backend/access/heap/heapam.c              | 32 ++++----
 src/backend/access/heap/heapam_xlog.c         |  6 +-
 src/backend/access/heap/pruneheap.c           | 10 +--
 src/backend/access/heap/rewriteheap.c         |  2 +-
 src/backend/access/nbtree/nbtdedup.c          |  2 +-
 src/backend/access/nbtree/nbtinsert.c         | 10 +--
 src/backend/access/nbtree/nbtpage.c           | 20 ++---
 src/backend/access/rmgrdesc/clogdesc.c        |  2 +-
 src/backend/access/rmgrdesc/xactdesc.c        |  4 +-
 src/backend/access/rmgrdesc/xlogdesc.c        |  6 +-
 src/backend/access/spgist/spgdoinsert.c       | 10 +--
 src/backend/access/spgist/spgvacuum.c         |  6 +-
 src/backend/access/spgist/spgxlog.c           | 14 ++--
 src/backend/access/transam/clog.c             |  4 +-
 src/backend/access/transam/commit_ts.c        |  2 +-
 src/backend/access/transam/multixact.c        |  8 +-
 src/backend/access/transam/xact.c             | 46 ++++++------
 src/backend/access/transam/xlog.c             | 25 ++++---
 src/backend/access/transam/xloginsert.c       |  5 +-
 src/backend/access/transam/xlogreader.c       |  3 +
 src/backend/access/transam/xlogrecovery.c     |  8 +-
 src/backend/catalog/storage.c                 |  4 +-
 src/backend/commands/dbcommands.c             | 10 +--
 src/backend/commands/sequence.c               | 12 +--
 src/backend/commands/tablecmds.c              |  2 +-
 src/backend/commands/tablespace.c             |  4 +-
 src/backend/postmaster/walsummarizer.c        |  6 +-
 src/backend/replication/logical/decode.c      |  2 +-
 src/backend/replication/logical/message.c     |  2 +-
 src/backend/replication/logical/origin.c      |  4 +-
 src/backend/storage/ipc/standby.c             | 14 ++--
 src/backend/utils/cache/inval.c               |  6 +-
 src/backend/utils/cache/relmapper.c           | 12 +--
 src/bin/pg_resetwal/pg_resetwal.c             |  1 +
 src/include/access/brin_xlog.h                | 30 ++++----
 src/include/access/clog.h                     |  2 +-
 src/include/access/commit_ts.h                |  6 +-
 src/include/access/ginblock.h                 |  6 +-
 src/include/access/ginxlog.h                  | 19 +++--
 src/include/access/gistxlog.h                 | 24 ++++--
 src/include/access/hash_xlog.h                | 56 +++++++-------
 src/include/access/heapam_xlog.h              | 75 ++++++++++++-------
 src/include/access/multixact.h                |  6 +-
 src/include/access/nbtxlog.h                  | 53 +++++++------
 src/include/access/spgist_private.h           |  6 +-
 src/include/access/spgxlog.h                  | 29 ++++---
 src/include/access/xact.h                     | 24 +++---
 src/include/access/xlog_internal.h            | 15 ++--
 src/include/access/xlogrecord.h               | 19 ++---
 src/include/catalog/pg_control.h              |  8 +-
 src/include/catalog/storage_xlog.h            |  4 +-
 src/include/commands/dbcommands_xlog.h        |  6 +-
 src/include/commands/sequence_xlog.h          |  2 +-
 src/include/commands/tablespace.h             |  4 +-
 src/include/replication/message.h             |  4 +-
 src/include/replication/origin.h              |  6 +-
 src/include/storage/lockdefs.h                |  2 +-
 src/include/storage/sinval.h                  | 28 +++++--
 src/include/storage/standbydefs.h             | 10 ++-
 src/include/utils/relmapper.h                 |  2 +-
 .../test_custom_rmgrs/test_custom_rmgrs.c     |  2 +-
 src/test/recovery/t/039_end_of_wal.pl         |  5 +-
 75 files changed, 457 insertions(+), 365 deletions(-)

diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 6887e421442..8ef44a0075b 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -1135,7 +1135,7 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo)
 
 	if (RelationNeedsWAL(index))
 	{
-		xl_brin_createidx xlrec;
+		xl_brin_createidx xlrec = {0};
 		XLogRecPtr	recptr;
 		Page		page;
 
diff --git a/src/backend/access/brin/brin_pageops.c b/src/backend/access/brin/brin_pageops.c
index 7da97bec43b..a1e8bd0e225 100644
--- a/src/backend/access/brin/brin_pageops.c
+++ b/src/backend/access/brin/brin_pageops.c
@@ -183,7 +183,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
 		/* XLOG stuff */
 		if (RelationNeedsWAL(idxrel))
 		{
-			xl_brin_samepage_update xlrec;
+			xl_brin_samepage_update xlrec = {0};
 			XLogRecPtr	recptr;
 			uint8		info = XLOG_BRIN_SAMEPAGE_UPDATE;
 
@@ -267,7 +267,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
 		/* XLOG stuff */
 		if (RelationNeedsWAL(idxrel))
 		{
-			xl_brin_update xlrec;
+			xl_brin_update xlrec = {0};
 			XLogRecPtr	recptr;
 			uint8		info;
 
@@ -423,7 +423,7 @@ brin_doinsert(Relation idxrel, BlockNumber pagesPerRange,
 	/* XLOG stuff */
 	if (RelationNeedsWAL(idxrel))
 	{
-		xl_brin_insert xlrec;
+		xl_brin_insert xlrec = {0};
 		XLogRecPtr	recptr;
 		uint8		info;
 
diff --git a/src/backend/access/brin/brin_revmap.c b/src/backend/access/brin/brin_revmap.c
index 233355cb2d5..57ac044497a 100644
--- a/src/backend/access/brin/brin_revmap.c
+++ b/src/backend/access/brin/brin_revmap.c
@@ -408,7 +408,7 @@ brinRevmapDesummarizeRange(Relation idxrel, BlockNumber heapBlk)
 
 	if (RelationNeedsWAL(idxrel))
 	{
-		xl_brin_desummarize xlrec;
+		xl_brin_desummarize xlrec = {0};
 		XLogRecPtr	recptr;
 
 		xlrec.pagesPerRange = revmap->rm_pagesPerRange;
@@ -621,7 +621,7 @@ revmap_physical_extend(BrinRevmap *revmap)
 
 	if (RelationNeedsWAL(revmap->rm_irel))
 	{
-		xl_brin_revmap_extend xlrec;
+		xl_brin_revmap_extend xlrec = {0};
 		XLogRecPtr	recptr;
 
 		xlrec.targetBlk = mapBlk;
diff --git a/src/backend/access/gin/ginbtree.c b/src/backend/access/gin/ginbtree.c
index 3d3a9da56b1..d28f79b8dce 100644
--- a/src/backend/access/gin/ginbtree.c
+++ b/src/backend/access/gin/ginbtree.c
@@ -418,7 +418,7 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack,
 		if (RelationNeedsWAL(btree->index) && !btree->isBuild)
 		{
 			XLogRecPtr	recptr;
-			ginxlogInsert xlrec;
+			ginxlogInsert xlrec = {0};
 			BlockIdData childblknos[2];
 
 			xlrec.flags = xlflags;
@@ -433,7 +433,7 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack,
 			{
 				BlockIdSet(&childblknos[0], BufferGetBlockNumber(childbuf));
 				BlockIdSet(&childblknos[1], GinPageGetOpaque(childpage)->rightlink);
-				XLogRegisterData(childblknos,
+				XLogRegisterData((char *) childblknos,
 								 sizeof(BlockIdData) * 2);
 			}
 
@@ -457,7 +457,7 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack,
 		 */
 		Buffer		rbuffer;
 		BlockNumber savedRightLink;
-		ginxlogSplit data;
+		ginxlogSplit data = {0};
 		Buffer		lbuffer = InvalidBuffer;
 		Page		newrootpg = NULL;
 
diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c
index c5d7db28077..7d9a466f1e5 100644
--- a/src/backend/access/gin/gindatapage.c
+++ b/src/backend/access/gin/gindatapage.c
@@ -1839,7 +1839,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
 	if (RelationNeedsWAL(index) && !is_build)
 	{
 		XLogRecPtr	recptr;
-		ginxlogCreatePostingTree data;
+		ginxlogCreatePostingTree data = {0};
 
 		data.size = rootsize;
 
diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c
index f50848eb65a..63a072a5688 100644
--- a/src/backend/access/gin/ginfast.c
+++ b/src/backend/access/gin/ginfast.c
@@ -115,7 +115,7 @@ writeListPage(Relation index, Buffer buffer,
 
 	if (RelationNeedsWAL(index))
 	{
-		ginxlogInsertListPage data;
+		ginxlogInsertListPage data = {0};
 		XLogRecPtr	recptr;
 
 		data.rightlink = rightlink;
@@ -224,7 +224,7 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
 	GinMetaPageData *metadata = NULL;
 	Buffer		buffer = InvalidBuffer;
 	Page		page = NULL;
-	ginxlogUpdateMeta data;
+	ginxlogUpdateMeta data = {0};
 	bool		separateList = false;
 	bool		needCleanup = false;
 	int			cleanupSize;
@@ -281,9 +281,8 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
 		/*
 		 * We should make sublist separately and append it to the tail
 		 */
-		GinMetaPageData sublist;
+		GinMetaPageData sublist = {0};
 
-		memset(&sublist, 0, sizeof(GinMetaPageData));
 		makeSublist(index, collector->tuples, collector->ntuples, &sublist);
 
 		/*
@@ -567,7 +566,7 @@ shiftList(Relation index, Buffer metabuffer, BlockNumber newHead,
 		Page		page;
 		int			i;
 		int64		nDeletedHeapTuples = 0;
-		ginxlogDeleteListPages data;
+		ginxlogDeleteListPages data = {0};
 		Buffer		buffers[GIN_NDELETE_AT_ONCE];
 		BlockNumber freespace[GIN_NDELETE_AT_ONCE];
 
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index ff927279cc3..1b228c17540 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -648,7 +648,7 @@ ginUpdateStats(Relation index, const GinStatsData *stats, bool is_build)
 	if (RelationNeedsWAL(index) && !is_build)
 	{
 		XLogRecPtr	recptr;
-		ginxlogUpdateMeta data;
+		ginxlogUpdateMeta data = {0};
 
 		data.locator = index->rd_locator;
 		data.ntuples = 0;
diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c
index c9f143f6c31..5b488e89a56 100644
--- a/src/backend/access/gin/ginvacuum.c
+++ b/src/backend/access/gin/ginvacuum.c
@@ -197,7 +197,7 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn
 	if (RelationNeedsWAL(gvs->index))
 	{
 		XLogRecPtr	recptr;
-		ginxlogDeletePage data;
+		ginxlogDeletePage data = {0};
 
 		/*
 		 * We can't pass REGBUF_STANDARD for the deleted page, because we
diff --git a/src/backend/access/gist/gistxlog.c b/src/backend/access/gist/gistxlog.c
index c783838495f..b93e831b829 100644
--- a/src/backend/access/gist/gistxlog.c
+++ b/src/backend/access/gist/gistxlog.c
@@ -495,7 +495,7 @@ gistXLogSplit(bool page_is_leaf,
 			  BlockNumber origrlink, GistNSN orignsn,
 			  Buffer leftchildbuf, bool markfollowright)
 {
-	gistxlogPageSplit xlrec;
+	gistxlogPageSplit xlrec = {0};
 	SplitPageLayout *ptr;
 	int			npage = 0;
 	XLogRecPtr	recptr;
@@ -550,7 +550,7 @@ XLogRecPtr
 gistXLogPageDelete(Buffer buffer, FullTransactionId xid,
 				   Buffer parentBuffer, OffsetNumber downlinkOffset)
 {
-	gistxlogPageDelete xlrec;
+	gistxlogPageDelete xlrec = {0};
 	XLogRecPtr	recptr;
 
 	xlrec.deleteXid = xid;
@@ -592,7 +592,7 @@ void
 gistXLogPageReuse(Relation rel, Relation heaprel,
 				  BlockNumber blkno, FullTransactionId deleteXid)
 {
-	gistxlogPageReuse xlrec_reuse;
+	gistxlogPageReuse xlrec_reuse = {0};
 
 	/*
 	 * Note that we don't register the buffer with the record, because this
@@ -629,7 +629,7 @@ gistXLogUpdate(Buffer buffer,
 			   IndexTuple *itup, int ituplen,
 			   Buffer leftchildbuf)
 {
-	gistxlogPageUpdate xlrec;
+	gistxlogPageUpdate xlrec = {0};
 	int			i;
 	XLogRecPtr	recptr;
 
@@ -668,7 +668,7 @@ XLogRecPtr
 gistXLogDelete(Buffer buffer, OffsetNumber *todelete, int ntodelete,
 			   TransactionId snapshotConflictHorizon, Relation heaprel)
 {
-	gistxlogDelete xlrec;
+	gistxlogDelete xlrec = {0};
 	XLogRecPtr	recptr;
 
 	xlrec.isCatalogRel = RelationIsAccessibleInLogicalDecoding(heaprel);
diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c
index e88ddb32a05..f565cfc77a8 100644
--- a/src/backend/access/hash/hash.c
+++ b/src/backend/access/hash/hash.c
@@ -613,7 +613,7 @@ loop_top:
 	/* XLOG stuff */
 	if (RelationNeedsWAL(rel))
 	{
-		xl_hash_update_meta_page xlrec;
+		xl_hash_update_meta_page xlrec = {0};
 		XLogRecPtr	recptr;
 
 		xlrec.ntuples = metap->hashm_ntuples;
@@ -819,7 +819,7 @@ hashbucketcleanup(Relation rel, Bucket cur_bucket, Buffer bucket_buf,
 			/* XLOG stuff */
 			if (RelationNeedsWAL(rel))
 			{
-				xl_hash_delete xlrec;
+				xl_hash_delete xlrec = {0};
 				XLogRecPtr	recptr;
 
 				xlrec.clear_dead_marking = clear_dead_marking;
diff --git a/src/backend/access/hash/hashinsert.c b/src/backend/access/hash/hashinsert.c
index 0cefbacc96e..5ba623393a8 100644
--- a/src/backend/access/hash/hashinsert.c
+++ b/src/backend/access/hash/hashinsert.c
@@ -215,7 +215,7 @@ restart_insert:
 	/* XLOG stuff */
 	if (RelationNeedsWAL(rel))
 	{
-		xl_hash_insert xlrec;
+		xl_hash_insert xlrec = {0};
 		XLogRecPtr	recptr;
 
 		xlrec.offnum = itup_off;
@@ -423,7 +423,7 @@ _hash_vacuum_one_page(Relation rel, Relation hrel, Buffer metabuf, Buffer buf)
 		/* XLOG stuff */
 		if (RelationNeedsWAL(rel))
 		{
-			xl_hash_vacuum_one_page xlrec;
+			xl_hash_vacuum_one_page xlrec = {0};
 			XLogRecPtr	recptr;
 
 			xlrec.isCatalogRel = RelationIsAccessibleInLogicalDecoding(hrel);
diff --git a/src/backend/access/hash/hashovfl.c b/src/backend/access/hash/hashovfl.c
index 8cfb6ce75d6..69e90ffac5b 100644
--- a/src/backend/access/hash/hashovfl.c
+++ b/src/backend/access/hash/hashovfl.c
@@ -382,7 +382,7 @@ found:
 	if (RelationNeedsWAL(rel))
 	{
 		XLogRecPtr	recptr;
-		xl_hash_add_ovfl_page xlrec;
+		xl_hash_add_ovfl_page xlrec = {0};
 
 		xlrec.bmpage_found = page_found;
 		xlrec.bmsize = metap->hashm_bmsize;
@@ -644,7 +644,7 @@ _hash_freeovflpage(Relation rel, Buffer bucketbuf, Buffer ovflbuf,
 	/* XLOG stuff */
 	if (RelationNeedsWAL(rel))
 	{
-		xl_hash_squeeze_page xlrec;
+		xl_hash_squeeze_page xlrec = {0};
 		XLogRecPtr	recptr;
 		int			i;
 		bool		mod_wbuf = false;
@@ -987,7 +987,7 @@ readpage:
 					if (RelationNeedsWAL(rel))
 					{
 						XLogRecPtr	recptr;
-						xl_hash_move_page_contents xlrec;
+						xl_hash_move_page_contents xlrec = {0};
 
 						xlrec.ntups = nitups;
 						xlrec.is_prim_bucket_same_wrt = (wbuf == bucket_buf);
diff --git a/src/backend/access/hash/hashpage.c b/src/backend/access/hash/hashpage.c
index 8e220a3ae16..61a0badbfaa 100644
--- a/src/backend/access/hash/hashpage.c
+++ b/src/backend/access/hash/hashpage.c
@@ -386,7 +386,7 @@ _hash_init(Relation rel, double num_tuples, ForkNumber forkNum)
 	/* XLOG stuff */
 	if (use_wal)
 	{
-		xl_hash_init_meta_page xlrec;
+		xl_hash_init_meta_page xlrec = {0};
 		XLogRecPtr	recptr;
 
 		xlrec.num_tuples = num_tuples;
@@ -462,7 +462,7 @@ _hash_init(Relation rel, double num_tuples, ForkNumber forkNum)
 	/* XLOG stuff */
 	if (use_wal)
 	{
-		xl_hash_init_bitmap_page xlrec;
+		xl_hash_init_bitmap_page xlrec = {0};
 		XLogRecPtr	recptr;
 
 		xlrec.bmsize = metap->hashm_bmsize;
@@ -899,7 +899,7 @@ restart_expand:
 	/* XLOG stuff */
 	if (RelationNeedsWAL(rel))
 	{
-		xl_hash_split_allocate_page xlrec;
+		xl_hash_split_allocate_page xlrec = {0};
 		XLogRecPtr	recptr;
 
 		xlrec.new_bucket = maxbucket;
@@ -1297,7 +1297,7 @@ _hash_splitbucket(Relation rel,
 	if (RelationNeedsWAL(rel))
 	{
 		XLogRecPtr	recptr;
-		xl_hash_split_complete xlrec;
+		xl_hash_split_complete xlrec = {0};
 
 		xlrec.old_bucket_flag = oopaque->hasho_flag;
 		xlrec.new_bucket_flag = nopaque->hasho_flag;
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 98d53caeea8..c8b1ef7d372 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -2218,8 +2218,8 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
 	/* XLOG stuff */
 	if (RelationNeedsWAL(relation))
 	{
-		xl_heap_insert xlrec;
-		xl_heap_header xlhdr;
+		xl_heap_insert xlrec = {0};
+		xl_heap_header xlhdr = {0};
 		XLogRecPtr	recptr;
 		Page		page = BufferGetPage(buffer);
 		uint8		info = XLOG_HEAP_INSERT;
@@ -3149,8 +3149,8 @@ l1:
 	 */
 	if (RelationNeedsWAL(relation))
 	{
-		xl_heap_delete xlrec;
-		xl_heap_header xlhdr;
+		xl_heap_delete xlrec = {0};
+		xl_heap_header xlhdr = {0};
 		XLogRecPtr	recptr;
 
 		/*
@@ -3948,7 +3948,7 @@ l2:
 
 		if (RelationNeedsWAL(relation))
 		{
-			xl_heap_lock xlrec;
+			xl_heap_lock xlrec = {0};
 			XLogRecPtr	recptr;
 
 			XLogBeginInsert();
@@ -5283,7 +5283,7 @@ failed:
 	 */
 	if (RelationNeedsWAL(relation))
 	{
-		xl_heap_lock xlrec;
+		xl_heap_lock xlrec = {0};
 		XLogRecPtr	recptr;
 
 		XLogBeginInsert();
@@ -6034,7 +6034,7 @@ l4:
 		/* XLOG stuff */
 		if (RelationNeedsWAL(rel))
 		{
-			xl_heap_lock_updated xlrec;
+			xl_heap_lock_updated xlrec = {0};
 			XLogRecPtr	recptr;
 			Page		page = BufferGetPage(buf);
 
@@ -6201,7 +6201,7 @@ heap_finish_speculative(Relation relation, const ItemPointerData *tid)
 	/* XLOG stuff */
 	if (RelationNeedsWAL(relation))
 	{
-		xl_heap_confirm xlrec;
+		xl_heap_confirm xlrec = {0};
 		XLogRecPtr	recptr;
 
 		xlrec.offnum = ItemPointerGetOffsetNumber(tid);
@@ -6346,7 +6346,7 @@ heap_abort_speculative(Relation relation, const ItemPointerData *tid)
 	 */
 	if (RelationNeedsWAL(relation))
 	{
-		xl_heap_delete xlrec;
+		xl_heap_delete xlrec = {0};
 		XLogRecPtr	recptr;
 
 		xlrec.flags = XLH_DELETE_IS_SUPER;
@@ -6646,7 +6646,7 @@ heap_inplace_update_and_unlock(Relation relation,
 	/* XLOG stuff */
 	if (RelationNeedsWAL(relation))
 	{
-		xl_heap_inplace xlrec;
+		xl_heap_inplace xlrec = {0};
 		PGAlignedBlock copied_buffer;
 		char	   *origdata = (char *) BufferGetBlock(buffer);
 		Page		page = BufferGetPage(buffer);
@@ -6667,7 +6667,7 @@ heap_inplace_update_and_unlock(Relation relation,
 		XLogBeginInsert();
 		XLogRegisterData(&xlrec, MinSizeOfHeapInplace);
 		if (nmsgs != 0)
-			XLogRegisterData(invalMessages,
+			XLogRegisterData((char *) invalMessages,
 							 nmsgs * sizeof(SharedInvalidationMessage));
 
 		/* register block matching what buffer will look like after changes */
@@ -8884,7 +8884,7 @@ XLogRecPtr
 log_heap_visible(Relation rel, Buffer heap_buffer, Buffer vm_buffer,
 				 TransactionId snapshotConflictHorizon, uint8 vmflags)
 {
-	xl_heap_visible xlrec;
+	xl_heap_visible xlrec = {0};
 	XLogRecPtr	recptr;
 	uint8		flags;
 
@@ -8920,9 +8920,9 @@ log_heap_update(Relation reln, Buffer oldbuf,
 				HeapTuple old_key_tuple,
 				bool all_visible_cleared, bool new_all_visible_cleared)
 {
-	xl_heap_update xlrec;
-	xl_heap_header xlhdr;
-	xl_heap_header xlhdr_idx;
+	xl_heap_update xlrec = {0};
+	xl_heap_header xlhdr = {0};
+	xl_heap_header xlhdr_idx = {0};
 	uint8		info;
 	uint16		prefix_suffix[2];
 	uint16		prefixlen = 0,
@@ -9139,7 +9139,7 @@ log_heap_update(Relation reln, Buffer oldbuf,
 static XLogRecPtr
 log_heap_new_cid(Relation relation, HeapTuple tup)
 {
-	xl_heap_new_cid xlrec;
+	xl_heap_new_cid xlrec = {0};
 
 	XLogRecPtr	recptr;
 	HeapTupleHeader hdr = tup->t_data;
diff --git a/src/backend/access/heap/heapam_xlog.c b/src/backend/access/heap/heapam_xlog.c
index f765345e9e4..46fc689302d 100644
--- a/src/backend/access/heap/heapam_xlog.c
+++ b/src/backend/access/heap/heapam_xlog.c
@@ -31,7 +31,7 @@ heap_xlog_prune_freeze(XLogReaderState *record)
 {
 	XLogRecPtr	lsn = record->EndRecPtr;
 	char	   *maindataptr = XLogRecGetData(record);
-	xl_heap_prune xlrec;
+	xl_heap_prune xlrec = {0};
 	Buffer		buffer;
 	RelFileLocator rlocator;
 	BlockNumber blkno;
@@ -504,7 +504,7 @@ heap_xlog_insert(XLogReaderState *record)
 		char		data[MaxHeapTupleSize];
 	}			tbuf;
 	HeapTupleHeader htup;
-	xl_heap_header xlhdr;
+	xl_heap_header xlhdr = {0};
 	uint32		newlen;
 	Size		freespace = 0;
 	RelFileLocator target_locator;
@@ -828,7 +828,7 @@ heap_xlog_update(XLogReaderState *record, bool hot_update)
 		HeapTupleHeaderData hdr;
 		char		data[MaxHeapTupleSize];
 	}			tbuf;
-	xl_heap_header xlhdr;
+	xl_heap_header xlhdr = {0};
 	uint32		newlen;
 	Size		freespace = 0;
 	XLogRedoAction oldaction;
diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index 632c2427952..d609b63ef97 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -2174,17 +2174,17 @@ log_heap_prune_and_freeze(Relation relation, Buffer buffer,
 						  OffsetNumber *dead, int ndead,
 						  OffsetNumber *unused, int nunused)
 {
-	xl_heap_prune xlrec;
+	xl_heap_prune xlrec = {0};
 	XLogRecPtr	recptr;
 	uint8		info;
 	uint8		regbuf_flags_heap;
 
 	/* The following local variables hold data registered in the WAL record: */
 	xlhp_freeze_plan plans[MaxHeapTuplesPerPage];
-	xlhp_freeze_plans freeze_plans;
-	xlhp_prune_items redirect_items;
-	xlhp_prune_items dead_items;
-	xlhp_prune_items unused_items;
+	xlhp_freeze_plans freeze_plans = {0};
+	xlhp_prune_items redirect_items = {0};
+	xlhp_prune_items dead_items = {0};
+	xlhp_prune_items unused_items = {0};
 	OffsetNumber frz_offsets[MaxHeapTuplesPerPage];
 	bool		do_prune = nredirected > 0 || ndead > 0 || nunused > 0;
 	bool		do_set_vm = vmflags & VISIBILITYMAP_VALID_BITS;
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 77fd48eb59e..2f47222a5c0 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -826,7 +826,7 @@ logical_heap_rewrite_flush_mappings(RewriteState state)
 	{
 		char	   *waldata;
 		char	   *waldata_start;
-		xl_heap_rewrite_mapping xlrec;
+		xl_heap_rewrite_mapping xlrec = {0};
 		Oid			dboid;
 		uint32		len;
 		int			written;
diff --git a/src/backend/access/nbtree/nbtdedup.c b/src/backend/access/nbtree/nbtdedup.c
index 95be0b17939..e20590a5547 100644
--- a/src/backend/access/nbtree/nbtdedup.c
+++ b/src/backend/access/nbtree/nbtdedup.c
@@ -246,7 +246,7 @@ _bt_dedup_pass(Relation rel, Buffer buf, IndexTuple newitem, Size newitemsz,
 	if (RelationNeedsWAL(rel))
 	{
 		XLogRecPtr	recptr;
-		xl_btree_dedup xlrec_dedup;
+		xl_btree_dedup xlrec_dedup = {0};
 
 		xlrec_dedup.nintervals = state->nintervals;
 
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index d17aaa5aa0f..71a62b06692 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -1319,8 +1319,8 @@ _bt_insertonpg(Relation rel,
 		/* XLOG stuff */
 		if (RelationNeedsWAL(rel))
 		{
-			xl_btree_insert xlrec;
-			xl_btree_metadata xlmeta;
+			xl_btree_insert xlrec = {0};
+			xl_btree_metadata xlmeta = {0};
 			uint8		xlinfo;
 			XLogRecPtr	recptr;
 			uint16		upostingoff;
@@ -1981,7 +1981,7 @@ _bt_split(Relation rel, Relation heaprel, BTScanInsert itup_key, Buffer buf,
 	/* XLOG stuff */
 	if (RelationNeedsWAL(rel))
 	{
-		xl_btree_split xlrec;
+		xl_btree_split xlrec = {0};
 		uint8		xlinfo;
 		XLogRecPtr	recptr;
 
@@ -2570,9 +2570,9 @@ _bt_newlevel(Relation rel, Relation heaprel, Buffer lbuf, Buffer rbuf)
 	/* XLOG stuff */
 	if (RelationNeedsWAL(rel))
 	{
-		xl_btree_newroot xlrec;
+		xl_btree_newroot xlrec = {0};
 		XLogRecPtr	recptr;
-		xl_btree_metadata md;
+		xl_btree_metadata md = {0};
 
 		xlrec.rootblk = rootblknum;
 		xlrec.level = metad->btm_level;
diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c
index 4125c185e8b..80f9ec2c846 100644
--- a/src/backend/access/nbtree/nbtpage.c
+++ b/src/backend/access/nbtree/nbtpage.c
@@ -285,7 +285,7 @@ _bt_set_cleanup_info(Relation rel, BlockNumber num_delpages)
 	/* write wal record if needed */
 	if (RelationNeedsWAL(rel))
 	{
-		xl_btree_metadata md;
+		xl_btree_metadata md = {0};
 		XLogRecPtr	recptr;
 
 		XLogBeginInsert();
@@ -472,9 +472,9 @@ _bt_getroot(Relation rel, Relation heaprel, int access)
 		/* XLOG stuff */
 		if (RelationNeedsWAL(rel))
 		{
-			xl_btree_newroot xlrec;
+			xl_btree_newroot xlrec = {0};
 			XLogRecPtr	recptr;
-			xl_btree_metadata md;
+			xl_btree_metadata md = {0};
 
 			XLogBeginInsert();
 			XLogRegisterBuffer(0, rootbuf, REGBUF_WILL_INIT);
@@ -933,7 +933,7 @@ _bt_allocbuf(Relation rel, Relation heaprel)
 				 */
 				if (RelationNeedsWAL(rel) && XLogStandbyInfoActive())
 				{
-					xl_btree_reuse_page xlrec_reuse;
+					xl_btree_reuse_page xlrec_reuse = {0};
 
 					/*
 					 * Note that we don't register the buffer with the record,
@@ -1227,7 +1227,7 @@ _bt_delitems_vacuum(Relation rel, Buffer buf,
 	if (needswal)
 	{
 		XLogRecPtr	recptr;
-		xl_btree_vacuum xlrec_vacuum;
+		xl_btree_vacuum xlrec_vacuum = {0};
 
 		xlrec_vacuum.ndeleted = ndeletable;
 		xlrec_vacuum.nupdated = nupdatable;
@@ -1343,7 +1343,7 @@ _bt_delitems_delete(Relation rel, Buffer buf,
 	if (needswal)
 	{
 		XLogRecPtr	recptr;
-		xl_btree_delete xlrec_delete;
+		xl_btree_delete xlrec_delete = {0};
 
 		xlrec_delete.snapshotConflictHorizon = snapshotConflictHorizon;
 		xlrec_delete.ndeleted = ndeletable;
@@ -1439,7 +1439,7 @@ _bt_delitems_update(BTVacuumPosting *updatable, int nupdatable,
 		{
 			BTVacuumPosting vacposting = updatable[i];
 			Size		itemsz;
-			xl_btree_update update;
+			xl_btree_update update = {0};
 
 			update.ndeletedtids = vacposting->ndeletedtids;
 			memcpy(updatedbuf + offset, &update.ndeletedtids,
@@ -2252,7 +2252,7 @@ _bt_mark_page_halfdead(Relation rel, Relation heaprel, Buffer leafbuf,
 	/* XLOG stuff */
 	if (RelationNeedsWAL(rel))
 	{
-		xl_btree_mark_page_halfdead xlrec;
+		xl_btree_mark_page_halfdead xlrec = {0};
 		XLogRecPtr	recptr;
 
 		xlrec.poffset = poffset;
@@ -2673,8 +2673,8 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
 	/* XLOG stuff */
 	if (RelationNeedsWAL(rel))
 	{
-		xl_btree_unlink_page xlrec;
-		xl_btree_metadata xlmeta;
+		xl_btree_unlink_page xlrec = {0};
+		xl_btree_metadata xlmeta = {0};
 		uint8		xlinfo;
 		XLogRecPtr	recptr;
 
diff --git a/src/backend/access/rmgrdesc/clogdesc.c b/src/backend/access/rmgrdesc/clogdesc.c
index 022376045d7..5669f0387c6 100644
--- a/src/backend/access/rmgrdesc/clogdesc.c
+++ b/src/backend/access/rmgrdesc/clogdesc.c
@@ -32,7 +32,7 @@ clog_desc(StringInfo buf, XLogReaderState *record)
 	}
 	else if (info == CLOG_TRUNCATE)
 	{
-		xl_clog_truncate xlrec;
+		xl_clog_truncate xlrec = {0};
 
 		memcpy(&xlrec, rec, sizeof(xl_clog_truncate));
 		appendStringInfo(buf, "page %" PRId64 "; oldestXact %u",
diff --git a/src/backend/access/rmgrdesc/xactdesc.c b/src/backend/access/rmgrdesc/xactdesc.c
index 4f53d3035cc..5e9b08b1dac 100644
--- a/src/backend/access/rmgrdesc/xactdesc.c
+++ b/src/backend/access/rmgrdesc/xactdesc.c
@@ -125,7 +125,7 @@ ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *pars
 
 	if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
 	{
-		xl_xact_origin xl_origin;
+		xl_xact_origin xl_origin = {0};
 
 		/* no alignment is guaranteed, so copy onto stack */
 		memcpy(&xl_origin, data, sizeof(xl_origin));
@@ -220,7 +220,7 @@ ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
 
 	if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
 	{
-		xl_xact_origin xl_origin;
+		xl_xact_origin xl_origin = {0};
 
 		/* no alignment is guaranteed, so copy onto stack */
 		memcpy(&xl_origin, data, sizeof(xl_origin));
diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c
index ff078f22264..6b3341d746e 100644
--- a/src/backend/access/rmgrdesc/xlogdesc.c
+++ b/src/backend/access/rmgrdesc/xlogdesc.c
@@ -116,7 +116,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
 	}
 	else if (info == XLOG_PARAMETER_CHANGE)
 	{
-		xl_parameter_change xlrec;
+		xl_parameter_change xlrec = {0};
 		const char *wal_level_str;
 
 		memcpy(&xlrec, rec, sizeof(xl_parameter_change));
@@ -144,7 +144,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
 	}
 	else if (info == XLOG_END_OF_RECOVERY)
 	{
-		xl_end_of_recovery xlrec;
+		xl_end_of_recovery xlrec = {0};
 
 		memcpy(&xlrec, rec, sizeof(xl_end_of_recovery));
 		appendStringInfo(buf, "tli %u; prev tli %u; time %s; wal_level %s",
@@ -154,7 +154,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
 	}
 	else if (info == XLOG_OVERWRITE_CONTRECORD)
 	{
-		xl_overwrite_contrecord xlrec;
+		xl_overwrite_contrecord xlrec = {0};
 
 		memcpy(&xlrec, rec, sizeof(xl_overwrite_contrecord));
 		appendStringInfo(buf, "lsn %X/%08X; time %s",
diff --git a/src/backend/access/spgist/spgdoinsert.c b/src/backend/access/spgist/spgdoinsert.c
index 7c7371c69e8..44e29814b10 100644
--- a/src/backend/access/spgist/spgdoinsert.c
+++ b/src/backend/access/spgist/spgdoinsert.c
@@ -202,7 +202,7 @@ static void
 addLeafTuple(Relation index, SpGistState *state, SpGistLeafTuple leafTuple,
 			 SPPageDesc *current, SPPageDesc *parent, bool isNulls, bool isNew)
 {
-	spgxlogAddLeaf xlrec;
+	spgxlogAddLeaf xlrec = {0};
 
 	xlrec.newPage = isNew;
 	xlrec.storesNulls = isNulls;
@@ -399,7 +399,7 @@ moveLeafs(Relation index, SpGistState *state,
 	OffsetNumber *toDelete;
 	OffsetNumber *toInsert;
 	BlockNumber nblkno;
-	spgxlogMoveLeafs xlrec;
+	spgxlogMoveLeafs xlrec = {0};
 	char	   *leafdata,
 			   *leafptr;
 
@@ -702,7 +702,7 @@ doPickSplit(Relation index, SpGistState *state,
 	int			currentFreeSpace;
 	int			totalLeafSizes;
 	bool		allTheSame;
-	spgxlogPickSplit xlrec;
+	spgxlogPickSplit xlrec = {0};
 	char	   *leafdata,
 			   *leafptr;
 	SPPageDesc	saveCurrent;
@@ -1512,7 +1512,7 @@ spgAddNodeAction(Relation index, SpGistState *state,
 				 int nodeN, Datum nodeLabel)
 {
 	SpGistInnerTuple newInnerTuple;
-	spgxlogAddNode xlrec;
+	spgxlogAddNode xlrec = {0};
 
 	/* Should not be applied to nulls */
 	Assert(!SpGistPageStoresNulls(current->page));
@@ -1719,7 +1719,7 @@ spgSplitNodeAction(Relation index, SpGistState *state,
 	BlockNumber postfixBlkno;
 	OffsetNumber postfixOffset;
 	int			i;
-	spgxlogSplitTuple xlrec;
+	spgxlogSplitTuple xlrec = {0};
 	Buffer		newBuffer = InvalidBuffer;
 
 	/* Should not be applied to nulls */
diff --git a/src/backend/access/spgist/spgvacuum.c b/src/backend/access/spgist/spgvacuum.c
index 6b7117b56b2..77947723d04 100644
--- a/src/backend/access/spgist/spgvacuum.c
+++ b/src/backend/access/spgist/spgvacuum.c
@@ -127,7 +127,7 @@ vacuumLeafPage(spgBulkDeleteState *bds, Relation index, Buffer buffer,
 			   bool forPending)
 {
 	Page		page = BufferGetPage(buffer);
-	spgxlogVacuumLeaf xlrec;
+	spgxlogVacuumLeaf xlrec = {0};
 	OffsetNumber toDead[MaxIndexTuplesPerPage];
 	OffsetNumber toPlaceholder[MaxIndexTuplesPerPage];
 	OffsetNumber moveSrc[MaxIndexTuplesPerPage];
@@ -409,7 +409,7 @@ static void
 vacuumLeafRoot(spgBulkDeleteState *bds, Relation index, Buffer buffer)
 {
 	Page		page = BufferGetPage(buffer);
-	spgxlogVacuumRoot xlrec;
+	spgxlogVacuumRoot xlrec = {0};
 	OffsetNumber toDelete[MaxIndexTuplesPerPage];
 	OffsetNumber i,
 				max = PageGetMaxOffsetNumber(page);
@@ -502,7 +502,7 @@ vacuumRedirectAndPlaceholder(Relation index, Relation heaprel, Buffer buffer)
 	bool		hasUpdate = false;
 	OffsetNumber itemToPlaceholder[MaxIndexTuplesPerPage];
 	OffsetNumber itemnos[MaxIndexTuplesPerPage];
-	spgxlogVacuumRedirect xlrec;
+	spgxlogVacuumRedirect xlrec = {0};
 	GlobalVisState *vistest;
 
 	xlrec.isCatalogRel = RelationIsAccessibleInLogicalDecoding(heaprel);
diff --git a/src/backend/access/spgist/spgxlog.c b/src/backend/access/spgist/spgxlog.c
index 55e8066a77b..b2d258f6c28 100644
--- a/src/backend/access/spgist/spgxlog.c
+++ b/src/backend/access/spgist/spgxlog.c
@@ -77,7 +77,7 @@ spgRedoAddLeaf(XLogReaderState *record)
 	char	   *ptr = XLogRecGetData(record);
 	spgxlogAddLeaf *xldata = (spgxlogAddLeaf *) ptr;
 	char	   *leafTuple;
-	SpGistLeafTupleData leafTupleHdr;
+	SpGistLeafTupleData leafTupleHdr = {0};
 	Buffer		buffer;
 	Page		page;
 	XLogRedoAction action;
@@ -221,7 +221,7 @@ spgRedoMoveLeafs(XLogReaderState *record)
 		for (i = 0; i < nInsert; i++)
 		{
 			char	   *leafTuple;
-			SpGistLeafTupleData leafTupleHdr;
+			SpGistLeafTupleData leafTupleHdr = {0};
 
 			/*
 			 * the tuples are not aligned, so must copy to access the size
@@ -285,7 +285,7 @@ spgRedoAddNode(XLogReaderState *record)
 	char	   *ptr = XLogRecGetData(record);
 	spgxlogAddNode *xldata = (spgxlogAddNode *) ptr;
 	char	   *innerTuple;
-	SpGistInnerTupleData innerTupleHdr;
+	SpGistInnerTupleData innerTupleHdr = {0};
 	SpGistState state;
 	Buffer		buffer;
 	Page		page;
@@ -451,9 +451,9 @@ spgRedoSplitTuple(XLogReaderState *record)
 	char	   *ptr = XLogRecGetData(record);
 	spgxlogSplitTuple *xldata = (spgxlogSplitTuple *) ptr;
 	char	   *prefixTuple;
-	SpGistInnerTupleData prefixTupleHdr;
+	SpGistInnerTupleData prefixTupleHdr = {0};
 	char	   *postfixTuple;
-	SpGistInnerTupleData postfixTupleHdr;
+	SpGistInnerTupleData postfixTupleHdr = {0};
 	Buffer		buffer;
 	Page		page;
 	XLogRedoAction action;
@@ -526,7 +526,7 @@ spgRedoPickSplit(XLogReaderState *record)
 	char	   *ptr = XLogRecGetData(record);
 	spgxlogPickSplit *xldata = (spgxlogPickSplit *) ptr;
 	char	   *innerTuple;
-	SpGistInnerTupleData innerTupleHdr;
+	SpGistInnerTupleData innerTupleHdr = {0};
 	SpGistState state;
 	OffsetNumber *toDelete;
 	OffsetNumber *toInsert;
@@ -645,7 +645,7 @@ spgRedoPickSplit(XLogReaderState *record)
 	for (i = 0; i < xldata->nInsert; i++)
 	{
 		char	   *leafTuple;
-		SpGistLeafTupleData leafTupleHdr;
+		SpGistLeafTupleData leafTupleHdr = {0};
 
 		/* the tuples are not aligned, so must copy to access the size field. */
 		leafTuple = ptr;
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index b5c38bbb162..d62d22ef444 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -1044,7 +1044,7 @@ static void
 WriteTruncateXlogRec(int64 pageno, TransactionId oldestXact, Oid oldestXactDb)
 {
 	XLogRecPtr	recptr;
-	xl_clog_truncate xlrec;
+	xl_clog_truncate xlrec = {0};
 
 	xlrec.pageno = pageno;
 	xlrec.oldestXact = oldestXact;
@@ -1076,7 +1076,7 @@ clog_redo(XLogReaderState *record)
 	}
 	else if (info == CLOG_TRUNCATE)
 	{
-		xl_clog_truncate xlrec;
+		xl_clog_truncate xlrec = {0};
 
 		memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_clog_truncate));
 
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 6fa2178f1dd..55349042ed7 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -966,7 +966,7 @@ CommitTsPagePrecedes(int64 page1, int64 page2)
 static void
 WriteTruncateXlogRec(int64 pageno, TransactionId oldestXid)
 {
-	xl_commit_ts_truncate xlrec;
+	xl_commit_ts_truncate xlrec = {0};
 
 	xlrec.pageno = pageno;
 	xlrec.oldestXid = oldestXid;
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 90ec87d9dd6..a005bbed209 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -657,7 +657,7 @@ MultiXactIdCreateFromMembers(int nmembers, MultiXactMember *members)
 {
 	MultiXactId multi;
 	MultiXactOffset offset;
-	xl_multixact_create xlrec;
+	xl_multixact_create xlrec = {0};
 
 	debug_elog3(DEBUG2, "Create: %s",
 				mxid_to_string(InvalidMultiXactId, nmembers, members));
@@ -728,7 +728,7 @@ MultiXactIdCreateFromMembers(int nmembers, MultiXactMember *members)
 	 */
 	XLogBeginInsert();
 	XLogRegisterData(&xlrec, SizeOfMultiXactCreate);
-	XLogRegisterData(members, nmembers * sizeof(MultiXactMember));
+	XLogRegisterData((char *) members, nmembers * sizeof(MultiXactMember));
 
 	(void) XLogInsert(RM_MULTIXACT_ID, XLOG_MULTIXACT_CREATE_ID);
 
@@ -2796,7 +2796,7 @@ WriteMTruncateXlogRec(Oid oldestMultiDB,
 					  MultiXactOffset oldestOffset)
 {
 	XLogRecPtr	recptr;
-	xl_multixact_truncate xlrec;
+	xl_multixact_truncate xlrec = {0};
 
 	xlrec.oldestMultiDB = oldestMultiDB;
 	xlrec.oldestMulti = oldestMulti;
@@ -2864,7 +2864,7 @@ multixact_redo(XLogReaderState *record)
 	}
 	else if (info == XLOG_MULTIXACT_TRUNCATE_ID)
 	{
-		xl_multixact_truncate xlrec;
+		xl_multixact_truncate xlrec = {0};
 		int64		pageno;
 
 		memcpy(&xlrec, XLogRecGetData(record),
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index eba4f063168..df72a2566e6 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -761,7 +761,7 @@ AssignTransactionId(TransactionState s)
 		if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS ||
 			log_unknown_top)
 		{
-			xl_xact_assignment xlrec;
+			xl_xact_assignment xlrec = {0};
 
 			/*
 			 * xtop is always set by now because we recurse up transaction
@@ -5842,15 +5842,15 @@ XactLogCommitRecord(TimestampTz commit_time,
 					int xactflags, TransactionId twophase_xid,
 					const char *twophase_gid)
 {
-	xl_xact_commit xlrec;
-	xl_xact_xinfo xl_xinfo;
-	xl_xact_dbinfo xl_dbinfo;
-	xl_xact_subxacts xl_subxacts;
-	xl_xact_relfilelocators xl_relfilelocators;
-	xl_xact_stats_items xl_dropped_stats;
-	xl_xact_invals xl_invals;
-	xl_xact_twophase xl_twophase;
-	xl_xact_origin xl_origin;
+	xl_xact_commit xlrec = {0};
+	xl_xact_xinfo xl_xinfo = {0};
+	xl_xact_dbinfo xl_dbinfo = {0};
+	xl_xact_subxacts xl_subxacts = {0};
+	xl_xact_relfilelocators xl_relfilelocators = {0};
+	xl_xact_stats_items xl_dropped_stats = {0};
+	xl_xact_invals xl_invals = {0};
+	xl_xact_twophase xl_twophase = {0};
+	xl_xact_origin xl_origin = {0};
 	uint8		info;
 
 	Assert(CritSectionCount > 0);
@@ -5963,7 +5963,7 @@ XactLogCommitRecord(TimestampTz commit_time,
 	{
 		XLogRegisterData(&xl_relfilelocators,
 						 MinSizeOfXactRelfileLocators);
-		XLogRegisterData(rels,
+		XLogRegisterData((char *) rels,
 						 nrels * sizeof(RelFileLocator));
 	}
 
@@ -5971,14 +5971,14 @@ XactLogCommitRecord(TimestampTz commit_time,
 	{
 		XLogRegisterData(&xl_dropped_stats,
 						 MinSizeOfXactStatsItems);
-		XLogRegisterData(droppedstats,
+		XLogRegisterData((char *) droppedstats,
 						 ndroppedstats * sizeof(xl_xact_stats_item));
 	}
 
 	if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
 	{
 		XLogRegisterData(&xl_invals, MinSizeOfXactInvals);
-		XLogRegisterData(msgs,
+		XLogRegisterData((char *) msgs,
 						 nmsgs * sizeof(SharedInvalidationMessage));
 	}
 
@@ -6012,14 +6012,14 @@ XactLogAbortRecord(TimestampTz abort_time,
 				   int xactflags, TransactionId twophase_xid,
 				   const char *twophase_gid)
 {
-	xl_xact_abort xlrec;
-	xl_xact_xinfo xl_xinfo;
-	xl_xact_subxacts xl_subxacts;
-	xl_xact_relfilelocators xl_relfilelocators;
-	xl_xact_stats_items xl_dropped_stats;
-	xl_xact_twophase xl_twophase;
-	xl_xact_dbinfo xl_dbinfo;
-	xl_xact_origin xl_origin;
+	xl_xact_abort xlrec = {0};
+	xl_xact_xinfo xl_xinfo = {0};
+	xl_xact_subxacts xl_subxacts = {0};
+	xl_xact_relfilelocators xl_relfilelocators = {0};
+	xl_xact_stats_items xl_dropped_stats = {0};
+	xl_xact_twophase xl_twophase = {0};
+	xl_xact_dbinfo xl_dbinfo = {0};
+	xl_xact_origin xl_origin = {0};
 
 	uint8		info;
 
@@ -6116,7 +6116,7 @@ XactLogAbortRecord(TimestampTz abort_time,
 	{
 		XLogRegisterData(&xl_relfilelocators,
 						 MinSizeOfXactRelfileLocators);
-		XLogRegisterData(rels,
+		XLogRegisterData((char *) rels,
 						 nrels * sizeof(RelFileLocator));
 	}
 
@@ -6124,7 +6124,7 @@ XactLogAbortRecord(TimestampTz abort_time,
 	{
 		XLogRegisterData(&xl_dropped_stats,
 						 MinSizeOfXactStatsItems);
-		XLogRegisterData(droppedstats,
+		XLogRegisterData((char *) droppedstats,
 						 ndroppedstats * sizeof(xl_xact_stats_item));
 	}
 
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 13cce9b49f1..45832a59e1d 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -5125,7 +5125,7 @@ XLOGShmemInit(void)
 void
 BootStrapXLOG(uint32 data_checksum_version)
 {
-	CheckPoint	checkPoint;
+	CheckPoint	checkPoint = {0};
 	PGAlignedXLogBlock buffer;
 	XLogPageHeader page;
 	XLogLongPageHeader longpage;
@@ -5207,6 +5207,7 @@ BootStrapXLOG(uint32 data_checksum_version)
 	/* Insert the initial checkpoint record */
 	recptr = ((char *) page + SizeOfXLogLongPHD);
 	record = (XLogRecord *) recptr;
+	memset(record, 0, SizeOfXLogRecord);
 	record->xl_prev = InvalidXLogRecPtr;
 	record->xl_xid = InvalidTransactionId;
 	record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
@@ -5517,7 +5518,7 @@ void
 StartupXLOG(void)
 {
 	XLogCtlInsert *Insert;
-	CheckPoint	checkPoint;
+	CheckPoint	checkPoint = {0};
 	bool		wasShutdown;
 	bool		didCrash;
 	bool		haveTblspcMap;
@@ -7025,7 +7026,7 @@ bool
 CreateCheckPoint(int flags)
 {
 	bool		shutdown;
-	CheckPoint	checkPoint;
+	CheckPoint	checkPoint = {0};
 	XLogRecPtr	recptr;
 	XLogSegNo	_logSegNo;
 	XLogCtlInsert *Insert = &XLogCtl->Insert;
@@ -7515,7 +7516,7 @@ CreateCheckPoint(int flags)
 static void
 CreateEndOfRecoveryRecord(void)
 {
-	xl_end_of_recovery xlrec;
+	xl_end_of_recovery xlrec = {0};
 	XLogRecPtr	recptr;
 
 	/* sanity check */
@@ -7581,7 +7582,7 @@ static XLogRecPtr
 CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn, XLogRecPtr pagePtr,
 								TimeLineID newTLI)
 {
-	xl_overwrite_contrecord xlrec;
+	xl_overwrite_contrecord xlrec = {0};
 	XLogRecPtr	recptr;
 	XLogPageHeader pagehdr;
 	XLogRecPtr	startPos;
@@ -7732,7 +7733,7 @@ CreateRestartPoint(int flags)
 {
 	XLogRecPtr	lastCheckPointRecPtr;
 	XLogRecPtr	lastCheckPointEndPtr;
-	CheckPoint	lastCheckPoint;
+	CheckPoint	lastCheckPoint = {0};
 	XLogRecPtr	PriorRedoPtr;
 	XLogRecPtr	receivePtr;
 	XLogRecPtr	replayPtr;
@@ -8223,7 +8224,7 @@ XLogRecPtr
 XLogRestorePoint(const char *rpName)
 {
 	XLogRecPtr	RecPtr;
-	xl_restore_point xlrec;
+	xl_restore_point xlrec = {0};
 
 	xlrec.rp_time = GetCurrentTimestamp();
 	strlcpy(xlrec.rp_name, rpName, MAXFNAMELEN);
@@ -8265,7 +8266,7 @@ XLogReportParameters(void)
 		 */
 		if (wal_level != ControlFile->wal_level || XLogIsNeeded())
 		{
-			xl_parameter_change xlrec;
+			xl_parameter_change xlrec = {0};
 			XLogRecPtr	recptr;
 
 			xlrec.MaxConnections = MaxConnections;
@@ -8408,7 +8409,7 @@ xlog_redo(XLogReaderState *record)
 	}
 	else if (info == XLOG_CHECKPOINT_SHUTDOWN)
 	{
-		CheckPoint	checkPoint;
+		CheckPoint	checkPoint = {0};
 		TimeLineID	replayTLI;
 
 		memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
@@ -8509,7 +8510,7 @@ xlog_redo(XLogReaderState *record)
 	}
 	else if (info == XLOG_CHECKPOINT_ONLINE)
 	{
-		CheckPoint	checkPoint;
+		CheckPoint	checkPoint = {0};
 		TimeLineID	replayTLI;
 
 		memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
@@ -8574,7 +8575,7 @@ xlog_redo(XLogReaderState *record)
 	}
 	else if (info == XLOG_END_OF_RECOVERY)
 	{
-		xl_end_of_recovery xlrec;
+		xl_end_of_recovery xlrec = {0};
 		TimeLineID	replayTLI;
 
 		memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_end_of_recovery));
@@ -8647,7 +8648,7 @@ xlog_redo(XLogReaderState *record)
 	}
 	else if (info == XLOG_PARAMETER_CHANGE)
 	{
-		xl_parameter_change xlrec;
+		xl_parameter_change xlrec = {0};
 
 		/* Update our copy of the parameters in pg_control */
 		memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_parameter_change));
diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index a9a1678acc9..d1b6fbea81c 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -584,6 +584,7 @@ XLogRecordAssemble(RmgrId rmid, uint8 info,
 
 	/* The record begins with the fixed-size header */
 	rechdr = (XLogRecord *) scratch;
+	memset(rechdr, 0, SizeOfXLogRecord);
 	scratch += SizeOfXLogRecord;
 
 	hdr_rdt.next = NULL;
@@ -610,8 +611,8 @@ XLogRecordAssemble(RmgrId rmid, uint8 info,
 		registered_buffer *regbuf = &registered_buffers[block_id];
 		bool		needs_backup;
 		bool		needs_data;
-		XLogRecordBlockHeader bkpb;
-		XLogRecordBlockImageHeader bimg;
+		XLogRecordBlockHeader bkpb = {0};
+		XLogRecordBlockImageHeader bimg = {0};
 		XLogRecordBlockCompressHeader cbimg = {0};
 		bool		samerel;
 		bool		is_compressed = false;
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index 03ada8aa0c5..6c743f8c98d 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -1806,9 +1806,12 @@ DecodeXLogRecord(XLogReaderState *state,
 
 			if (blk->has_image)
 			{
+				uint8		bimg_pad;
+
 				COPY_HEADER_FIELD(&blk->bimg_len, sizeof(uint16));
 				COPY_HEADER_FIELD(&blk->hole_offset, sizeof(uint16));
 				COPY_HEADER_FIELD(&blk->bimg_info, sizeof(uint8));
+				COPY_HEADER_FIELD(&bimg_pad, sizeof(uint8));
 
 				blk->apply_image = ((blk->bimg_info & BKPIMAGE_APPLY) != 0);
 
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index ecd66fd86a4..75bd50ec278 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -526,7 +526,7 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
 	DBState		dbstate_at_startup;
 	bool		haveTblspcMap = false;
 	bool		haveBackupLabel = false;
-	CheckPoint	checkPoint;
+	CheckPoint	checkPoint = {0};
 	bool		backupFromStandby = false;
 
 	dbstate_at_startup = ControlFile->state;
@@ -1971,7 +1971,7 @@ ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *repl
 
 		if (info == XLOG_CHECKPOINT_SHUTDOWN)
 		{
-			CheckPoint	checkPoint;
+			CheckPoint	checkPoint = {0};
 
 			memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
 			newReplayTLI = checkPoint.ThisTimeLineID;
@@ -1979,7 +1979,7 @@ ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *repl
 		}
 		else if (info == XLOG_END_OF_RECOVERY)
 		{
-			xl_end_of_recovery xlrec;
+			xl_end_of_recovery xlrec = {0};
 
 			memcpy(&xlrec, XLogRecGetData(xlogreader), sizeof(xl_end_of_recovery));
 			newReplayTLI = xlrec.ThisTimeLineID;
@@ -2113,7 +2113,7 @@ xlogrecovery_redo(XLogReaderState *record, TimeLineID replayTLI)
 	if (info == XLOG_OVERWRITE_CONTRECORD)
 	{
 		/* Verify the payload of a XLOG_OVERWRITE_CONTRECORD record. */
-		xl_overwrite_contrecord xlrec;
+		xl_overwrite_contrecord xlrec = {0};
 
 		memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_overwrite_contrecord));
 		if (xlrec.overwritten_lsn != record->overwrittenRecPtr)
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index e443a4993c5..f82fce1f929 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -186,7 +186,7 @@ RelationCreateStorage(RelFileLocator rlocator, char relpersistence,
 void
 log_smgrcreate(const RelFileLocator *rlocator, ForkNumber forkNum)
 {
-	xl_smgr_create xlrec;
+	xl_smgr_create xlrec = {0};
 
 	/*
 	 * Make an XLOG entry reporting the file creation.
@@ -391,7 +391,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
 		 * Make an XLOG entry reporting the file truncation.
 		 */
 		XLogRecPtr	lsn;
-		xl_smgr_truncate xlrec;
+		xl_smgr_truncate xlrec = {0};
 
 		xlrec.blkno = nblocks;
 		xlrec.rlocator = rel->rd_locator;
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 740c526e92d..42f3fd1c931 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -524,7 +524,7 @@ CreateDirAndVersionFile(char *dbpath, Oid dbid, Oid tsid, bool isRedo)
 	/* If we are not in WAL replay then write the WAL. */
 	if (!isRedo)
 	{
-		xl_dbase_create_wal_log_rec xlrec;
+		xl_dbase_create_wal_log_rec xlrec = {0};
 
 		START_CRIT_SECTION();
 
@@ -620,7 +620,7 @@ CreateDatabaseUsingFileCopy(Oid src_dboid, Oid dst_dboid, Oid src_tsid,
 
 		/* Record the filesystem change in XLOG */
 		{
-			xl_dbase_create_file_copy_rec xlrec;
+			xl_dbase_create_file_copy_rec xlrec = {0};
 
 			xlrec.db_id = dst_dboid;
 			xlrec.tablespace_id = dsttablespace;
@@ -2215,7 +2215,7 @@ movedb(const char *dbname, const char *tblspcname)
 		 * Record the filesystem change in XLOG
 		 */
 		{
-			xl_dbase_create_file_copy_rec xlrec;
+			xl_dbase_create_file_copy_rec xlrec = {0};
 
 			xlrec.db_id = db_id;
 			xlrec.tablespace_id = dst_tblspcoid;
@@ -2313,7 +2313,7 @@ movedb(const char *dbname, const char *tblspcname)
 	 * Record the filesystem change in XLOG
 	 */
 	{
-		xl_dbase_drop_rec xlrec;
+		xl_dbase_drop_rec xlrec = {0};
 
 		xlrec.db_id = db_id;
 		xlrec.ntablespaces = 1;
@@ -3072,7 +3072,7 @@ remove_dbtablespaces(Oid db_id)
 
 	/* Record the filesystem change in XLOG */
 	{
-		xl_dbase_drop_rec xlrec;
+		xl_dbase_drop_rec xlrec = {0};
 
 		xlrec.db_id = db_id;
 		xlrec.ntablespaces = ntblspc;
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index e1b808bbb60..f59be766238 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -399,7 +399,7 @@ fill_seq_fork_with_data(Relation rel, HeapTuple tuple, ForkNumber forkNum)
 	/* XLOG stuff */
 	if (RelationNeedsWAL(rel) || forkNum == INIT_FORKNUM)
 	{
-		xl_seq_rec	xlrec;
+		xl_seq_rec	xlrec = {0};
 		XLogRecPtr	recptr;
 
 		XLogBeginInsert();
@@ -408,7 +408,7 @@ fill_seq_fork_with_data(Relation rel, HeapTuple tuple, ForkNumber forkNum)
 		xlrec.locator = rel->rd_locator;
 
 		XLogRegisterData(&xlrec, sizeof(xl_seq_rec));
-		XLogRegisterData(tuple->t_data, tuple->t_len);
+		XLogRegisterData((char *) tuple->t_data, tuple->t_len);
 
 		recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);
 
@@ -822,7 +822,7 @@ nextval_internal(Oid relid, bool check_permissions)
 	/* XLOG stuff */
 	if (logit && RelationNeedsWAL(seqrel))
 	{
-		xl_seq_rec	xlrec;
+		xl_seq_rec	xlrec = {0};
 		XLogRecPtr	recptr;
 
 		/*
@@ -842,7 +842,7 @@ nextval_internal(Oid relid, bool check_permissions)
 		xlrec.locator = seqrel->rd_locator;
 
 		XLogRegisterData(&xlrec, sizeof(xl_seq_rec));
-		XLogRegisterData(seqdatatuple.t_data, seqdatatuple.t_len);
+		XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len);
 
 		recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);
 
@@ -1019,7 +1019,7 @@ SetSequence(Oid relid, int64 next, bool iscalled)
 	/* XLOG stuff */
 	if (RelationNeedsWAL(seqrel))
 	{
-		xl_seq_rec	xlrec;
+		xl_seq_rec	xlrec = {0};
 		XLogRecPtr	recptr;
 		Page		page = BufferGetPage(buf);
 
@@ -1028,7 +1028,7 @@ SetSequence(Oid relid, int64 next, bool iscalled)
 
 		xlrec.locator = seqrel->rd_locator;
 		XLogRegisterData(&xlrec, sizeof(xl_seq_rec));
-		XLogRegisterData(seqdatatuple.t_data, seqdatatuple.t_len);
+		XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len);
 
 		recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);
 
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index b04b0dbd2a0..f04d647186c 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -2307,7 +2307,7 @@ ExecuteTruncateGuts(List *explicit_rels,
 	 */
 	if (relids_logged != NIL)
 	{
-		xl_heap_truncate xlrec;
+		xl_heap_truncate xlrec = {0};
 		int			i = 0;
 
 		/* should only get here if effective_wal_level is 'logical' */
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index ed2a93a09db..fca45c5137a 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -365,7 +365,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 
 	/* Record the filesystem change in XLOG */
 	{
-		xl_tblspc_create_rec xlrec;
+		xl_tblspc_create_rec xlrec = {0};
 
 		xlrec.ts_id = tablespaceoid;
 
@@ -535,7 +535,7 @@ DropTableSpace(DropTableSpaceStmt *stmt)
 
 	/* Record the filesystem change in XLOG */
 	{
-		xl_tblspc_drop_rec xlrec;
+		xl_tblspc_drop_rec xlrec = {0};
 
 		xlrec.ts_id = tablespaceoid;
 
diff --git a/src/backend/postmaster/walsummarizer.c b/src/backend/postmaster/walsummarizer.c
index 742137edad6..e0eb2bea0f1 100644
--- a/src/backend/postmaster/walsummarizer.c
+++ b/src/backend/postmaster/walsummarizer.c
@@ -1431,7 +1431,7 @@ SummarizeXlogRecord(XLogReaderState *xlogreader, bool *new_fast_forward)
 	}
 	else if (info == XLOG_CHECKPOINT_SHUTDOWN)
 	{
-		CheckPoint	rec_ckpt;
+		CheckPoint	rec_ckpt = {0};
 
 		/* Extract wal_level at time record was written from payload. */
 		memcpy(&rec_ckpt, XLogRecGetData(xlogreader), sizeof(CheckPoint));
@@ -1439,7 +1439,7 @@ SummarizeXlogRecord(XLogReaderState *xlogreader, bool *new_fast_forward)
 	}
 	else if (info == XLOG_PARAMETER_CHANGE)
 	{
-		xl_parameter_change xlrec;
+		xl_parameter_change xlrec = {0};
 
 		/* Extract wal_level at time record was written from payload. */
 		memcpy(&xlrec, XLogRecGetData(xlogreader),
@@ -1448,7 +1448,7 @@ SummarizeXlogRecord(XLogReaderState *xlogreader, bool *new_fast_forward)
 	}
 	else if (info == XLOG_END_OF_RECOVERY)
 	{
-		xl_end_of_recovery xlrec;
+		xl_end_of_recovery xlrec = {0};
 
 		/* Extract wal_level at time record was written from payload. */
 		memcpy(&xlrec, XLogRecGetData(xlogreader), sizeof(xl_end_of_recovery));
diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c
index 21f03864a66..867cf9d0158 100644
--- a/src/backend/replication/logical/decode.c
+++ b/src/backend/replication/logical/decode.c
@@ -1245,7 +1245,7 @@ DecodeSpecConfirm(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 static void
 DecodeXLogTuple(char *data, Size len, HeapTuple tuple)
 {
-	xl_heap_header xlhdr;
+	xl_heap_header xlhdr = {0};
 	int			datalen = len - SizeOfHeapHeader;
 	HeapTupleHeader header;
 
diff --git a/src/backend/replication/logical/message.c b/src/backend/replication/logical/message.c
index 06825d66e7f..5a165c591cb 100644
--- a/src/backend/replication/logical/message.c
+++ b/src/backend/replication/logical/message.c
@@ -43,7 +43,7 @@ XLogRecPtr
 LogLogicalMessage(const char *prefix, const char *message, size_t size,
 				  bool transactional, bool flush)
 {
-	xl_logical_message xlrec;
+	xl_logical_message xlrec = {0};
 	XLogRecPtr	lsn;
 
 	/*
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index c3271a6fd0e..3a3dee4c411 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -419,7 +419,7 @@ restart:
 
 			/* first make a WAL log entry */
 			{
-				xl_replorigin_drop xlrec;
+				xl_replorigin_drop xlrec = {0};
 
 				xlrec.node_id = roident;
 				XLogBeginInsert();
@@ -1008,7 +1008,7 @@ replorigin_advance(ReplOriginId node,
 	 */
 	if (wal_log)
 	{
-		xl_replorigin_set xlrec;
+		xl_replorigin_set xlrec = {0};
 
 		xlrec.remote_lsn = remote_commit;
 		xlrec.node_id = node;
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index d83afbfb9d6..6b950fbab86 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -987,7 +987,7 @@ StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid)
 {
 	RecoveryLockXidEntry *xidentry;
 	RecoveryLockEntry *lockentry;
-	xl_standby_lock key;
+	xl_standby_lock key = {0};
 	LOCKTAG		locktag;
 	bool		found;
 
@@ -1353,7 +1353,7 @@ LogStandbySnapshot(void)
 static XLogRecPtr
 LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
 {
-	xl_running_xacts xlrec;
+	xl_running_xacts xlrec = {0};
 	XLogRecPtr	recptr;
 
 	xlrec.xcnt = CurrRunningXacts->xcnt;
@@ -1413,7 +1413,7 @@ LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
 static void
 LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
 {
-	xl_standby_locks xlrec;
+	xl_standby_locks xlrec = {0};
 
 	xlrec.nlocks = nlocks;
 
@@ -1431,7 +1431,7 @@ LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
 void
 LogAccessExclusiveLock(Oid dbOid, Oid relOid)
 {
-	xl_standby_lock xlrec;
+	xl_standby_lock xlrec = {0};
 
 	xlrec.xid = GetCurrentTransactionId();
 
@@ -1471,10 +1471,8 @@ void
 LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs,
 						bool relcacheInitFileInval)
 {
-	xl_invalidations xlrec;
+	xl_invalidations xlrec = {0};
 
-	/* prepare record */
-	memset(&xlrec, 0, sizeof(xlrec));
 	xlrec.dbId = MyDatabaseId;
 	xlrec.tsId = MyDatabaseTableSpace;
 	xlrec.relcacheInitFileInval = relcacheInitFileInval;
@@ -1483,7 +1481,7 @@ LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs,
 	/* perform insertion */
 	XLogBeginInsert();
 	XLogRegisterData(&xlrec, MinSizeOfInvalidations);
-	XLogRegisterData(msgs,
+	XLogRegisterData((char *) msgs,
 					 nmsgs * sizeof(SharedInvalidationMessage));
 	XLogInsert(RM_STANDBY_ID, XLOG_INVALIDATIONS);
 }
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index d59216b28f1..389b493e21b 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -1938,7 +1938,7 @@ CallRelSyncCallbacks(Oid relid)
 void
 LogLogicalInvalidations(void)
 {
-	xl_xact_invals xlrec;
+	xl_xact_invals xlrec = {0};
 	InvalidationMsgsGroup *group;
 	int			nmsgs;
 
@@ -1959,10 +1959,10 @@ LogLogicalInvalidations(void)
 		XLogBeginInsert();
 		XLogRegisterData(&xlrec, MinSizeOfXactInvals);
 		ProcessMessageSubGroupMulti(group, CatCacheMsgs,
-									XLogRegisterData(msgs,
+									XLogRegisterData((char *) msgs,
 													 n * sizeof(SharedInvalidationMessage)));
 		ProcessMessageSubGroupMulti(group, RelCacheMsgs,
-									XLogRegisterData(msgs,
+									XLogRegisterData((char *) msgs,
 													 n * sizeof(SharedInvalidationMessage)));
 		XLogInsert(RM_XACT_ID, XLOG_XACT_INVALIDATIONS);
 	}
diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c
index 778b14a2318..896c153bf87 100644
--- a/src/backend/utils/cache/relmapper.c
+++ b/src/backend/utils/cache/relmapper.c
@@ -86,7 +86,7 @@ typedef struct RelMapping
 	RelFileNumber mapfilenumber;	/* its rel file number */
 } RelMapping;
 
-typedef struct RelMapFile
+typedef struct PG_NO_PADDING RelMapFile
 {
 	int32		magic;			/* always RELMAPPER_FILEMAGIC */
 	int32		num_mappings;	/* number of valid RelMapping entries */
@@ -264,7 +264,7 @@ RelationMapFilenumberToOid(RelFileNumber filenumber, bool shared)
 RelFileNumber
 RelationMapOidToFilenumberForDatabase(char *dbpath, Oid relationId)
 {
-	RelMapFile	map;
+	RelMapFile	map = {0};
 	int			i;
 
 	/* Read the relmap file from the source database. */
@@ -291,7 +291,7 @@ RelationMapOidToFilenumberForDatabase(char *dbpath, Oid relationId)
 void
 RelationMapCopy(Oid dbid, Oid tsid, char *srcdbpath, char *dstdbpath)
 {
-	RelMapFile	map;
+	RelMapFile	map = {0};
 
 	/*
 	 * Read the relmap file from the source database.
@@ -958,7 +958,7 @@ write_relmap_file(RelMapFile *newmap, bool write_wal, bool send_sinval,
 
 	if (write_wal)
 	{
-		xl_relmap_update xlrec;
+		xl_relmap_update xlrec = {0};
 		XLogRecPtr	lsn;
 
 		/* now errors are fatal ... */
@@ -1038,7 +1038,7 @@ write_relmap_file(RelMapFile *newmap, bool write_wal, bool send_sinval,
 static void
 perform_relmap_update(bool shared, const RelMapFile *updates)
 {
-	RelMapFile	newmap;
+	RelMapFile	newmap = {0};
 
 	/*
 	 * Anyone updating a relation's mapping info should take exclusive lock on
@@ -1103,7 +1103,7 @@ relmap_redo(XLogReaderState *record)
 	if (info == XLOG_RELMAP_UPDATE)
 	{
 		xl_relmap_update *xlrec = (xl_relmap_update *) XLogRecGetData(record);
-		RelMapFile	newmap;
+		RelMapFile	newmap = {0};
 		char	   *dbpath;
 
 		if (xlrec->nbytes != sizeof(RelMapFile))
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index ab766c34d4b..04a7168240a 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -1152,6 +1152,7 @@ WriteEmptyXLOG(void)
 	/* Insert the initial checkpoint record */
 	recptr = (char *) page + SizeOfXLogLongPHD;
 	record = (XLogRecord *) recptr;
+	memset(record, 0, SizeOfXLogRecord);
 	record->xl_prev = InvalidXLogRecPtr;
 	record->xl_xid = InvalidTransactionId;
 	record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(CheckPoint);
diff --git a/src/include/access/brin_xlog.h b/src/include/access/brin_xlog.h
index 1c60dc8adb9..b22137970d3 100644
--- a/src/include/access/brin_xlog.h
+++ b/src/include/access/brin_xlog.h
@@ -47,12 +47,13 @@
  *
  * Backup block 0: metapage
  */
-typedef struct xl_brin_createidx
+typedef struct PG_NO_PADDING xl_brin_createidx
 {
 	BlockNumber pagesPerRange;
 	uint16		version;
+	pg_padding_2(pg_pad);
 } xl_brin_createidx;
-#define SizeOfBrinCreateIdx (offsetof(xl_brin_createidx, version) + sizeof(uint16))
+#define SizeOfBrinCreateIdx (sizeof(xl_brin_createidx))
 
 /*
  * This is what we need to know about a BRIN tuple insert
@@ -60,7 +61,7 @@ typedef struct xl_brin_createidx
  * Backup block 0: main page, block data is the new BrinTuple.
  * Backup block 1: revmap page
  */
-typedef struct xl_brin_insert
+typedef struct PG_NO_PADDING xl_brin_insert
 {
 	BlockNumber heapBlk;
 
@@ -69,9 +70,10 @@ typedef struct xl_brin_insert
 
 	/* offset number in the main page to insert the tuple to. */
 	OffsetNumber offnum;
+	pg_padding_2(pg_pad);
 } xl_brin_insert;
 
-#define SizeOfBrinInsert	(offsetof(xl_brin_insert, offnum) + sizeof(OffsetNumber))
+#define SizeOfBrinInsert	(sizeof(xl_brin_insert))
 
 /*
  * A cross-page update is the same as an insert, but also stores information
@@ -84,27 +86,28 @@ typedef struct xl_brin_insert
  * And in addition:
  * Backup block 2: old page
  */
-typedef struct xl_brin_update
+typedef struct PG_NO_PADDING xl_brin_update
 {
 	/* offset number of old tuple on old page */
 	OffsetNumber oldOffnum;
+	pg_padding_2(pg_pad);
 
 	xl_brin_insert insert;
 } xl_brin_update;
 
-#define SizeOfBrinUpdate	(offsetof(xl_brin_update, insert) + SizeOfBrinInsert)
+#define SizeOfBrinUpdate	(sizeof(xl_brin_update))
 
 /*
  * This is what we need to know about a BRIN tuple samepage update
  *
  * Backup block 0: updated page, with new BrinTuple as block data
  */
-typedef struct xl_brin_samepage_update
+typedef struct PG_NO_PADDING xl_brin_samepage_update
 {
 	OffsetNumber offnum;
 } xl_brin_samepage_update;
 
-#define SizeOfBrinSamepageUpdate		(sizeof(OffsetNumber))
+#define SizeOfBrinSamepageUpdate	(sizeof(xl_brin_samepage_update))
 
 /*
  * This is what we need to know about a revmap extension
@@ -112,7 +115,7 @@ typedef struct xl_brin_samepage_update
  * Backup block 0: metapage
  * Backup block 1: new revmap page
  */
-typedef struct xl_brin_revmap_extend
+typedef struct PG_NO_PADDING xl_brin_revmap_extend
 {
 	/*
 	 * XXX: This is actually redundant - the block number is stored as part of
@@ -121,8 +124,7 @@ typedef struct xl_brin_revmap_extend
 	BlockNumber targetBlk;
 } xl_brin_revmap_extend;
 
-#define SizeOfBrinRevmapExtend	(offsetof(xl_brin_revmap_extend, targetBlk) + \
-								 sizeof(BlockNumber))
+#define SizeOfBrinRevmapExtend	(sizeof(xl_brin_revmap_extend))
 
 /*
  * This is what we need to know about a range de-summarization
@@ -130,17 +132,17 @@ typedef struct xl_brin_revmap_extend
  * Backup block 0: revmap page
  * Backup block 1: regular page
  */
-typedef struct xl_brin_desummarize
+typedef struct PG_NO_PADDING xl_brin_desummarize
 {
 	BlockNumber pagesPerRange;
 	/* page number location to set to invalid */
 	BlockNumber heapBlk;
 	/* offset of item to delete in regular index page */
 	OffsetNumber regOffset;
+	pg_padding_2(pg_pad);
 } xl_brin_desummarize;
 
-#define SizeOfBrinDesummarize	(offsetof(xl_brin_desummarize, regOffset) + \
-								 sizeof(OffsetNumber))
+#define SizeOfBrinDesummarize	(sizeof(xl_brin_desummarize))
 
 
 extern void brin_redo(XLogReaderState *record);
diff --git a/src/include/access/clog.h b/src/include/access/clog.h
index a1cfed5f43c..ee949ca108c 100644
--- a/src/include/access/clog.h
+++ b/src/include/access/clog.h
@@ -29,7 +29,7 @@ typedef int XidStatus;
 #define TRANSACTION_STATUS_ABORTED			0x02
 #define TRANSACTION_STATUS_SUB_COMMITTED	0x03
 
-typedef struct xl_clog_truncate
+typedef struct PG_NO_PADDING xl_clog_truncate
 {
 	int64		pageno;
 	TransactionId oldestXact;
diff --git a/src/include/access/commit_ts.h b/src/include/access/commit_ts.h
index 49ee21cd5d2..92e50b0c806 100644
--- a/src/include/access/commit_ts.h
+++ b/src/include/access/commit_ts.h
@@ -46,14 +46,14 @@ extern int	committssyncfiletag(const FileTag *ftag, char *path);
 #define COMMIT_TS_ZEROPAGE		0x00
 #define COMMIT_TS_TRUNCATE		0x10
 
-typedef struct xl_commit_ts_truncate
+typedef struct PG_NO_PADDING xl_commit_ts_truncate
 {
 	int64		pageno;
 	TransactionId oldestXid;
+	pg_padding_4(pg_pad);
 } xl_commit_ts_truncate;
 
-#define SizeOfCommitTsTruncate	(offsetof(xl_commit_ts_truncate, oldestXid) + \
-								 sizeof(TransactionId))
+#define SizeOfCommitTsTruncate	(sizeof(xl_commit_ts_truncate))
 
 extern void commit_ts_redo(XLogReaderState *record);
 extern void commit_ts_desc(StringInfo buf, XLogReaderState *record);
diff --git a/src/include/access/ginblock.h b/src/include/access/ginblock.h
index 2d75023179a..903c518df39 100644
--- a/src/include/access/ginblock.h
+++ b/src/include/access/ginblock.h
@@ -52,7 +52,7 @@ typedef GinPageOpaqueData *GinPageOpaque;
 #define GIN_METAPAGE_BLKNO	(0)
 #define GIN_ROOT_BLKNO		(1)
 
-typedef struct GinMetaPageData
+typedef struct PG_NO_PADDING GinMetaPageData
 {
 	/*
 	 * Pointers to head and tail of pending list, which consists of GIN_LIST
@@ -80,6 +80,7 @@ typedef struct GinMetaPageData
 	BlockNumber nTotalPages;
 	BlockNumber nEntryPages;
 	BlockNumber nDataPages;
+	pg_padding_4(pg_pad1);
 	int64		nEntries;
 
 	/*
@@ -98,6 +99,7 @@ typedef struct GinMetaPageData
 	 * Reject full-index-scan attempts on such indexes.
 	 */
 	int32		ginVersion;
+	pg_padding_4(pg_pad2);
 } GinMetaPageData;
 
 #define GIN_CURRENT_VERSION		2
@@ -333,7 +335,7 @@ typedef signed char GinNullCategory;
  *
  * Note: This requires 2-byte alignment.
  */
-typedef struct
+typedef struct PG_NO_PADDING
 {
 	ItemPointerData first;		/* first item in this posting list (unpacked) */
 	uint16		nbytes;			/* number of bytes that follow */
diff --git a/src/include/access/ginxlog.h b/src/include/access/ginxlog.h
index 74fdf9b3d7e..7df3b38737c 100644
--- a/src/include/access/ginxlog.h
+++ b/src/include/access/ginxlog.h
@@ -18,7 +18,7 @@
 
 #define XLOG_GIN_CREATE_PTREE  0x10
 
-typedef struct ginxlogCreatePostingTree
+typedef struct PG_NO_PADDING ginxlogCreatePostingTree
 {
 	uint32		size;
 	/* A compressed posting list follows */
@@ -34,7 +34,7 @@ typedef struct ginxlogCreatePostingTree
 
 #define XLOG_GIN_INSERT  0x20
 
-typedef struct
+typedef struct PG_NO_PADDING
 {
 	uint16		flags;			/* GIN_INSERT_ISLEAF and/or GIN_INSERT_ISDATA */
 
@@ -108,7 +108,7 @@ typedef struct
  */
 #define XLOG_GIN_SPLIT	0x30
 
-typedef struct ginxlogSplit
+typedef struct PG_NO_PADDING ginxlogSplit
 {
 	RelFileLocator locator;
 	BlockNumber rrlink;			/* right link, or root's blocknumber if root
@@ -116,6 +116,7 @@ typedef struct ginxlogSplit
 	BlockNumber leftChildBlkno; /* valid on a non-leaf split */
 	BlockNumber rightChildBlkno;
 	uint16		flags;			/* see below */
+	pg_padding_2(pg_pad);
 } ginxlogSplit;
 
 /*
@@ -152,9 +153,10 @@ typedef struct ginxlogVacuumDataLeafPage
  */
 #define XLOG_GIN_DELETE_PAGE	0x50
 
-typedef struct ginxlogDeletePage
+typedef struct PG_NO_PADDING ginxlogDeletePage
 {
 	OffsetNumber parentOffset;
+	pg_padding_2(pg_pad);
 	BlockNumber rightLink;
 	TransactionId deleteXid;	/* last Xid which could see this page in scan */
 } ginxlogDeletePage;
@@ -165,15 +167,17 @@ typedef struct ginxlogDeletePage
  * Backup Blk 0: metapage
  * Backup Blk 1: tail page
  */
-typedef struct ginxlogUpdateMeta
+typedef struct PG_NO_PADDING ginxlogUpdateMeta
 {
 	RelFileLocator locator;
+	pg_padding_4(pg_pad1);
 	GinMetaPageData metadata;
 	BlockNumber prevTail;
 	BlockNumber newRightlink;
 	int32		ntuples;		/* if ntuples > 0 then metadata.tail was
 								 * updated with that many tuples; else new sub
 								 * list was inserted */
+	pg_padding_4(pg_pad2);
 	/* array of inserted tuples follows */
 } ginxlogUpdateMeta;
 
@@ -182,7 +186,7 @@ typedef struct ginxlogUpdateMeta
 /*
  * Backup Blk 0: list page with inserted tuples
  */
-typedef struct ginxlogInsertListPage
+typedef struct PG_NO_PADDING ginxlogInsertListPage
 {
 	BlockNumber rightlink;
 	int32		ntuples;
@@ -203,10 +207,11 @@ typedef struct ginxlogInsertListPage
  * metapage.)
  */
 #define GIN_NDELETE_AT_ONCE Min(16, XLR_MAX_BLOCK_ID - 1)
-typedef struct ginxlogDeleteListPages
+typedef struct PG_NO_PADDING ginxlogDeleteListPages
 {
 	GinMetaPageData metadata;
 	int32		ndeleted;
+	pg_padding_4(pg_pad);
 } ginxlogDeleteListPages;
 
 extern void gin_redo(XLogReaderState *record);
diff --git a/src/include/access/gistxlog.h b/src/include/access/gistxlog.h
index d3d1c6549be..f19d4e8dfe6 100644
--- a/src/include/access/gistxlog.h
+++ b/src/include/access/gistxlog.h
@@ -33,7 +33,7 @@
  * Backup Blk 1: If this operation completes a page split, by inserting a
  *				 downlink for the split page, the left half of the split
  */
-typedef struct gistxlogPageUpdate
+typedef struct PG_NO_PADDING gistxlogPageUpdate
 {
 	/* number of deleted offsets */
 	uint16		ntodelete;
@@ -47,12 +47,13 @@ typedef struct gistxlogPageUpdate
 /*
  * Backup Blk 0: Leaf page, whose index tuples are deleted.
  */
-typedef struct gistxlogDelete
+typedef struct PG_NO_PADDING gistxlogDelete
 {
 	TransactionId snapshotConflictHorizon;
 	uint16		ntodelete;		/* number of deleted offsets */
 	bool		isCatalogRel;	/* to handle recovery conflict during logical
 								 * decoding on standby */
+	pg_padding_1(pg_pad);
 
 	/* TODELETE OFFSET NUMBERS */
 	OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
@@ -65,14 +66,18 @@ typedef struct gistxlogDelete
  *				 downlink for the split page, the left half of the split
  * Backup Blk 1 - npage: split pages (1 is the original page)
  */
-typedef struct gistxlogPageSplit
+typedef struct PG_NO_PADDING gistxlogPageSplit
 {
 	BlockNumber origrlink;		/* rightlink of the page before split */
+	pg_padding_4(pg_pad1);
 	GistNSN		orignsn;		/* NSN of the page before split */
 	bool		origleaf;		/* was split page a leaf page? */
+	pg_padding_1(pg_pad2);
 
 	uint16		npage;			/* # of pages in the split */
 	bool		markfollowright;	/* set F_FOLLOW_RIGHT flags */
+	pg_padding_1(pg_pad3);
+	pg_padding_2(pg_pad4);
 
 	/*
 	 * follow: 1. gistxlogPage and array of IndexTupleData per page
@@ -83,29 +88,34 @@ typedef struct gistxlogPageSplit
  * Backup Blk 0: page that was deleted.
  * Backup Blk 1: parent page, containing the downlink to the deleted page.
  */
-typedef struct gistxlogPageDelete
+typedef struct PG_NO_PADDING gistxlogPageDelete
 {
 	FullTransactionId deleteXid;	/* last Xid which could see page in scan */
 	OffsetNumber downlinkOffset;	/* Offset of downlink referencing this
 									 * page */
+	pg_padding_2(pg_pad1);
+	pg_padding_4(pg_pad2);
 } gistxlogPageDelete;
 
-#define SizeOfGistxlogPageDelete	(offsetof(gistxlogPageDelete, downlinkOffset) + sizeof(OffsetNumber))
+#define SizeOfGistxlogPageDelete	(sizeof(gistxlogPageDelete))
 
 
 /*
  * This is what we need to know about page reuse, for hot standby.
  */
-typedef struct gistxlogPageReuse
+typedef struct PG_NO_PADDING gistxlogPageReuse
 {
 	RelFileLocator locator;
 	BlockNumber block;
 	FullTransactionId snapshotConflictHorizon;
 	bool		isCatalogRel;	/* to handle recovery conflict during logical
 								 * decoding on standby */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
+	pg_padding_4(pg_pad4);
 } gistxlogPageReuse;
 
-#define SizeOfGistxlogPageReuse	(offsetof(gistxlogPageReuse, isCatalogRel) + sizeof(bool))
+#define SizeOfGistxlogPageReuse	(sizeof(gistxlogPageReuse))
 
 extern void gist_redo(XLogReaderState *record);
 extern void gist_desc(StringInfo buf, XLogReaderState *record);
diff --git a/src/include/access/hash_xlog.h b/src/include/access/hash_xlog.h
index 149aed69dc5..bb6b9d0fe11 100644
--- a/src/include/access/hash_xlog.h
+++ b/src/include/access/hash_xlog.h
@@ -59,12 +59,12 @@
  * Backup Blk 0: original page (data contains the inserted tuple)
  * Backup Blk 1: metapage (HashMetaPageData)
  */
-typedef struct xl_hash_insert
+typedef struct PG_NO_PADDING xl_hash_insert
 {
 	OffsetNumber offnum;
 } xl_hash_insert;
 
-#define SizeOfHashInsert	(offsetof(xl_hash_insert, offnum) + sizeof(OffsetNumber))
+#define SizeOfHashInsert	(sizeof(xl_hash_insert))
 
 /*
  * This is what we need to know about addition of overflow page.
@@ -77,14 +77,14 @@ typedef struct xl_hash_insert
  * Backup Blk 3: new bitmap page
  * Backup Blk 4: metapage
  */
-typedef struct xl_hash_add_ovfl_page
+typedef struct PG_NO_PADDING xl_hash_add_ovfl_page
 {
 	uint16		bmsize;
 	bool		bmpage_found;
+	pg_padding_1(pg_pad);
 } xl_hash_add_ovfl_page;
 
-#define SizeOfHashAddOvflPage	\
-	(offsetof(xl_hash_add_ovfl_page, bmpage_found) + sizeof(bool))
+#define SizeOfHashAddOvflPage	(sizeof(xl_hash_add_ovfl_page))
 
 /*
  * This is what we need to know about allocating a page for split.
@@ -95,16 +95,17 @@ typedef struct xl_hash_add_ovfl_page
  * Backup Blk 1: page for new bucket
  * Backup Blk 2: metapage
  */
-typedef struct xl_hash_split_allocate_page
+typedef struct PG_NO_PADDING xl_hash_split_allocate_page
 {
 	uint32		new_bucket;
 	uint16		old_bucket_flag;
 	uint16		new_bucket_flag;
 	uint8		flags;
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 } xl_hash_split_allocate_page;
 
-#define SizeOfHashSplitAllocPage	\
-	(offsetof(xl_hash_split_allocate_page, flags) + sizeof(uint8))
+#define SizeOfHashSplitAllocPage	(sizeof(xl_hash_split_allocate_page))
 
 /*
  * This is what we need to know about completing the split operation.
@@ -114,14 +115,13 @@ typedef struct xl_hash_split_allocate_page
  * Backup Blk 0: page for old bucket
  * Backup Blk 1: page for new bucket
  */
-typedef struct xl_hash_split_complete
+typedef struct PG_NO_PADDING xl_hash_split_complete
 {
 	uint16		old_bucket_flag;
 	uint16		new_bucket_flag;
 } xl_hash_split_complete;
 
-#define SizeOfHashSplitComplete \
-	(offsetof(xl_hash_split_complete, new_bucket_flag) + sizeof(uint16))
+#define SizeOfHashSplitComplete	(sizeof(xl_hash_split_complete))
 
 /*
  * This is what we need to know about move page contents required during
@@ -133,16 +133,16 @@ typedef struct xl_hash_split_complete
  * Backup Blk 1: page containing moved tuples
  * Backup Blk 2: page from which tuples will be removed
  */
-typedef struct xl_hash_move_page_contents
+typedef struct PG_NO_PADDING xl_hash_move_page_contents
 {
 	uint16		ntups;
 	bool		is_prim_bucket_same_wrt;	/* true if the page to which
 											 * tuples are moved is same as
 											 * primary bucket page */
+	pg_padding_1(pg_pad);
 } xl_hash_move_page_contents;
 
-#define SizeOfHashMovePageContents	\
-	(offsetof(xl_hash_move_page_contents, is_prim_bucket_same_wrt) + sizeof(bool))
+#define SizeOfHashMovePageContents	(sizeof(xl_hash_move_page_contents))
 
 /*
  * This is what we need to know about the squeeze page operation.
@@ -157,7 +157,7 @@ typedef struct xl_hash_move_page_contents
  * Backup Blk 5: bitmap page containing info of freed overflow page
  * Backup Blk 6: meta page
  */
-typedef struct xl_hash_squeeze_page
+typedef struct PG_NO_PADDING xl_hash_squeeze_page
 {
 	BlockNumber prevblkno;
 	BlockNumber nextblkno;
@@ -171,8 +171,7 @@ typedef struct xl_hash_squeeze_page
 											 * page */
 } xl_hash_squeeze_page;
 
-#define SizeOfHashSqueezePage	\
-	(offsetof(xl_hash_squeeze_page, is_prev_bucket_same_wrt) + sizeof(bool))
+#define SizeOfHashSqueezePage	(sizeof(xl_hash_squeeze_page))
 
 /*
  * This is what we need to know about the deletion of index tuples from a page.
@@ -182,7 +181,7 @@ typedef struct xl_hash_squeeze_page
  * Backup Blk 0: primary bucket page
  * Backup Blk 1: page from which tuples are deleted
  */
-typedef struct xl_hash_delete
+typedef struct PG_NO_PADDING xl_hash_delete
 {
 	bool		clear_dead_marking; /* true if this operation clears
 									 * LH_PAGE_HAS_DEAD_TUPLES flag */
@@ -190,7 +189,7 @@ typedef struct xl_hash_delete
 										 * primary bucket page */
 } xl_hash_delete;
 
-#define SizeOfHashDelete	(offsetof(xl_hash_delete, is_primary_bucket_page) + sizeof(bool))
+#define SizeOfHashDelete	(sizeof(xl_hash_delete))
 
 /*
  * This is what we need for metapage update operation.
@@ -199,13 +198,12 @@ typedef struct xl_hash_delete
  *
  * Backup Blk 0: meta page
  */
-typedef struct xl_hash_update_meta_page
+typedef struct PG_NO_PADDING xl_hash_update_meta_page
 {
 	double		ntuples;
 } xl_hash_update_meta_page;
 
-#define SizeOfHashUpdateMetaPage	\
-	(offsetof(xl_hash_update_meta_page, ntuples) + sizeof(double))
+#define SizeOfHashUpdateMetaPage	(sizeof(xl_hash_update_meta_page))
 
 /*
  * This is what we need to initialize metapage.
@@ -214,15 +212,15 @@ typedef struct xl_hash_update_meta_page
  *
  * Backup Blk 0: meta page
  */
-typedef struct xl_hash_init_meta_page
+typedef struct PG_NO_PADDING xl_hash_init_meta_page
 {
 	double		num_tuples;
 	RegProcedure procid;
 	uint16		ffactor;
+	pg_padding_2(pg_pad);
 } xl_hash_init_meta_page;
 
-#define SizeOfHashInitMetaPage		\
-	(offsetof(xl_hash_init_meta_page, ffactor) + sizeof(uint16))
+#define SizeOfHashInitMetaPage	(sizeof(xl_hash_init_meta_page))
 
 /*
  * This is what we need to initialize bitmap page.
@@ -232,13 +230,12 @@ typedef struct xl_hash_init_meta_page
  * Backup Blk 0: bitmap page
  * Backup Blk 1: meta page
  */
-typedef struct xl_hash_init_bitmap_page
+typedef struct PG_NO_PADDING xl_hash_init_bitmap_page
 {
 	uint16		bmsize;
 } xl_hash_init_bitmap_page;
 
-#define SizeOfHashInitBitmapPage	\
-	(offsetof(xl_hash_init_bitmap_page, bmsize) + sizeof(uint16))
+#define SizeOfHashInitBitmapPage	(sizeof(xl_hash_init_bitmap_page))
 
 /*
  * This is what we need for index tuple deletion and to
@@ -249,12 +246,13 @@ typedef struct xl_hash_init_bitmap_page
  * Backup Blk 0: primary bucket page
  * Backup Blk 1: meta page
  */
-typedef struct xl_hash_vacuum_one_page
+typedef struct PG_NO_PADDING xl_hash_vacuum_one_page
 {
 	TransactionId snapshotConflictHorizon;
 	uint16		ntuples;
 	bool		isCatalogRel;	/* to handle recovery conflict during logical
 								 * decoding on standby */
+	pg_padding_1(pg_pad);
 
 	/* TARGET OFFSET NUMBERS */
 	OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
diff --git a/src/include/access/heapam_xlog.h b/src/include/access/heapam_xlog.h
index ce3566ba949..74a3803ad14 100644
--- a/src/include/access/heapam_xlog.h
+++ b/src/include/access/heapam_xlog.h
@@ -110,7 +110,7 @@
 	(XLH_DELETE_CONTAINS_OLD_TUPLE | XLH_DELETE_CONTAINS_OLD_KEY)
 
 /* This is what we need to know about delete */
-typedef struct xl_heap_delete
+typedef struct PG_NO_PADDING xl_heap_delete
 {
 	TransactionId xmax;			/* xmax of the deleted tuple */
 	OffsetNumber offnum;		/* deleted tuple's offset */
@@ -118,7 +118,7 @@ typedef struct xl_heap_delete
 	uint8		flags;
 } xl_heap_delete;
 
-#define SizeOfHeapDelete	(offsetof(xl_heap_delete, flags) + sizeof(uint8))
+#define SizeOfHeapDelete	sizeof(xl_heap_delete)
 
 /*
  * xl_heap_truncate flag values, 8 bits are available.
@@ -131,11 +131,13 @@ typedef struct xl_heap_delete
  * sequence relids that need to be restarted, if any.
  * All rels are always within the same database, so we just list dbid once.
  */
-typedef struct xl_heap_truncate
+typedef struct PG_NO_PADDING xl_heap_truncate
 {
 	Oid			dbId;
 	uint32		nrelids;
 	uint8		flags;
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 	Oid			relids[FLEXIBLE_ARRAY_MEMBER];
 } xl_heap_truncate;
 
@@ -147,25 +149,27 @@ typedef struct xl_heap_truncate
  * fields that are available elsewhere in the WAL record, or perhaps just
  * plain needn't be reconstructed.  These are the fields we must store.
  */
-typedef struct xl_heap_header
+typedef struct PG_NO_PADDING xl_heap_header
 {
 	uint16		t_infomask2;
 	uint16		t_infomask;
 	uint8		t_hoff;
+	pg_padding_1(pg_pad);
 } xl_heap_header;
 
-#define SizeOfHeapHeader	(offsetof(xl_heap_header, t_hoff) + sizeof(uint8))
+#define SizeOfHeapHeader	sizeof(xl_heap_header)
 
 /* This is what we need to know about insert */
-typedef struct xl_heap_insert
+typedef struct PG_NO_PADDING xl_heap_insert
 {
 	OffsetNumber offnum;		/* inserted tuple's offset */
 	uint8		flags;
+	pg_padding_1(pg_pad);
 
 	/* xl_heap_header & TUPLE DATA in backup block 0 */
 } xl_heap_insert;
 
-#define SizeOfHeapInsert	(offsetof(xl_heap_insert, flags) + sizeof(uint8))
+#define SizeOfHeapInsert	sizeof(xl_heap_insert)
 
 /*
  * This is what we need to know about a multi-insert.
@@ -178,25 +182,27 @@ typedef struct xl_heap_insert
  * followed by the tuple data for each tuple. There is padding to align
  * each xl_multi_insert_tuple struct.
  */
-typedef struct xl_heap_multi_insert
+typedef struct PG_NO_PADDING xl_heap_multi_insert
 {
 	uint8		flags;
+	pg_padding_1(pg_pad);
 	uint16		ntuples;
 	OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
 } xl_heap_multi_insert;
 
 #define SizeOfHeapMultiInsert	offsetof(xl_heap_multi_insert, offsets)
 
-typedef struct xl_multi_insert_tuple
+typedef struct PG_NO_PADDING xl_multi_insert_tuple
 {
 	uint16		datalen;		/* size of tuple data that follows */
 	uint16		t_infomask2;
 	uint16		t_infomask;
 	uint8		t_hoff;
+	pg_padding_1(pg_pad);
 	/* TUPLE DATA FOLLOWS AT END OF STRUCT */
 } xl_multi_insert_tuple;
 
-#define SizeOfMultiInsertTuple	(offsetof(xl_multi_insert_tuple, t_hoff) + sizeof(uint8))
+#define SizeOfMultiInsertTuple	sizeof(xl_multi_insert_tuple)
 
 /*
  * This is what we need to know about update|hot_update
@@ -215,7 +221,7 @@ typedef struct xl_multi_insert_tuple
  *
  * Backup blk 1: old page, if different. (no data, just a reference to the blk)
  */
-typedef struct xl_heap_update
+typedef struct PG_NO_PADDING xl_heap_update
 {
 	TransactionId old_xmax;		/* xmax of the old tuple */
 	OffsetNumber old_offnum;	/* old tuple's offset */
@@ -223,6 +229,7 @@ typedef struct xl_heap_update
 	uint8		flags;
 	TransactionId new_xmax;		/* xmax of the new tuple */
 	OffsetNumber new_offnum;	/* new tuple's offset */
+	pg_padding_2(pg_pad);
 
 	/*
 	 * If XLH_UPDATE_CONTAINS_OLD_TUPLE or XLH_UPDATE_CONTAINS_OLD_KEY flags
@@ -230,7 +237,7 @@ typedef struct xl_heap_update
 	 */
 } xl_heap_update;
 
-#define SizeOfHeapUpdate	(offsetof(xl_heap_update, new_offnum) + sizeof(OffsetNumber))
+#define SizeOfHeapUpdate	sizeof(xl_heap_update)
 
 /*
  * These structures and flags encode VACUUM pruning and freezing and on-access
@@ -282,7 +289,7 @@ typedef struct xl_heap_update
  * other fields require only 2-byte alignment.  This is also the reason that
  * 'frz_offsets' is stored separately from the xlhp_freeze_plan structs.
  */
-typedef struct xl_heap_prune
+typedef struct PG_NO_PADDING xl_heap_prune
 {
 	uint16		flags;
 
@@ -292,7 +299,7 @@ typedef struct xl_heap_prune
 	 */
 } xl_heap_prune;
 
-#define SizeOfHeapPrune (offsetof(xl_heap_prune, flags) + sizeof(uint16))
+#define SizeOfHeapPrune sizeof(xl_heap_prune)
 
 /* to handle recovery conflict during logical decoding on standby */
 #define		XLHP_IS_CATALOG_REL			(1 << 1)
@@ -347,12 +354,13 @@ typedef struct xl_heap_prune
 #define		XLH_FREEZE_XVAC		0x02
 #define		XLH_INVALID_XVAC	0x04
 
-typedef struct xlhp_freeze_plan
+typedef struct PG_NO_PADDING xlhp_freeze_plan
 {
 	TransactionId xmax;
 	uint16		t_infomask2;
 	uint16		t_infomask;
 	uint8		frzflags;
+	pg_padding_1(pg_pad);
 
 	/* Length of individual page offset numbers array for this plan */
 	uint16		ntuples;
@@ -370,9 +378,10 @@ typedef struct xlhp_freeze_plan
  * (As of PostgreSQL 17, XLOG_HEAP2_PRUNE_VACUUM_SCAN records replace the
  * separate XLOG_HEAP2_FREEZE_PAGE records.)
  */
-typedef struct xlhp_freeze_plans
+typedef struct PG_NO_PADDING xlhp_freeze_plans
 {
 	uint16		nplans;
+	pg_padding_2(pg_pad);
 	xlhp_freeze_plan plans[FLEXIBLE_ARRAY_MEMBER];
 } xlhp_freeze_plans;
 
@@ -383,7 +392,7 @@ typedef struct xlhp_freeze_plans
  * set.  Note that in the XLHP_HAS_REDIRECTIONS variant, there are actually 2
  * * length number of OffsetNumbers in the data.
  */
-typedef struct xlhp_prune_items
+typedef struct PG_NO_PADDING xlhp_prune_items
 {
 	uint16		ntargets;
 	OffsetNumber data[FLEXIBLE_ARRAY_MEMBER];
@@ -401,7 +410,7 @@ typedef struct xlhp_prune_items
 #define XLH_LOCK_ALL_FROZEN_CLEARED		0x01
 
 /* This is what we need to know about lock */
-typedef struct xl_heap_lock
+typedef struct PG_NO_PADDING xl_heap_lock
 {
 	TransactionId xmax;			/* might be a MultiXactId */
 	OffsetNumber offnum;		/* locked tuple's offset on page */
@@ -409,10 +418,10 @@ typedef struct xl_heap_lock
 	uint8		flags;			/* XLH_LOCK_* flag bits */
 } xl_heap_lock;
 
-#define SizeOfHeapLock	(offsetof(xl_heap_lock, flags) + sizeof(uint8))
+#define SizeOfHeapLock	sizeof(xl_heap_lock)
 
 /* This is what we need to know about locking an updated version of a row */
-typedef struct xl_heap_lock_updated
+typedef struct PG_NO_PADDING xl_heap_lock_updated
 {
 	TransactionId xmax;
 	OffsetNumber offnum;
@@ -420,23 +429,26 @@ typedef struct xl_heap_lock_updated
 	uint8		flags;
 } xl_heap_lock_updated;
 
-#define SizeOfHeapLockUpdated	(offsetof(xl_heap_lock_updated, flags) + sizeof(uint8))
+#define SizeOfHeapLockUpdated	sizeof(xl_heap_lock_updated)
 
 /* This is what we need to know about confirmation of speculative insertion */
-typedef struct xl_heap_confirm
+typedef struct PG_NO_PADDING xl_heap_confirm
 {
 	OffsetNumber offnum;		/* confirmed tuple's offset on page */
 } xl_heap_confirm;
 
-#define SizeOfHeapConfirm	(offsetof(xl_heap_confirm, offnum) + sizeof(OffsetNumber))
+#define SizeOfHeapConfirm	sizeof(xl_heap_confirm)
 
 /* This is what we need to know about in-place update */
-typedef struct xl_heap_inplace
+typedef struct PG_NO_PADDING xl_heap_inplace
 {
 	OffsetNumber offnum;		/* updated tuple's offset on page */
+	pg_padding_2(pg_pad1);
 	Oid			dbId;			/* MyDatabaseId */
 	Oid			tsId;			/* MyDatabaseTableSpace */
 	bool		relcacheInitFileInval;	/* invalidate relcache init files */
+	pg_padding_1(pg_pad2);
+	pg_padding_2(pg_pad3);
 	int			nmsgs;			/* number of shared inval msgs */
 	SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER];
 } xl_heap_inplace;
@@ -449,15 +461,17 @@ typedef struct xl_heap_inplace
  * Backup blk 0: visibility map buffer
  * Backup blk 1: heap buffer
  */
-typedef struct xl_heap_visible
+typedef struct PG_NO_PADDING xl_heap_visible
 {
 	TransactionId snapshotConflictHorizon;
 	uint8		flags;
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 } xl_heap_visible;
 
-#define SizeOfHeapVisible (offsetof(xl_heap_visible, flags) + sizeof(uint8))
+#define SizeOfHeapVisible sizeof(xl_heap_visible)
 
-typedef struct xl_heap_new_cid
+typedef struct PG_NO_PADDING xl_heap_new_cid
 {
 	/*
 	 * store toplevel xid so we don't have to merge cids from different
@@ -473,18 +487,21 @@ typedef struct xl_heap_new_cid
 	 */
 	RelFileLocator target_locator;
 	ItemPointerData target_tid;
+	pg_padding_2(pg_pad);
 } xl_heap_new_cid;
 
-#define SizeOfHeapNewCid (offsetof(xl_heap_new_cid, target_tid) + sizeof(ItemPointerData))
+#define SizeOfHeapNewCid sizeof(xl_heap_new_cid)
 
 /* logical rewrite xlog record header */
-typedef struct xl_heap_rewrite_mapping
+typedef struct PG_NO_PADDING xl_heap_rewrite_mapping
 {
 	TransactionId mapped_xid;	/* xid that might need to see the row */
 	Oid			mapped_db;		/* DbOid or InvalidOid for shared rels */
 	Oid			mapped_rel;		/* Oid of the mapped relation */
+	pg_padding_4(pg_pad1);
 	off_t		offset;			/* How far have we written so far */
 	uint32		num_mappings;	/* Number of in-memory mappings */
+	pg_padding_4(pg_pad2);
 	XLogRecPtr	start_lsn;		/* Insert LSN at begin of rewrite */
 } xl_heap_rewrite_mapping;
 
diff --git a/src/include/access/multixact.h b/src/include/access/multixact.h
index 2ae8b571dcc..3fe4501d27f 100644
--- a/src/include/access/multixact.h
+++ b/src/include/access/multixact.h
@@ -69,17 +69,19 @@ typedef struct MultiXactMember
 #define XLOG_MULTIXACT_CREATE_ID		0x20
 #define XLOG_MULTIXACT_TRUNCATE_ID		0x30
 
-typedef struct xl_multixact_create
+typedef struct PG_NO_PADDING xl_multixact_create
 {
 	MultiXactId mid;			/* new MultiXact's ID */
+	pg_padding_4(pg_pad1);
 	MultiXactOffset moff;		/* its starting offset in members file */
 	int32		nmembers;		/* number of member XIDs */
+	pg_padding_4(pg_pad2);
 	MultiXactMember members[FLEXIBLE_ARRAY_MEMBER];
 } xl_multixact_create;
 
 #define SizeOfMultiXactCreate (offsetof(xl_multixact_create, members))
 
-typedef struct xl_multixact_truncate
+typedef struct PG_NO_PADDING xl_multixact_truncate
 {
 	Oid			oldestMultiDB;
 
diff --git a/src/include/access/nbtxlog.h b/src/include/access/nbtxlog.h
index 3a78ec27fe8..8918d675dce 100644
--- a/src/include/access/nbtxlog.h
+++ b/src/include/access/nbtxlog.h
@@ -46,7 +46,7 @@
 /*
  * All that we need to regenerate the meta-data page
  */
-typedef struct xl_btree_metadata
+typedef struct PG_NO_PADDING xl_btree_metadata
 {
 	uint32		version;
 	BlockNumber root;
@@ -55,6 +55,8 @@ typedef struct xl_btree_metadata
 	uint32		fastlevel;
 	uint32		last_cleanup_num_delpages;
 	bool		allequalimage;
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 } xl_btree_metadata;
 
 /*
@@ -76,7 +78,7 @@ typedef struct xl_btree_metadata
  * that was split as an extra step.  Also, recovery generates a "final"
  * newitem.  See _bt_swap_posting() for details on posting list splits.
  */
-typedef struct xl_btree_insert
+typedef struct PG_NO_PADDING xl_btree_insert
 {
 	OffsetNumber offnum;
 
@@ -84,7 +86,7 @@ typedef struct xl_btree_insert
 	/* NEW TUPLE ALWAYS FOLLOWS AT THE END */
 } xl_btree_insert;
 
-#define SizeOfBtreeInsert	(offsetof(xl_btree_insert, offnum) + sizeof(OffsetNumber))
+#define SizeOfBtreeInsert	sizeof(xl_btree_insert)
 
 /*
  * On insert with split, we save all the items going into the right sibling
@@ -150,15 +152,16 @@ typedef struct xl_btree_insert
  * Backup Blk 2: next block (orig page's rightlink), if any
  * Backup Blk 3: child's left sibling, if non-leaf split
  */
-typedef struct xl_btree_split
+typedef struct PG_NO_PADDING xl_btree_split
 {
 	uint32		level;			/* tree level of page being split */
 	OffsetNumber firstrightoff; /* first origpage item on rightpage */
 	OffsetNumber newitemoff;	/* new item's offset */
 	uint16		postingoff;		/* offset inside orig posting tuple */
+	pg_padding_2(pg_pad);
 } xl_btree_split;
 
-#define SizeOfBtreeSplit	(offsetof(xl_btree_split, postingoff) + sizeof(uint16))
+#define SizeOfBtreeSplit	sizeof(xl_btree_split)
 
 /*
  * When page is deduplicated, consecutive groups of tuples with equal keys are
@@ -167,14 +170,14 @@ typedef struct xl_btree_split
  * The WAL record represents a deduplication pass for a leaf page.  An array
  * of BTDedupInterval structs follows.
  */
-typedef struct xl_btree_dedup
+typedef struct PG_NO_PADDING xl_btree_dedup
 {
 	uint16		nintervals;
 
 	/* DEDUPLICATION INTERVALS FOLLOW */
 } xl_btree_dedup;
 
-#define SizeOfBtreeDedup 	(offsetof(xl_btree_dedup, nintervals) + sizeof(uint16))
+#define SizeOfBtreeDedup	sizeof(xl_btree_dedup)
 
 /*
  * This is what we need to know about page reuse within btree.  This record
@@ -183,16 +186,19 @@ typedef struct xl_btree_dedup
  * Note that we must include a RelFileLocator in the record because we don't
  * actually register the buffer with the record.
  */
-typedef struct xl_btree_reuse_page
+typedef struct PG_NO_PADDING xl_btree_reuse_page
 {
 	RelFileLocator locator;
 	BlockNumber block;
 	FullTransactionId snapshotConflictHorizon;
 	bool		isCatalogRel;	/* to handle recovery conflict during logical
 								 * decoding on standby */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
+	pg_padding_4(pg_pad4);
 } xl_btree_reuse_page;
 
-#define SizeOfBtreeReusePage	(offsetof(xl_btree_reuse_page, isCatalogRel) + sizeof(bool))
+#define SizeOfBtreeReusePage	sizeof(xl_btree_reuse_page)
 
 /*
  * xl_btree_vacuum and xl_btree_delete records describe deletion of index
@@ -220,7 +226,7 @@ typedef struct xl_btree_reuse_page
  * Updates are only used when there will be some remaining TIDs left by the
  * REDO routine.  Otherwise the posting list tuple just gets deleted outright.
  */
-typedef struct xl_btree_vacuum
+typedef struct PG_NO_PADDING xl_btree_vacuum
 {
 	uint16		ndeleted;
 	uint16		nupdated;
@@ -234,15 +240,17 @@ typedef struct xl_btree_vacuum
 	 */
 } xl_btree_vacuum;
 
-#define SizeOfBtreeVacuum	(offsetof(xl_btree_vacuum, nupdated) + sizeof(uint16))
+#define SizeOfBtreeVacuum	sizeof(xl_btree_vacuum)
 
-typedef struct xl_btree_delete
+typedef struct PG_NO_PADDING xl_btree_delete
 {
 	TransactionId snapshotConflictHorizon;
 	uint16		ndeleted;
 	uint16		nupdated;
 	bool		isCatalogRel;	/* to handle recovery conflict during logical
 								 * decoding on standby */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 
 	/*----
 	 * In payload of blk 0 :
@@ -253,7 +261,7 @@ typedef struct xl_btree_delete
 	 */
 } xl_btree_delete;
 
-#define SizeOfBtreeDelete	(offsetof(xl_btree_delete, isCatalogRel) + sizeof(bool))
+#define SizeOfBtreeDelete	sizeof(xl_btree_delete)
 
 /*
  * The offsets that appear in xl_btree_update metadata are offsets into the
@@ -261,14 +269,14 @@ typedef struct xl_btree_delete
  * 0-based.  The page offset number for the original posting list tuple comes
  * from the main xl_btree_vacuum/xl_btree_delete record.
  */
-typedef struct xl_btree_update
+typedef struct PG_NO_PADDING xl_btree_update
 {
 	uint16		ndeletedtids;
 
 	/* POSTING LIST uint16 OFFSETS TO A DELETED TID FOLLOW */
 } xl_btree_update;
 
-#define SizeOfBtreeUpdate	(offsetof(xl_btree_update, ndeletedtids) + sizeof(uint16))
+#define SizeOfBtreeUpdate	sizeof(xl_btree_update)
 
 /*
  * This is what we need to know about marking an empty subtree for deletion.
@@ -280,9 +288,10 @@ typedef struct xl_btree_update
  * Backup Blk 0: leaf block
  * Backup Blk 1: top parent
  */
-typedef struct xl_btree_mark_page_halfdead
+typedef struct PG_NO_PADDING xl_btree_mark_page_halfdead
 {
 	OffsetNumber poffset;		/* deleted tuple id in parent page */
+	pg_padding_2(pg_pad);
 
 	/* information needed to recreate the leaf page: */
 	BlockNumber leafblk;		/* leaf block ultimately being deleted */
@@ -291,7 +300,7 @@ typedef struct xl_btree_mark_page_halfdead
 	BlockNumber topparent;		/* topmost internal page in the subtree */
 } xl_btree_mark_page_halfdead;
 
-#define SizeOfBtreeMarkPageHalfDead (offsetof(xl_btree_mark_page_halfdead, topparent) + sizeof(BlockNumber))
+#define SizeOfBtreeMarkPageHalfDead sizeof(xl_btree_mark_page_halfdead)
 
 /*
  * This is what we need to know about deletion of a btree page.  Note that we
@@ -307,11 +316,12 @@ typedef struct xl_btree_mark_page_halfdead
  * Backup Blk 3: leaf block (if different from target)
  * Backup Blk 4: metapage (if rightsib becomes new fast root)
  */
-typedef struct xl_btree_unlink_page
+typedef struct PG_NO_PADDING xl_btree_unlink_page
 {
 	BlockNumber leftsib;		/* target block's left sibling, if any */
 	BlockNumber rightsib;		/* target block's right sibling */
 	uint32		level;			/* target block's level */
+	pg_padding_4(pg_pad1);
 	FullTransactionId safexid;	/* target block's BTPageSetDeleted() XID */
 
 	/*
@@ -324,11 +334,12 @@ typedef struct xl_btree_unlink_page
 	BlockNumber leafleftsib;
 	BlockNumber leafrightsib;
 	BlockNumber leaftopparent;	/* next child down in the subtree */
+	pg_padding_4(pg_pad2);
 
 	/* xl_btree_metadata FOLLOWS IF XLOG_BTREE_UNLINK_PAGE_META */
 } xl_btree_unlink_page;
 
-#define SizeOfBtreeUnlinkPage	(offsetof(xl_btree_unlink_page, leaftopparent) + sizeof(BlockNumber))
+#define SizeOfBtreeUnlinkPage	sizeof(xl_btree_unlink_page)
 
 /*
  * New root log record.  There are zero tuples if this is to establish an
@@ -341,13 +352,13 @@ typedef struct xl_btree_unlink_page
  * Backup Blk 1: left child (if splitting an old root)
  * Backup Blk 2: metapage
  */
-typedef struct xl_btree_newroot
+typedef struct PG_NO_PADDING xl_btree_newroot
 {
 	BlockNumber rootblk;		/* location of new root (redundant with blk 0) */
 	uint32		level;			/* its tree level */
 } xl_btree_newroot;
 
-#define SizeOfBtreeNewroot	(offsetof(xl_btree_newroot, level) + sizeof(uint32))
+#define SizeOfBtreeNewroot	sizeof(xl_btree_newroot)
 
 
 /*
diff --git a/src/include/access/spgist_private.h b/src/include/access/spgist_private.h
index ec6d6f5f74d..c05693846d8 100644
--- a/src/include/access/spgist_private.h
+++ b/src/include/access/spgist_private.h
@@ -292,14 +292,14 @@ typedef struct SpGistCache
  * opclasses.  Going forward, we will be using a fixed size of Datum so that
  * there's no longer any pressing reason to change this.
  */
-typedef struct SpGistInnerTupleData
+typedef struct PG_NO_PADDING SpGistInnerTupleData
 {
 	unsigned int tupstate:2,	/* LIVE/REDIRECT/DEAD/PLACEHOLDER */
 				allTheSame:1,	/* all nodes in tuple are equivalent */
 				nNodes:13,		/* number of nodes within inner tuple */
 				prefixSize:16;	/* size of prefix, or 0 if none */
 	uint16		size;			/* total size of inner tuple */
-	/* On most machines there will be a couple of wasted bytes here */
+	pg_padding_2(pg_pad);
 	/* prefix datum follows, then nodes */
 } SpGistInnerTupleData;
 
@@ -382,7 +382,7 @@ typedef SpGistNodeTupleData *SpGistNodeTuple;
  * restriction only adds bytes for a NULL leaf datum; otherwise alignment
  * restrictions force it anyway.)
  */
-typedef struct SpGistLeafTupleData
+typedef struct PG_NO_PADDING SpGistLeafTupleData
 {
 	unsigned int tupstate:2,	/* LIVE/REDIRECT/DEAD/PLACEHOLDER */
 				size:30;		/* large enough for any palloc'able value */
diff --git a/src/include/access/spgxlog.h b/src/include/access/spgxlog.h
index c257408be66..fc1431407fd 100644
--- a/src/include/access/spgxlog.h
+++ b/src/include/access/spgxlog.h
@@ -33,17 +33,19 @@
  * need to be valid.  spgxlogState carries the required info in xlog records.
  * (See fillFakeState in spgxlog.c for more comments.)
  */
-typedef struct spgxlogState
+typedef struct PG_NO_PADDING spgxlogState
 {
 	TransactionId redirectXid;
 	bool		isBuild;
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 } spgxlogState;
 
 /*
  * Backup Blk 0: destination page for leaf tuple
  * Backup Blk 1: parent page (if any)
  */
-typedef struct spgxlogAddLeaf
+typedef struct PG_NO_PADDING spgxlogAddLeaf
 {
 	bool		newPage;		/* init dest page? */
 	bool		storesNulls;	/* page is in the nulls tree? */
@@ -61,17 +63,19 @@ typedef struct spgxlogAddLeaf
  * Backup Blk 1: destination leaf page
  * Backup Blk 2: parent page
  */
-typedef struct spgxlogMoveLeafs
+typedef struct PG_NO_PADDING spgxlogMoveLeafs
 {
 	uint16		nMoves;			/* number of tuples moved from source page */
 	bool		newPage;		/* init dest page? */
 	bool		replaceDead;	/* are we replacing a DEAD source tuple? */
 	bool		storesNulls;	/* pages are in the nulls tree? */
+	pg_padding_1(pg_pad1);
 
 	/* where the parent downlink is */
 	OffsetNumber offnumParent;
 	uint16		nodeI;
 
+	pg_padding_2(pg_pad2);
 	spgxlogState stateSrc;
 
 	/*----------
@@ -96,7 +100,7 @@ typedef struct spgxlogMoveLeafs
  * Backup Blk 2: where parent downlink is, if updated and different from
  *				 the old and new
  */
-typedef struct spgxlogAddNode
+typedef struct PG_NO_PADDING spgxlogAddNode
 {
 	/*
 	 * Offset of the original inner tuple, in the original page (on backup
@@ -127,6 +131,7 @@ typedef struct spgxlogAddNode
 
 	uint16		nodeI;
 
+	pg_padding_2(pg_pad);
 	spgxlogState stateSrc;
 
 	/*
@@ -138,7 +143,7 @@ typedef struct spgxlogAddNode
  * Backup Blk 0: where the prefix tuple goes
  * Backup Blk 1: where the postfix tuple goes (if different page)
  */
-typedef struct spgxlogSplitTuple
+typedef struct PG_NO_PADDING spgxlogSplitTuple
 {
 	/* where the prefix tuple goes */
 	OffsetNumber offnumPrefix;
@@ -162,9 +167,10 @@ typedef struct spgxlogSplitTuple
  * Backup Blk 2: Inner page
  * Backup Blk 3: Parent page (if any, and different from Inner)
  */
-typedef struct spgxlogPickSplit
+typedef struct PG_NO_PADDING spgxlogPickSplit
 {
 	bool		isRootSplit;
+	pg_padding_1(pg_pad1);
 
 	uint16		nDelete;		/* n to delete from Src */
 	uint16		nInsert;		/* n to insert on Src and/or Dest */
@@ -179,9 +185,11 @@ typedef struct spgxlogPickSplit
 
 	/* where the parent downlink is, if any */
 	bool		innerIsParent;	/* is parent the same as inner page? */
+	pg_padding_1(pg_pad2);
 	OffsetNumber offnumParent;
 	uint16		nodeI;
 
+	pg_padding_2(pg_pad3);
 	spgxlogState stateSrc;
 
 	/*----------
@@ -198,7 +206,7 @@ typedef struct spgxlogPickSplit
 
 #define SizeOfSpgxlogPickSplit offsetof(spgxlogPickSplit, offsets)
 
-typedef struct spgxlogVacuumLeaf
+typedef struct PG_NO_PADDING spgxlogVacuumLeaf
 {
 	uint16		nDead;			/* number of tuples to become DEAD */
 	uint16		nPlaceholder;	/* number of tuples to become PLACEHOLDER */
@@ -222,10 +230,11 @@ typedef struct spgxlogVacuumLeaf
 
 #define SizeOfSpgxlogVacuumLeaf offsetof(spgxlogVacuumLeaf, offsets)
 
-typedef struct spgxlogVacuumRoot
+typedef struct PG_NO_PADDING spgxlogVacuumRoot
 {
 	/* vacuum a root page when it is also a leaf */
 	uint16		nDelete;		/* number of tuples to delete */
+	pg_padding_2(pg_pad);
 
 	spgxlogState stateSrc;
 
@@ -235,13 +244,15 @@ typedef struct spgxlogVacuumRoot
 
 #define SizeOfSpgxlogVacuumRoot offsetof(spgxlogVacuumRoot, offsets)
 
-typedef struct spgxlogVacuumRedirect
+typedef struct PG_NO_PADDING spgxlogVacuumRedirect
 {
 	uint16		nToPlaceholder; /* number of redirects to make placeholders */
 	OffsetNumber firstPlaceholder;	/* first placeholder tuple to remove */
 	TransactionId snapshotConflictHorizon;	/* newest XID of removed redirects */
 	bool		isCatalogRel;	/* to handle recovery conflict during logical
 								 * decoding on standby */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 
 	/* offsets of redirect tuples to make placeholders follow */
 	OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index f0b4d795071..d9617b235bd 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -216,7 +216,7 @@ typedef struct SavedTransactionCharacteristics
 #define XactCompletionForceSyncCommit(xinfo) \
 	((xinfo & XACT_COMPLETION_FORCE_SYNC_COMMIT) != 0)
 
-typedef struct xl_xact_assignment
+typedef struct PG_NO_PADDING xl_xact_assignment
 {
 	TransactionId xtop;			/* assigned XID's top-level XID */
 	int			nsubxacts;		/* number of subtransaction XIDs */
@@ -242,7 +242,7 @@ typedef struct xl_xact_assignment
 
 /* sub-records for commit/abort */
 
-typedef struct xl_xact_xinfo
+typedef struct PG_NO_PADDING xl_xact_xinfo
 {
 	/*
 	 * Even though we right now only require two bytes of space in xinfo we
@@ -253,20 +253,20 @@ typedef struct xl_xact_xinfo
 	uint32		xinfo;
 } xl_xact_xinfo;
 
-typedef struct xl_xact_dbinfo
+typedef struct PG_NO_PADDING xl_xact_dbinfo
 {
 	Oid			dbId;			/* MyDatabaseId */
 	Oid			tsId;			/* MyDatabaseTableSpace */
 } xl_xact_dbinfo;
 
-typedef struct xl_xact_subxacts
+typedef struct PG_NO_PADDING xl_xact_subxacts
 {
 	int			nsubxacts;		/* number of subtransaction XIDs */
 	TransactionId subxacts[FLEXIBLE_ARRAY_MEMBER];
 } xl_xact_subxacts;
 #define MinSizeOfXactSubxacts offsetof(xl_xact_subxacts, subxacts)
 
-typedef struct xl_xact_relfilelocators
+typedef struct PG_NO_PADDING xl_xact_relfilelocators
 {
 	int			nrels;			/* number of relations */
 	RelFileLocator xlocators[FLEXIBLE_ARRAY_MEMBER];
@@ -280,7 +280,7 @@ typedef struct xl_xact_relfilelocators
  * frontend code, but the WAL format needs to be readable by frontend
  * programs.
  */
-typedef struct xl_xact_stats_item
+typedef struct PG_NO_PADDING xl_xact_stats_item
 {
 	int			kind;
 	Oid			dboid;
@@ -293,32 +293,32 @@ typedef struct xl_xact_stats_item
 	uint32		objid_hi;
 } xl_xact_stats_item;
 
-typedef struct xl_xact_stats_items
+typedef struct PG_NO_PADDING xl_xact_stats_items
 {
 	int			nitems;
 	xl_xact_stats_item items[FLEXIBLE_ARRAY_MEMBER];
 } xl_xact_stats_items;
 #define MinSizeOfXactStatsItems offsetof(xl_xact_stats_items, items)
 
-typedef struct xl_xact_invals
+typedef struct PG_NO_PADDING xl_xact_invals
 {
 	int			nmsgs;			/* number of shared inval msgs */
 	SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER];
 } xl_xact_invals;
 #define MinSizeOfXactInvals offsetof(xl_xact_invals, msgs)
 
-typedef struct xl_xact_twophase
+typedef struct PG_NO_PADDING xl_xact_twophase
 {
 	TransactionId xid;
 } xl_xact_twophase;
 
-typedef struct xl_xact_origin
+typedef struct PG_NO_PADDING xl_xact_origin
 {
 	XLogRecPtr	origin_lsn;
 	TimestampTz origin_timestamp;
 } xl_xact_origin;
 
-typedef struct xl_xact_commit
+typedef struct PG_NO_PADDING xl_xact_commit
 {
 	TimestampTz xact_time;		/* time of commit */
 
@@ -334,7 +334,7 @@ typedef struct xl_xact_commit
 } xl_xact_commit;
 #define MinSizeOfXactCommit (offsetof(xl_xact_commit, xact_time) + sizeof(TimestampTz))
 
-typedef struct xl_xact_abort
+typedef struct PG_NO_PADDING xl_xact_abort
 {
 	TimestampTz xact_time;		/* time of abort */
 
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index fbc5d77ab39..a8c07b20fe5 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -33,7 +33,7 @@
  */
 #define XLOG_PAGE_MAGIC 0xD11B	/* can be used as WAL version indicator */
 
-typedef struct XLogPageHeaderData
+typedef struct PG_NO_PADDING XLogPageHeaderData
 {
 	uint16		xlp_magic;		/* magic value for correctness checks */
 	uint16		xlp_info;		/* flag bits, see below */
@@ -47,6 +47,7 @@ typedef struct XLogPageHeaderData
 	 * header.  Note that the continuation data isn't necessarily aligned.
 	 */
 	uint32		xlp_rem_len;	/* total len of remaining data for record */
+	pg_padding_4(pg_pad);
 } XLogPageHeaderData;
 
 #define SizeOfXLogShortPHD	MAXALIGN(sizeof(XLogPageHeaderData))
@@ -58,7 +59,7 @@ typedef XLogPageHeaderData *XLogPageHeader;
  * page header.  (This is ordinarily done just in the first page of an
  * XLOG file.)	The additional fields serve to identify the file accurately.
  */
-typedef struct XLogLongPageHeaderData
+typedef struct PG_NO_PADDING XLogLongPageHeaderData
 {
 	XLogPageHeaderData std;		/* standard header fields */
 	uint64		xlp_sysid;		/* system identifier from pg_control */
@@ -270,7 +271,7 @@ BackupHistoryFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr
  * Information logged when we detect a change in one of the parameters
  * important for Hot Standby.
  */
-typedef struct xl_parameter_change
+typedef struct PG_NO_PADDING xl_parameter_change
 {
 	int			MaxConnections;
 	int			max_worker_processes;
@@ -280,29 +281,31 @@ typedef struct xl_parameter_change
 	int			wal_level;
 	bool		wal_log_hints;
 	bool		track_commit_timestamp;
+	pg_padding_2(pg_pad);
 } xl_parameter_change;
 
 /* logs restore point */
-typedef struct xl_restore_point
+typedef struct PG_NO_PADDING xl_restore_point
 {
 	TimestampTz rp_time;
 	char		rp_name[MAXFNAMELEN];
 } xl_restore_point;
 
 /* Overwrite of prior contrecord */
-typedef struct xl_overwrite_contrecord
+typedef struct PG_NO_PADDING xl_overwrite_contrecord
 {
 	XLogRecPtr	overwritten_lsn;
 	TimestampTz overwrite_time;
 } xl_overwrite_contrecord;
 
 /* End of recovery mark, when we don't do an END_OF_RECOVERY checkpoint */
-typedef struct xl_end_of_recovery
+typedef struct PG_NO_PADDING xl_end_of_recovery
 {
 	TimestampTz end_time;
 	TimeLineID	ThisTimeLineID; /* new TLI */
 	TimeLineID	PrevTimeLineID; /* previous TLI we forked off from */
 	int			wal_level;
+	pg_padding_4(pg_pad);
 } xl_end_of_recovery;
 
 /*
diff --git a/src/include/access/xlogrecord.h b/src/include/access/xlogrecord.h
index e8999d3fe91..8c74998607d 100644
--- a/src/include/access/xlogrecord.h
+++ b/src/include/access/xlogrecord.h
@@ -38,14 +38,14 @@
  * XLogRecordDataHeaderLong structs all begin with a single 'id' byte. It's
  * used to distinguish between block references, and the main data structs.
  */
-typedef struct XLogRecord
+typedef struct PG_NO_PADDING XLogRecord
 {
 	uint32		xl_tot_len;		/* total len of entire record */
 	TransactionId xl_xid;		/* xact id */
 	XLogRecPtr	xl_prev;		/* ptr to previous record in log */
 	uint8		xl_info;		/* flag bits, see below */
 	RmgrId		xl_rmid;		/* resource manager for this record */
-	/* 2 bytes of padding here, initialize to zero */
+	pg_padding_2(pg_pad);
 	pg_crc32c	xl_crc;			/* CRC for this record */
 
 	/* XLogRecordBlockHeaders and XLogRecordDataHeader follow, no padding */
@@ -100,7 +100,7 @@ typedef struct XLogRecord
  * Note that we don't attempt to align the XLogRecordBlockHeader struct!
  * So, the struct must be copied to aligned local storage before use.
  */
-typedef struct XLogRecordBlockHeader
+typedef struct PG_NO_PADDING XLogRecordBlockHeader
 {
 	uint8		id;				/* block reference ID */
 	uint8		fork_flags;		/* fork within the relation, and flags */
@@ -112,7 +112,7 @@ typedef struct XLogRecordBlockHeader
 	/* BlockNumber follows */
 } XLogRecordBlockHeader;
 
-#define SizeOfXLogRecordBlockHeader (offsetof(XLogRecordBlockHeader, data_length) + sizeof(uint16))
+#define SizeOfXLogRecordBlockHeader (sizeof(XLogRecordBlockHeader))
 
 /*
  * Additional header information when a full-page image is included
@@ -138,11 +138,12 @@ typedef struct XLogRecordBlockHeader
  * compressed, the amount of block data actually present is less than
  * BLCKSZ - the length of "hole" bytes - the length of extra information.
  */
-typedef struct XLogRecordBlockImageHeader
+typedef struct PG_NO_PADDING XLogRecordBlockImageHeader
 {
 	uint16		length;			/* number of page image bytes */
 	uint16		hole_offset;	/* number of bytes before "hole" */
 	uint8		bimg_info;		/* flag bits, see below */
+	pg_padding_1(pg_pad);
 
 	/*
 	 * If BKPIMAGE_HAS_HOLE and BKPIMAGE_COMPRESSED(), an
@@ -151,7 +152,7 @@ typedef struct XLogRecordBlockImageHeader
 } XLogRecordBlockImageHeader;
 
 #define SizeOfXLogRecordBlockImageHeader	\
-	(offsetof(XLogRecordBlockImageHeader, bimg_info) + sizeof(uint8))
+	(sizeof(XLogRecordBlockImageHeader))
 
 /* Information stored in bimg_info */
 #define BKPIMAGE_HAS_HOLE		0x01	/* page image has "hole" */
@@ -170,7 +171,7 @@ typedef struct XLogRecordBlockImageHeader
  * Extra header information used when page image has "hole" and
  * is compressed.
  */
-typedef struct XLogRecordBlockCompressHeader
+typedef struct PG_NO_PADDING XLogRecordBlockCompressHeader
 {
 	uint16		hole_length;	/* number of bytes in "hole" */
 } XLogRecordBlockCompressHeader;
@@ -210,7 +211,7 @@ typedef struct XLogRecordBlockCompressHeader
  * (These structs are currently not used in the code, they are here just for
  * documentation purposes).
  */
-typedef struct XLogRecordDataHeaderShort
+typedef struct PG_NO_PADDING XLogRecordDataHeaderShort
 {
 	uint8		id;				/* XLR_BLOCK_ID_DATA_SHORT */
 	uint8		data_length;	/* number of payload bytes */
@@ -218,7 +219,7 @@ typedef struct XLogRecordDataHeaderShort
 
 #define SizeOfXLogRecordDataHeaderShort (sizeof(uint8) * 2)
 
-typedef struct XLogRecordDataHeaderLong
+typedef struct PG_NO_PADDING XLogRecordDataHeaderLong
 {
 	uint8		id;				/* XLR_BLOCK_ID_DATA_LONG */
 	/* followed by uint32 data_length, unaligned */
diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h
index 7503db1af51..9e745b14177 100644
--- a/src/include/catalog/pg_control.h
+++ b/src/include/catalog/pg_control.h
@@ -32,7 +32,7 @@
  * a copy of the latest one in pg_control for possible disaster recovery.
  * Changing this struct requires a PG_CONTROL_VERSION bump.
  */
-typedef struct CheckPoint
+typedef struct PG_NO_PADDING CheckPoint
 {
 	XLogRecPtr	redo;			/* next RecPtr available when we began to
 								 * create CheckPoint (i.e. REDO start point) */
@@ -40,8 +40,13 @@ typedef struct CheckPoint
 	TimeLineID	PrevTimeLineID; /* previous TLI, if this record begins a new
 								 * timeline (equals ThisTimeLineID otherwise) */
 	bool		fullPageWrites; /* current full_page_writes */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 	int			wal_level;		/* current wal_level */
 	bool		logicalDecodingEnabled; /* current logical decoding status */
+	pg_padding_1(pg_pad3);
+	pg_padding_2(pg_pad4);
+	pg_padding_4(pg_pad5);
 	FullTransactionId nextXid;	/* next free transaction ID */
 	Oid			nextOid;		/* next free OID */
 	MultiXactId nextMulti;		/* next free MultiXactId */
@@ -63,6 +68,7 @@ typedef struct CheckPoint
 	 * set to InvalidTransactionId.
 	 */
 	TransactionId oldestActiveXid;
+	pg_padding_4(pg_pad6);
 } CheckPoint;
 
 /* XLOG info values for XLOG rmgr */
diff --git a/src/include/catalog/storage_xlog.h b/src/include/catalog/storage_xlog.h
index c1b2f736669..89b1bfeef6e 100644
--- a/src/include/catalog/storage_xlog.h
+++ b/src/include/catalog/storage_xlog.h
@@ -30,7 +30,7 @@
 #define XLOG_SMGR_CREATE	0x10
 #define XLOG_SMGR_TRUNCATE	0x20
 
-typedef struct xl_smgr_create
+typedef struct PG_NO_PADDING xl_smgr_create
 {
 	RelFileLocator rlocator;
 	ForkNumber	forkNum;
@@ -43,7 +43,7 @@ typedef struct xl_smgr_create
 #define SMGR_TRUNCATE_ALL		\
 	(SMGR_TRUNCATE_HEAP|SMGR_TRUNCATE_VM|SMGR_TRUNCATE_FSM)
 
-typedef struct xl_smgr_truncate
+typedef struct PG_NO_PADDING xl_smgr_truncate
 {
 	BlockNumber blkno;
 	RelFileLocator rlocator;
diff --git a/src/include/commands/dbcommands_xlog.h b/src/include/commands/dbcommands_xlog.h
index 4ff3d0c82c9..04c4f35c160 100644
--- a/src/include/commands/dbcommands_xlog.h
+++ b/src/include/commands/dbcommands_xlog.h
@@ -26,7 +26,7 @@
  * Single WAL record for an entire CREATE DATABASE operation. This is used
  * by the FILE_COPY strategy.
  */
-typedef struct xl_dbase_create_file_copy_rec
+typedef struct PG_NO_PADDING xl_dbase_create_file_copy_rec
 {
 	Oid			db_id;
 	Oid			tablespace_id;
@@ -39,13 +39,13 @@ typedef struct xl_dbase_create_file_copy_rec
  * WAL_LOG strategy is used. Each individual block will be logged separately
  * afterward.
  */
-typedef struct xl_dbase_create_wal_log_rec
+typedef struct PG_NO_PADDING xl_dbase_create_wal_log_rec
 {
 	Oid			db_id;
 	Oid			tablespace_id;
 } xl_dbase_create_wal_log_rec;
 
-typedef struct xl_dbase_drop_rec
+typedef struct PG_NO_PADDING xl_dbase_drop_rec
 {
 	Oid			db_id;
 	int			ntablespaces;	/* number of tablespace IDs */
diff --git a/src/include/commands/sequence_xlog.h b/src/include/commands/sequence_xlog.h
index b0495f41b43..81685f6bf04 100644
--- a/src/include/commands/sequence_xlog.h
+++ b/src/include/commands/sequence_xlog.h
@@ -31,7 +31,7 @@ typedef struct sequence_magic
 } sequence_magic;
 
 /* Sequence WAL record */
-typedef struct xl_seq_rec
+typedef struct PG_NO_PADDING xl_seq_rec
 {
 	RelFileLocator locator;
 	/* SEQUENCE TUPLE DATA FOLLOWS AT THE END */
diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h
index 4fa85c2906b..f4e0be425ba 100644
--- a/src/include/commands/tablespace.h
+++ b/src/include/commands/tablespace.h
@@ -27,13 +27,13 @@ extern PGDLLIMPORT bool allow_in_place_tablespaces;
 #define XLOG_TBLSPC_CREATE		0x00
 #define XLOG_TBLSPC_DROP		0x10
 
-typedef struct xl_tblspc_create_rec
+typedef struct PG_NO_PADDING xl_tblspc_create_rec
 {
 	Oid			ts_id;
 	char		ts_path[FLEXIBLE_ARRAY_MEMBER]; /* null-terminated string */
 } xl_tblspc_create_rec;
 
-typedef struct xl_tblspc_drop_rec
+typedef struct PG_NO_PADDING xl_tblspc_drop_rec
 {
 	Oid			ts_id;
 } xl_tblspc_drop_rec;
diff --git a/src/include/replication/message.h b/src/include/replication/message.h
index d1c72755084..574ae407406 100644
--- a/src/include/replication/message.h
+++ b/src/include/replication/message.h
@@ -17,10 +17,12 @@
 /*
  * Generic logical decoding message wal record.
  */
-typedef struct xl_logical_message
+typedef struct PG_NO_PADDING xl_logical_message
 {
 	Oid			dbId;			/* database Oid emitted from */
 	bool		transactional;	/* is message transactional? */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 	Size		prefix_size;	/* length of prefix */
 	Size		message_size;	/* size of the message */
 	/* payload, including null-terminated prefix of length prefix_size */
diff --git a/src/include/replication/origin.h b/src/include/replication/origin.h
index eb46b41b4b7..f7c7ee58bd9 100644
--- a/src/include/replication/origin.h
+++ b/src/include/replication/origin.h
@@ -15,14 +15,16 @@
 #include "access/xlogreader.h"
 #include "catalog/pg_replication_origin.h"
 
-typedef struct xl_replorigin_set
+typedef struct PG_NO_PADDING xl_replorigin_set
 {
 	XLogRecPtr	remote_lsn;
 	ReplOriginId node_id;
 	bool		force;
+	pg_padding_1(pg_pad1);
+	pg_padding_4(pg_pad2);
 } xl_replorigin_set;
 
-typedef struct xl_replorigin_drop
+typedef struct PG_NO_PADDING xl_replorigin_drop
 {
 	ReplOriginId node_id;
 } xl_replorigin_drop;
diff --git a/src/include/storage/lockdefs.h b/src/include/storage/lockdefs.h
index b73bb5618e6..ea95983f1e2 100644
--- a/src/include/storage/lockdefs.h
+++ b/src/include/storage/lockdefs.h
@@ -51,7 +51,7 @@ typedef int LOCKMODE;
 #define InplaceUpdateTupleLock ExclusiveLock
 
 /* WAL representation of an AccessExclusiveLock on a table */
-typedef struct xl_standby_lock
+typedef struct PG_NO_PADDING xl_standby_lock
 {
 	TransactionId xid;			/* xid of holder of AccessExclusiveLock */
 	Oid			dbOid;			/* DB containing table */
diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h
index 4d33fdcabe1..d66a095f0ea 100644
--- a/src/include/storage/sinval.h
+++ b/src/include/storage/sinval.h
@@ -58,34 +58,40 @@
  * sent immediately when the underlying file change is made.
  */
 
-typedef struct
+typedef struct SharedInvalCatcacheMsg
 {
 	int8		id;				/* cache ID --- must be first */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 	Oid			dbId;			/* database ID, or 0 if a shared relation */
 	uint32		hashValue;		/* hash value of key for this catcache */
 } SharedInvalCatcacheMsg;
 
 #define SHAREDINVALCATALOG_ID	(-1)
 
-typedef struct
+typedef struct SharedInvalCatalogMsg
 {
 	int8		id;				/* type field --- must be first */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 	Oid			dbId;			/* database ID, or 0 if a shared catalog */
 	Oid			catId;			/* ID of catalog whose contents are invalid */
 } SharedInvalCatalogMsg;
 
 #define SHAREDINVALRELCACHE_ID	(-2)
 
-typedef struct
+typedef struct SharedInvalRelcacheMsg
 {
 	int8		id;				/* type field --- must be first */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 	Oid			dbId;			/* database ID, or 0 if a shared relation */
 	Oid			relId;			/* relation ID, or 0 if whole relcache */
 } SharedInvalRelcacheMsg;
 
 #define SHAREDINVALSMGR_ID		(-3)
 
-typedef struct
+typedef struct SharedInvalSmgrMsg
 {
 	/* note: field layout chosen to pack into 16 bytes */
 	int8		id;				/* type field --- must be first */
@@ -96,32 +102,38 @@ typedef struct
 
 #define SHAREDINVALRELMAP_ID	(-4)
 
-typedef struct
+typedef struct SharedInvalRelmapMsg
 {
 	int8		id;				/* type field --- must be first */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 	Oid			dbId;			/* database ID, or 0 for shared catalogs */
 } SharedInvalRelmapMsg;
 
 #define SHAREDINVALSNAPSHOT_ID	(-5)
 
-typedef struct
+typedef struct SharedInvalSnapshotMsg
 {
 	int8		id;				/* type field --- must be first */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 	Oid			dbId;			/* database ID, or 0 if a shared relation */
 	Oid			relId;			/* relation ID */
 } SharedInvalSnapshotMsg;
 
 #define SHAREDINVALRELSYNC_ID	(-6)
 
-typedef struct
+typedef struct SharedInvalRelSyncMsg
 {
 	int8		id;				/* type field --- must be first */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 	Oid			dbId;			/* database ID */
 	Oid			relid;			/* relation ID, or 0 if whole
 								 * RelationSyncCache */
 } SharedInvalRelSyncMsg;
 
-typedef union
+typedef union SharedInvalidationMessage
 {
 	int8		id;				/* type field --- must be first */
 	SharedInvalCatcacheMsg cc;
diff --git a/src/include/storage/standbydefs.h b/src/include/storage/standbydefs.h
index 231d251fd51..c1053cbdf22 100644
--- a/src/include/storage/standbydefs.h
+++ b/src/include/storage/standbydefs.h
@@ -35,7 +35,7 @@ extern void standby_desc_invalidations(StringInfo buf,
 #define XLOG_RUNNING_XACTS			0x10
 #define XLOG_INVALIDATIONS			0x20
 
-typedef struct xl_standby_locks
+typedef struct PG_NO_PADDING xl_standby_locks
 {
 	int			nlocks;			/* number of entries in locks array */
 	xl_standby_lock locks[FLEXIBLE_ARRAY_MEMBER];
@@ -44,11 +44,13 @@ typedef struct xl_standby_locks
 /*
  * When we write running xact data to WAL, we use this structure.
  */
-typedef struct xl_running_xacts
+typedef struct PG_NO_PADDING xl_running_xacts
 {
 	int			xcnt;			/* # of xact ids in xids[] */
 	int			subxcnt;		/* # of subxact ids in xids[] */
 	bool		subxid_overflow;	/* snapshot overflowed, subxids missing */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 	TransactionId nextXid;		/* xid from TransamVariables->nextXid */
 	TransactionId oldestRunningXid; /* *not* oldestXmin */
 	TransactionId latestCompletedXid;	/* so we can set xmax */
@@ -60,11 +62,13 @@ typedef struct xl_running_xacts
  * Invalidations for standby, currently only when transactions without an
  * assigned xid commit.
  */
-typedef struct xl_invalidations
+typedef struct PG_NO_PADDING xl_invalidations
 {
 	Oid			dbId;			/* MyDatabaseId */
 	Oid			tsId;			/* MyDatabaseTableSpace */
 	bool		relcacheInitFileInval;	/* invalidate relcache init files */
+	pg_padding_1(pg_pad1);
+	pg_padding_2(pg_pad2);
 	int			nmsgs;			/* number of shared inval msgs */
 	SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER];
 } xl_invalidations;
diff --git a/src/include/utils/relmapper.h b/src/include/utils/relmapper.h
index aa9226edac3..e60f495d5d4 100644
--- a/src/include/utils/relmapper.h
+++ b/src/include/utils/relmapper.h
@@ -24,7 +24,7 @@
 
 #define XLOG_RELMAP_UPDATE		0x00
 
-typedef struct xl_relmap_update
+typedef struct PG_NO_PADDING xl_relmap_update
 {
 	Oid			dbid;			/* database ID, or 0 for shared map */
 	Oid			tsid;			/* database's tablespace, or pg_global */
diff --git a/src/test/modules/test_custom_rmgrs/test_custom_rmgrs.c b/src/test/modules/test_custom_rmgrs/test_custom_rmgrs.c
index 6333661e437..2cd2ee0de14 100644
--- a/src/test/modules/test_custom_rmgrs/test_custom_rmgrs.c
+++ b/src/test/modules/test_custom_rmgrs/test_custom_rmgrs.c
@@ -29,7 +29,7 @@ PG_MODULE_MAGIC;
 /*
  * test_custom_rmgrs WAL record message.
  */
-typedef struct xl_testcustomrmgrs_message
+typedef struct PG_NO_PADDING xl_testcustomrmgrs_message
 {
 	Size		message_size;	/* size of the message */
 	char		message[FLEXIBLE_ARRAY_MEMBER]; /* payload */
diff --git a/src/test/recovery/t/039_end_of_wal.pl b/src/test/recovery/t/039_end_of_wal.pl
index f46d089a0fb..766e660988e 100644
--- a/src/test/recovery/t/039_end_of_wal.pl
+++ b/src/test/recovery/t/039_end_of_wal.pl
@@ -100,10 +100,11 @@ sub build_page_header
 	# I for xlp_tli
 	# II for xlp_pageaddr
 	# I for xlp_rem_len
-	return pack("SSIIII",
+	# I for pg_pad
+	return pack("SSIIIII",
 		$xlp_magic, $xlp_info, $xlp_tli,
 		$BIG_ENDIAN ? 0             : $xlp_pageaddr,
-		$BIG_ENDIAN ? $xlp_pageaddr : 0, $xlp_rem_len);
+		$BIG_ENDIAN ? $xlp_pageaddr : 0, $xlp_rem_len, 0);
 }
 
 # Setup a new node.  The configuration chosen here minimizes the number
-- 
2.43.0

