diff --git a/config/c-library.m4 b/config/c-library.m4
index 1e3997bb1cc21903f73ea6d666f40db1c116af0a..8f45010593729f1b3cdad19b219776e65658fb50 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -273,16 +273,16 @@ case $pgac_cv_snprintf_long_long_int_format in
 esac])# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT
 
 
-# PGAC_FUNC_PRINTF_ARG_CONTROL
+# PGAC_FUNC_SNPRINTF_ARG_CONTROL
 # ---------------------------------------
-# Determine if printf supports %1$ argument selection, e.g. %5$ selects
-# the fifth argument after the printf print string.
+# Determine if snprintf supports %1$ argument selection, e.g. %5$ selects
+# the fifth argument after the printf format string.
 # This is not in the C99 standard, but in the Single Unix Specification (SUS).
 # It is used in our language translation strings.
 #
-AC_DEFUN([PGAC_FUNC_PRINTF_ARG_CONTROL],
-[AC_MSG_CHECKING([whether printf supports argument control])
-AC_CACHE_VAL(pgac_cv_printf_arg_control,
+AC_DEFUN([PGAC_FUNC_SNPRINTF_ARG_CONTROL],
+[AC_MSG_CHECKING([whether snprintf supports argument control])
+AC_CACHE_VAL(pgac_cv_snprintf_arg_control,
 [AC_TRY_RUN([#include <stdio.h>
 #include <string.h>
 
@@ -296,12 +296,48 @@ int main()
     return 1;
   return 0;
 }],
-[pgac_cv_printf_arg_control=yes],
-[pgac_cv_printf_arg_control=no],
-[pgac_cv_printf_arg_control=cross])
+[pgac_cv_snprintf_arg_control=yes],
+[pgac_cv_snprintf_arg_control=no],
+[pgac_cv_snprintf_arg_control=cross])
 ])dnl AC_CACHE_VAL
-AC_MSG_RESULT([$pgac_cv_printf_arg_control])
-])# PGAC_FUNC_PRINTF_ARG_CONTROL
+AC_MSG_RESULT([$pgac_cv_snprintf_arg_control])
+])# PGAC_FUNC_SNPRINTF_ARG_CONTROL
+
+# PGAC_FUNC_SNPRINTF_SIZE_T_SUPPORT
+# ---------------------------------------
+# Determine if snprintf supports the z length modifier for printing
+# size_t-sized variables. That's supported by C99 and POSIX but not
+# all platforms play ball, so we must test whether it's working.
+#
+AC_DEFUN([PGAC_FUNC_SNPRINTF_SIZE_T_SUPPORT],
+[AC_MSG_CHECKING([whether snprintf supports the %z modifier])
+AC_CACHE_VAL(pgac_cv_snprintf_size_t_support,
+[AC_TRY_RUN([#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+  char bufz[100];
+  char buf64[100];
+
+  /*
+   * Print the largest unsigned number fitting in a size_t using both %zu
+   * and the previously-determined format for 64-bit integers.  Note that
+   * we don't run this code unless we know snprintf handles 64-bit ints.
+   */
+  bufz[0] = '\0';  /* in case snprintf fails to emit anything */
+  snprintf(bufz, sizeof(bufz), "%zu", ~((size_t) 0));
+  snprintf(buf64, sizeof(buf64), UINT64_FORMAT, (PG_INT64_TYPE) ~((size_t) 0));
+  if (strcmp(bufz, buf64) != 0)
+    return 1;
+  return 0;
+}],
+[pgac_cv_snprintf_size_t_support=yes],
+[pgac_cv_snprintf_size_t_support=no],
+[pgac_cv_snprintf_size_t_support=cross])
+])dnl AC_CACHE_VAL
+AC_MSG_RESULT([$pgac_cv_snprintf_size_t_support])
+])# PGAC_FUNC_SNPRINTF_SIZE_T_SUPPORT
 
 
 # PGAC_TYPE_LOCALE_T
diff --git a/configure b/configure
index e1ff704ca572fa1d9c9c033c11961ef4b834687f..6ad165f3abb0639ad682ee81d5a754a49a47b664 100755
--- a/configure
+++ b/configure
@@ -12698,13 +12698,13 @@ fi
 # Force use of our snprintf if system's doesn't do arg control
 # See comment above at snprintf test for details.
 if test "$enable_nls" = yes -a "$pgac_need_repl_snprintf" = no; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether printf supports argument control" >&5
-$as_echo_n "checking whether printf supports argument control... " >&6; }
-if ${pgac_cv_printf_arg_control+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether snprintf supports argument control" >&5
+$as_echo_n "checking whether snprintf supports argument control... " >&6; }
+if ${pgac_cv_snprintf_arg_control+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
-  pgac_cv_printf_arg_control=cross
+  pgac_cv_snprintf_arg_control=cross
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -12723,9 +12723,9 @@ int main()
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
-  pgac_cv_printf_arg_control=yes
+  pgac_cv_snprintf_arg_control=yes
 else
-  pgac_cv_printf_arg_control=no
+  pgac_cv_snprintf_arg_control=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
@@ -12733,10 +12733,10 @@ fi
 
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_printf_arg_control" >&5
-$as_echo "$pgac_cv_printf_arg_control" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_snprintf_arg_control" >&5
+$as_echo "$pgac_cv_snprintf_arg_control" >&6; }
 
-  if test $pgac_cv_printf_arg_control != yes ; then
+  if test $pgac_cv_snprintf_arg_control != yes ; then
     pgac_need_repl_snprintf=yes
   fi
 fi
@@ -13036,6 +13036,58 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+# Also force use of our snprintf if the system's doesn't support the %z flag.
+if test "$pgac_need_repl_snprintf" = no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether snprintf supports the %z modifier" >&5
+$as_echo_n "checking whether snprintf supports the %z modifier... " >&6; }
+if ${pgac_cv_snprintf_size_t_support+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  pgac_cv_snprintf_size_t_support=cross
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+  char bufz[100];
+  char buf64[100];
+
+  /*
+   * Print the largest unsigned number fitting in a size_t using both %zu
+   * and the previously-determined format for 64-bit integers.  Note that
+   * we don't run this code unless we know snprintf handles 64-bit ints.
+   */
+  bufz[0] = '\0';  /* in case snprintf fails to emit anything */
+  snprintf(bufz, sizeof(bufz), "%zu", ~((size_t) 0));
+  snprintf(buf64, sizeof(buf64), UINT64_FORMAT, (PG_INT64_TYPE) ~((size_t) 0));
+  if (strcmp(bufz, buf64) != 0)
+    return 1;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  pgac_cv_snprintf_size_t_support=yes
+else
+  pgac_cv_snprintf_size_t_support=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_snprintf_size_t_support" >&5
+$as_echo "$pgac_cv_snprintf_size_t_support" >&6; }
+
+  if test "$pgac_cv_snprintf_size_t_support" != yes; then
+    pgac_need_repl_snprintf=yes
+  fi
+fi
+
 # Now we have checked all the reasons to replace snprintf
 if test $pgac_need_repl_snprintf = yes; then
 
diff --git a/configure.in b/configure.in
index 3826237410f3ae3139cc8929442696c49303b6b4..aa23f9b8a0fd0356c6c92807643f267b2f19641a 100644
--- a/configure.in
+++ b/configure.in
@@ -1533,8 +1533,8 @@ for the exact reason.]])],
 # Force use of our snprintf if system's doesn't do arg control
 # See comment above at snprintf test for details.
 if test "$enable_nls" = yes -a "$pgac_need_repl_snprintf" = no; then
-  PGAC_FUNC_PRINTF_ARG_CONTROL
-  if test $pgac_cv_printf_arg_control != yes ; then
+  PGAC_FUNC_SNPRINTF_ARG_CONTROL
+  if test $pgac_cv_snprintf_arg_control != yes ; then
     pgac_need_repl_snprintf=yes
   fi
 fi
@@ -1617,6 +1617,14 @@ AC_DEFINE_UNQUOTED(INT64_FORMAT, $INT64_FORMAT,
 AC_DEFINE_UNQUOTED(UINT64_FORMAT, $UINT64_FORMAT,
                    [Define to the appropriate snprintf format for unsigned 64-bit ints.])
 
+# Also force use of our snprintf if the system's doesn't support the %z flag.
+if test "$pgac_need_repl_snprintf" = no; then
+  PGAC_FUNC_SNPRINTF_SIZE_T_SUPPORT
+  if test "$pgac_cv_snprintf_size_t_support" != yes; then
+    pgac_need_repl_snprintf=yes
+  fi
+fi
+
 # Now we have checked all the reasons to replace snprintf
 if test $pgac_need_repl_snprintf = yes; then
   AC_DEFINE(USE_REPL_SNPRINTF, 1, [Use replacement snprintf() functions.])
diff --git a/src/backend/access/common/indextuple.c b/src/backend/access/common/indextuple.c
index 840a2924b0a34d74c27114787e8df6c725aa21db..b4c68e9fe27719118f14accb95a3e673bd01b596 100644
--- a/src/backend/access/common/indextuple.c
+++ b/src/backend/access/common/indextuple.c
@@ -165,9 +165,8 @@ index_form_tuple(TupleDesc tupleDescriptor,
 	if ((size & INDEX_SIZE_MASK) != size)
 		ereport(ERROR,
 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-				 errmsg("index row requires %lu bytes, maximum size is %lu",
-						(unsigned long) size,
-						(unsigned long) INDEX_SIZE_MASK)));
+				 errmsg("index row requires %zu bytes, maximum size is %zu",
+						size, (Size) INDEX_SIZE_MASK)));
 
 	infomask |= size;
 
diff --git a/src/backend/access/gin/ginentrypage.c b/src/backend/access/gin/ginentrypage.c
index d5aa243a65931cca905a3b6ced1ea56d1198f41e..5c7893419d4c311fd3b6d218dcdd1eeaa7c9980e 100644
--- a/src/backend/access/gin/ginentrypage.c
+++ b/src/backend/access/gin/ginentrypage.c
@@ -105,9 +105,8 @@ GinFormTuple(GinState *ginstate,
 		if (errorTooBig)
 			ereport(ERROR,
 					(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-			errmsg("index row size %lu exceeds maximum %lu for index \"%s\"",
-				   (unsigned long) newsize,
-				   (unsigned long) GinMaxItemSize,
+			errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",
+				   (Size) newsize, (Size) GinMaxItemSize,
 				   RelationGetRelationName(ginstate->index))));
 		pfree(itup);
 		return NULL;
diff --git a/src/backend/access/hash/hashinsert.c b/src/backend/access/hash/hashinsert.c
index 090db0bdf8b656d0a0e52c58537dce414250f80b..49211eef9a3cd4f8e7ecd83d1e5a4e222afa579a 100644
--- a/src/backend/access/hash/hashinsert.c
+++ b/src/backend/access/hash/hashinsert.c
@@ -65,9 +65,8 @@ _hash_doinsert(Relation rel, IndexTuple itup)
 	if (itemsz > HashMaxItemSize((Page) metap))
 		ereport(ERROR,
 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-				 errmsg("index row size %lu exceeds hash maximum %lu",
-						(unsigned long) itemsz,
-						(unsigned long) HashMaxItemSize((Page) metap)),
+				 errmsg("index row size %zu exceeds hash maximum %zu",
+						itemsz, HashMaxItemSize((Page) metap)),
 			errhint("Values larger than a buffer page cannot be indexed.")));
 
 	/*
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index a0a97784f1cbb381cca7798caf3195dba29086df..b306398aec1ce5b10ad02967e6f145a8dd9af066 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -237,9 +237,8 @@ RelationGetBufferForTuple(Relation relation, Size len,
 	if (len > MaxHeapTupleSize)
 		ereport(ERROR,
 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-				 errmsg("row is too big: size %lu, maximum size %lu",
-						(unsigned long) len,
-						(unsigned long) MaxHeapTupleSize)));
+				 errmsg("row is too big: size %zu, maximum size %zu",
+						len, MaxHeapTupleSize)));
 
 	/* Compute desired extra freespace due to fillfactor option */
 	saveFreeSpace = RelationGetTargetPageFreeSpace(relation,
@@ -477,7 +476,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
 	if (len > PageGetHeapFreeSpace(page))
 	{
 		/* We should not get here given the test at the top */
-		elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
+		elog(PANIC, "tuple is too big: size %zu", len);
 	}
 
 	/*
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index bb719c76947adc3808d290032558b1c11e70f1d0..c34ab9865f8e7cf3e134d8e341c8edb36021d9f4 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -601,9 +601,8 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
 	if (len > MaxHeapTupleSize)
 		ereport(ERROR,
 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-				 errmsg("row is too big: size %lu, maximum size %lu",
-						(unsigned long) len,
-						(unsigned long) MaxHeapTupleSize)));
+				 errmsg("row is too big: size %zu, maximum size %zu",
+						len, MaxHeapTupleSize)));
 
 	/* Compute desired extra freespace due to fillfactor option */
 	saveFreeSpace = RelationGetTargetPageFreeSpace(state->rs_new_rel,
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index 11d930bd8da0b709721388c5cc56291b74dbedbd..49c084a5abeb23297c99c0dda0a58b2bc6d81a59 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -537,9 +537,8 @@ _bt_findinsertloc(Relation rel,
 	if (itemsz > BTMaxItemSize(page))
 		ereport(ERROR,
 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-			errmsg("index row size %lu exceeds maximum %lu for index \"%s\"",
-				   (unsigned long) itemsz,
-				   (unsigned long) BTMaxItemSize(page),
+			errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",
+				   itemsz, BTMaxItemSize(page),
 				   RelationGetRelationName(rel)),
 		errhint("Values larger than 1/3 of a buffer page cannot be indexed.\n"
 				"Consider a function index of an MD5 hash of the value, "
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index 504eb716006fb5a0e95c5105a48452f278af4c40..9ddc27549979248ea39bf1438dc2c40f635c8f38 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -482,9 +482,8 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
 	if (itupsz > BTMaxItemSize(npage))
 		ereport(ERROR,
 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-			errmsg("index row size %lu exceeds maximum %lu for index \"%s\"",
-				   (unsigned long) itupsz,
-				   (unsigned long) BTMaxItemSize(npage),
+			errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",
+				   itupsz, BTMaxItemSize(npage),
 				   RelationGetRelationName(wstate->index)),
 		errhint("Values larger than 1/3 of a buffer page cannot be indexed.\n"
 				"Consider a function index of an MD5 hash of the value, "
diff --git a/src/backend/access/spgist/spgdoinsert.c b/src/backend/access/spgist/spgdoinsert.c
index 2f6a8781b1e8a7ecb9b01a6407b8fb9dcdffb812..1f5d97694db196e461ef53556dcb1bf9a556ca08 100644
--- a/src/backend/access/spgist/spgdoinsert.c
+++ b/src/backend/access/spgist/spgdoinsert.c
@@ -1885,9 +1885,9 @@ spgdoinsert(Relation index, SpGistState *state,
 	if (leafSize > SPGIST_PAGE_CAPACITY && !state->config.longValuesOK)
 		ereport(ERROR,
 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-			errmsg("index row size %lu exceeds maximum %lu for index \"%s\"",
-				   (unsigned long) (leafSize - sizeof(ItemIdData)),
-				 (unsigned long) (SPGIST_PAGE_CAPACITY - sizeof(ItemIdData)),
+			errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",
+				   leafSize - sizeof(ItemIdData),
+				   SPGIST_PAGE_CAPACITY - sizeof(ItemIdData),
 				   RelationGetRelationName(index)),
 			errhint("Values larger than a buffer page cannot be indexed.")));
 
diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c
index 1754f05aea4a9ffe58925ef91281fb9ab0b73a35..3cbad99e46ad7b5df82892370a15d7407acf0abe 100644
--- a/src/backend/access/spgist/spgutils.c
+++ b/src/backend/access/spgist/spgutils.c
@@ -602,9 +602,8 @@ spgFormNodeTuple(SpGistState *state, Datum label, bool isnull)
 	if ((size & INDEX_SIZE_MASK) != size)
 		ereport(ERROR,
 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-				 errmsg("index row requires %lu bytes, maximum size is %lu",
-						(unsigned long) size,
-						(unsigned long) INDEX_SIZE_MASK)));
+				 errmsg("index row requires %zu bytes, maximum size is %zu",
+						(Size) size, (Size) INDEX_SIZE_MASK)));
 
 	tup = (SpGistNodeTuple) palloc0(size);
 
@@ -661,9 +660,9 @@ spgFormInnerTuple(SpGistState *state, bool hasPrefix, Datum prefix,
 	if (size > SPGIST_PAGE_CAPACITY - sizeof(ItemIdData))
 		ereport(ERROR,
 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-				 errmsg("SP-GiST inner tuple size %lu exceeds maximum %lu",
-						(unsigned long) size,
-				(unsigned long) (SPGIST_PAGE_CAPACITY - sizeof(ItemIdData))),
+				 errmsg("SP-GiST inner tuple size %zu exceeds maximum %zu",
+						(Size) size,
+						SPGIST_PAGE_CAPACITY - sizeof(ItemIdData)),
 			errhint("Values larger than a buffer page cannot be indexed.")));
 
 	/*
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 8679d0aa7f4755aa5fb5872382a6eff9399dd844..9559d6d6aef93fcce6c2b7011568af61c9fed2f5 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2738,9 +2738,9 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
 					ereport(PANIC,
 							(errcode_for_file_access(),
 							 errmsg("could not write to log file %s "
-									"at offset %u, length %lu: %m",
+									"at offset %u, length %zu: %m",
 									XLogFileNameP(ThisTimeLineID, openLogSegNo),
-									openLogOff, (unsigned long) nbytes)));
+									openLogOff, nbytes)));
 				}
 				nleft -= written;
 				from += written;
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index c22acd5d271da00e714e7169c18d2ba981c3a0cd..216d75e8d1a453520c4a1e6b3e27be6766c0d517 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -1439,15 +1439,13 @@ readDatum(bool typbyval)
 
 	token = pg_strtok(&tokenLength);	/* read the '[' */
 	if (token == NULL || token[0] != '[')
-		elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %lu",
-			 token ? (const char *) token : "[NULL]",
-			 (unsigned long) length);
+		elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu",
+			 token ? (const char *) token : "[NULL]", length);
 
 	if (typbyval)
 	{
 		if (length > (Size) sizeof(Datum))
-			elog(ERROR, "byval datum but length = %lu",
-				 (unsigned long) length);
+			elog(ERROR, "byval datum but length = %zu", length);
 		res = (Datum) 0;
 		s = (char *) (&res);
 		for (i = 0; i < (Size) sizeof(Datum); i++)
@@ -1471,9 +1469,8 @@ readDatum(bool typbyval)
 
 	token = pg_strtok(&tokenLength);	/* read the ']' */
 	if (token == NULL || token[0] != ']')
-		elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %lu",
-			 token ? (const char *) token : "[NULL]",
-			 (unsigned long) length);
+		elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu",
+			 token ? (const char *) token : "[NULL]", length);
 
 	return res;
 }
diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c
index 36674ad1e74ef3f192e08b6a6848130b0f786fbf..0d01617e2f5eccb3476d8aba2f7e38f6a4af65d6 100644
--- a/src/backend/port/sysv_shmem.c
+++ b/src/backend/port/sysv_shmem.c
@@ -138,8 +138,8 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
 		 */
 		ereport(FATAL,
 				(errmsg("could not create shared memory segment: %m"),
-		  errdetail("Failed system call was shmget(key=%lu, size=%lu, 0%o).",
-					(unsigned long) memKey, (unsigned long) size,
+		  errdetail("Failed system call was shmget(key=%lu, size=%zu, 0%o).",
+					(unsigned long) memKey, size,
 					IPC_CREAT | IPC_EXCL | IPCProtection),
 				 (errno == EINVAL) ?
 				 errhint("This error usually means that PostgreSQL's request for a shared memory "
@@ -395,10 +395,10 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port)
 				errhint("This error usually means that PostgreSQL's request "
 					 "for a shared memory segment exceeded available memory "
 					  "or swap space. To reduce the request size (currently "
-					  "%lu bytes), reduce PostgreSQL's shared memory usage, "
+					  "%zu bytes), reduce PostgreSQL's shared memory usage, "
 						"perhaps by reducing shared_buffers or "
 						"max_connections.",
-						(unsigned long) size) : 0));
+						size) : 0));
 		AnonymousShmemSize = size;
 
 		/* Now we need only allocate a minimal-sized SysV shmem block. */
diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c
index 2887d10d06587c5cb286ea10acc976cb643ecd1a..80f198277a3c89a5810773f91d6668087c516739 100644
--- a/src/backend/port/win32_shmem.c
+++ b/src/backend/port/win32_shmem.c
@@ -166,8 +166,8 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port)
 		if (!hmap)
 			ereport(FATAL,
 					(errmsg("could not create shared memory segment: error code %lu", GetLastError()),
-					 errdetail("Failed system call was CreateFileMapping(size=%lu, name=%s).",
-							   (unsigned long) size, szShareMem)));
+					 errdetail("Failed system call was CreateFileMapping(size=%zu, name=%s).",
+							   size, szShareMem)));
 
 		/*
 		 * If the segment already existed, CreateFileMapping() will return a
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index a733cfb0cab9dad534e67afd5abc80577920be80..2918f75c0eb89bd3bd2fe533653a803b30d2dd27 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -829,7 +829,7 @@ AllocateVfd(void)
 	Index		i;
 	File		file;
 
-	DO_DB(elog(LOG, "AllocateVfd. Size %lu", (unsigned long) SizeVfdCache));
+	DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
 
 	Assert(SizeVfdCache > 0);	/* InitFileAccess not called? */
 
diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c
index 8d499283647bcf97a0e1f39e24e06c556ac5638a..24e69ebdbb3b958a7ca2408487d60a60f875c2fd 100644
--- a/src/backend/storage/freespace/freespace.c
+++ b/src/backend/storage/freespace/freespace.c
@@ -379,8 +379,7 @@ fsm_space_needed_to_cat(Size needed)
 
 	/* Can't ask for more space than the highest category represents */
 	if (needed > MaxFSMRequestSize)
-		elog(ERROR, "invalid FSM request size %lu",
-			 (unsigned long) needed);
+		elog(ERROR, "invalid FSM request size %zu", needed);
 
 	if (needed == 0)
 		return 1;
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index 4ee453e5ec4c7b3de490d28fcef159830d0d59a0..327d6850971af4a19e3ea2c25c38a99a6149dcd7 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -201,8 +201,8 @@ dsm_postmaster_startup(void)
 	dsm_control = dsm_control_address;
 	on_shmem_exit(dsm_postmaster_shutdown, 0);
 	elog(DEBUG2,
-		 "created dynamic shared memory control segment %u (%lu bytes)",
-		 dsm_control_handle, (unsigned long) segsize);
+		 "created dynamic shared memory control segment %u (%zu bytes)",
+		 dsm_control_handle, segsize);
 	dsm_write_state_file(dsm_control_handle);
 
 	/* Initialize control segment. */
diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c
index fc74990a2faed49172078f04b91d65ecc045c0bd..a8d8a64afbd4c9dc4a505ae7603a71dee396cf59 100644
--- a/src/backend/storage/ipc/dsm_impl.c
+++ b/src/backend/storage/ipc/dsm_impl.c
@@ -329,8 +329,8 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size,
 
 		ereport(elevel,
 				(errcode_for_dynamic_shared_memory(),
-				 errmsg("could not resize shared memory segment %s to %lu bytes: %m",
-					name, (unsigned long) request_size)));
+				 errmsg("could not resize shared memory segment %s to %zu bytes: %m",
+					name, request_size)));
 		return false;
 	}
 
@@ -871,8 +871,8 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
 
 		ereport(elevel,
 				(errcode_for_dynamic_shared_memory(),
-				 errmsg("could not resize shared memory segment %s to %lu bytes: %m",
-					name, (unsigned long) request_size)));
+				 errmsg("could not resize shared memory segment %s to %zu bytes: %m",
+					name, request_size)));
 		return false;
 	}
 	else if (*mapped_size < request_size)
@@ -919,8 +919,8 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
 
 			ereport(elevel,
 					(errcode_for_dynamic_shared_memory(),
-					 errmsg("could not resize shared memory segment %s to %lu bytes: %m",
-						name, (unsigned long) request_size)));
+					 errmsg("could not resize shared memory segment %s to %zu bytes: %m",
+						name, request_size)));
 			return false;
 		}
 	}
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 3c04fc31baed54f45ddbe852f901554e1b154ee3..cc219237097f06a974657be05c488714b7d1d882 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -142,8 +142,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
 		/* might as well round it off to a multiple of a typical page size */
 		size = add_size(size, 8192 - (size % 8192));
 
-		elog(DEBUG3, "invoking IpcMemoryCreate(size=%lu)",
-			 (unsigned long) size);
+		elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
 
 		/*
 		 * Create the shmem segment
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index 70b02ca8384b87354aebe96f59a36ebdd8d073e5..1d27a89bdd1ddc49ca46740f972b0ed345e666b4 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -359,8 +359,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
 				ereport(ERROR,
 						(errcode(ERRCODE_OUT_OF_MEMORY),
 						 errmsg("not enough shared memory for data structure"
-								" \"%s\" (%lu bytes requested)",
-								name, (unsigned long) size)));
+								" \"%s\" (%zu bytes requested)",
+								name, size)));
 			shmemseghdr->index = structPtr;
 			*foundPtr = FALSE;
 		}
@@ -393,10 +393,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
 			LWLockRelease(ShmemIndexLock);
 			ereport(ERROR,
 				  (errmsg("ShmemIndex entry size is wrong for data structure"
-						  " \"%s\": expected %lu, actual %lu",
-						  name,
-						  (unsigned long) size,
-						  (unsigned long) result->size)));
+						  " \"%s\": expected %zu, actual %zu",
+						  name, size, result->size)));
 		}
 		structPtr = result->location;
 	}
@@ -412,8 +410,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
 			ereport(ERROR,
 					(errcode(ERRCODE_OUT_OF_MEMORY),
 					 errmsg("not enough shared memory for data structure"
-							" \"%s\" (%lu bytes requested)",
-							name, (unsigned long) size)));
+							" \"%s\" (%zu bytes requested)",
+							name, size)));
 		}
 		result->size = size;
 		result->location = structPtr;
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index 633b37de59e23c9f2fc954c2d26f50b72926c3e0..e7f44cce841e2587e59b1c807bea6a7ae2b04e8d 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -1185,8 +1185,8 @@ InitPredicateLocks(void)
 			ereport(ERROR,
 					(errcode(ERRCODE_OUT_OF_MEMORY),
 			 errmsg("not enough shared memory for elements of data structure"
-					" \"%s\" (%lu bytes requested)",
-					"PredXactList", (unsigned long) requestSize)));
+					" \"%s\" (%zu bytes requested)",
+					"PredXactList", requestSize)));
 		/* Add all elements to available list, clean. */
 		memset(PredXact->element, 0, requestSize);
 		for (i = 0; i < max_table_size; i++)
@@ -1257,8 +1257,8 @@ InitPredicateLocks(void)
 			ereport(ERROR,
 					(errcode(ERRCODE_OUT_OF_MEMORY),
 			 errmsg("not enough shared memory for elements of data structure"
-					" \"%s\" (%lu bytes requested)",
-					"RWConflictPool", (unsigned long) requestSize)));
+					" \"%s\" (%zu bytes requested)",
+					"RWConflictPool", requestSize)));
 		/* Add all elements to available list, clean. */
 		memset(RWConflictPool->element, 0, requestSize);
 		for (i = 0; i < max_table_size; i++)
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index 56e53f4977afc5ad478ac3aecb06437cd4fdd436..099200cb66a295cbcfb96061bbb69d51b89d4394 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -676,8 +676,7 @@ AllocSetAlloc(MemoryContext context, Size size)
 			ereport(ERROR,
 					(errcode(ERRCODE_OUT_OF_MEMORY),
 					 errmsg("out of memory"),
-					 errdetail("Failed on request of size %lu.",
-							   (unsigned long) size)));
+					 errdetail("Failed on request of size %zu.", size)));
 		}
 		block->aset = set;
 		block->freeptr = block->endptr = ((char *) block) + blksize;
@@ -871,8 +870,7 @@ AllocSetAlloc(MemoryContext context, Size size)
 			ereport(ERROR,
 					(errcode(ERRCODE_OUT_OF_MEMORY),
 					 errmsg("out of memory"),
-					 errdetail("Failed on request of size %lu.",
-							   (unsigned long) size)));
+					 errdetail("Failed on request of size %zu.", size)));
 		}
 
 		block->aset = set;
@@ -1114,8 +1112,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
 			ereport(ERROR,
 					(errcode(ERRCODE_OUT_OF_MEMORY),
 					 errmsg("out of memory"),
-					 errdetail("Failed on request of size %lu.",
-							   (unsigned long) size)));
+					 errdetail("Failed on request of size %zu.", size)));
 		}
 		block->freeptr = block->endptr = ((char *) block) + blksize;
 
@@ -1245,10 +1242,10 @@ static void
 AllocSetStats(MemoryContext context, int level)
 {
 	AllocSet	set = (AllocSet) context;
-	long		nblocks = 0;
-	long		nchunks = 0;
-	long		totalspace = 0;
-	long		freespace = 0;
+	Size		nblocks = 0;
+	Size		nchunks = 0;
+	Size		totalspace = 0;
+	Size		freespace = 0;
 	AllocBlock	block;
 	AllocChunk	chunk;
 	int			fidx;
@@ -1274,7 +1271,7 @@ AllocSetStats(MemoryContext context, int level)
 		fprintf(stderr, "  ");
 
 	fprintf(stderr,
-			"%s: %lu total in %ld blocks; %lu free (%ld chunks); %lu used\n",
+			"%s: %zu total in %zd blocks; %zu free (%zd chunks); %zu used\n",
 			set->header.name, totalspace, nblocks, freespace, nchunks,
 			totalspace - freespace);
 }
@@ -1338,8 +1335,8 @@ AllocSetCheck(MemoryContext context)
 				elog(WARNING, "problem in alloc set %s: req size > alloc size for chunk %p in block %p",
 					 name, chunk, block);
 			if (chsize < (1 << ALLOC_MINBITS))
-				elog(WARNING, "problem in alloc set %s: bad size %lu for chunk %p in block %p",
-					 name, (unsigned long) chsize, chunk, block);
+				elog(WARNING, "problem in alloc set %s: bad size %zu for chunk %p in block %p",
+					 name, chsize, chunk, block);
 
 			/* single-chunk block? */
 			if (chsize > set->allocChunkLimit &&
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 7b089f77df8aa6aab95168afe04f31ae6400486a..a7ca44dd86cc05d99482add5773f22379fb8ac2c 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -577,8 +577,7 @@ MemoryContextAlloc(MemoryContext context, Size size)
 	AssertArg(MemoryContextIsValid(context));
 
 	if (!AllocSizeIsValid(size))
-		elog(ERROR, "invalid memory alloc request size %lu",
-			 (unsigned long) size);
+		elog(ERROR, "invalid memory alloc request size %zu", size);
 
 	context->isReset = false;
 
@@ -603,8 +602,7 @@ MemoryContextAllocZero(MemoryContext context, Size size)
 	AssertArg(MemoryContextIsValid(context));
 
 	if (!AllocSizeIsValid(size))
-		elog(ERROR, "invalid memory alloc request size %lu",
-			 (unsigned long) size);
+		elog(ERROR, "invalid memory alloc request size %zu", size);
 
 	context->isReset = false;
 
@@ -631,8 +629,7 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size)
 	AssertArg(MemoryContextIsValid(context));
 
 	if (!AllocSizeIsValid(size))
-		elog(ERROR, "invalid memory alloc request size %lu",
-			 (unsigned long) size);
+		elog(ERROR, "invalid memory alloc request size %zu", size);
 
 	context->isReset = false;
 
@@ -653,8 +650,7 @@ palloc(Size size)
 	AssertArg(MemoryContextIsValid(CurrentMemoryContext));
 
 	if (!AllocSizeIsValid(size))
-		elog(ERROR, "invalid memory alloc request size %lu",
-			 (unsigned long) size);
+		elog(ERROR, "invalid memory alloc request size %zu", size);
 
 	CurrentMemoryContext->isReset = false;
 
@@ -673,8 +669,7 @@ palloc0(Size size)
 	AssertArg(MemoryContextIsValid(CurrentMemoryContext));
 
 	if (!AllocSizeIsValid(size))
-		elog(ERROR, "invalid memory alloc request size %lu",
-			 (unsigned long) size);
+		elog(ERROR, "invalid memory alloc request size %zu", size);
 
 	CurrentMemoryContext->isReset = false;
 
@@ -726,8 +721,7 @@ repalloc(void *pointer, Size size)
 	void	   *ret;
 
 	if (!AllocSizeIsValid(size))
-		elog(ERROR, "invalid memory alloc request size %lu",
-			 (unsigned long) size);
+		elog(ERROR, "invalid memory alloc request size %zu", size);
 
 	/*
 	 * Try to detect bogus pointers handed to us, poorly though we can.
@@ -768,8 +762,7 @@ MemoryContextAllocHuge(MemoryContext context, Size size)
 	AssertArg(MemoryContextIsValid(context));
 
 	if (!AllocHugeSizeIsValid(size))
-		elog(ERROR, "invalid memory alloc request size %lu",
-			 (unsigned long) size);
+		elog(ERROR, "invalid memory alloc request size %zu", size);
 
 	context->isReset = false;
 
@@ -791,8 +784,7 @@ repalloc_huge(void *pointer, Size size)
 	void	   *ret;
 
 	if (!AllocHugeSizeIsValid(size))
-		elog(ERROR, "invalid memory alloc request size %lu",
-			 (unsigned long) size);
+		elog(ERROR, "invalid memory alloc request size %zu", size);
 
 	/*
 	 * Try to detect bogus pointers handed to us, poorly though we can.
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 0bade28b972cab7b53642c5d2d33f8689f04595a..db930f5bb0e0313c067e2585e52e7acb65014e0f 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -671,8 +671,8 @@
 /* Define to the name of a signed 64-bit integer type. */
 #undef PG_INT64_TYPE
 
-/* Define to the name of the default PostgreSQL service principal in Kerberos.
-   (--with-krb-srvnam=NAME) */
+/* Define to the name of the default PostgreSQL service principal in Kerberos
+   (GSSAPI). (--with-krb-srvnam=NAME) */
 #undef PG_KRB_SRVNAM
 
 /* PostgreSQL major version as a string */
diff --git a/src/port/snprintf.c b/src/port/snprintf.c
index 9f719505f492f33a65401a75102fbbe81822aa74..d3f890fae99090b1a107c1dcd6303f2ff5ff901d 100644
--- a/src/port/snprintf.c
+++ b/src/port/snprintf.c
@@ -386,6 +386,19 @@ nextch1:
 				else
 					longflag = 1;
 				goto nextch1;
+			case 'z':
+#if SIZEOF_SIZE_T == 8
+#ifdef HAVE_LONG_INT_64
+				longflag = 1;
+#elif defined(HAVE_LONG_LONG_INT_64)
+				longlongflag = 1;
+#else
+#error "Don't know how to print 64bit integers"
+#endif
+#else
+				/* assume size_t is same size as int */
+#endif
+				goto nextch1;
 			case 'h':
 			case '\'':
 				/* ignore these */
@@ -619,6 +632,19 @@ nextch2:
 				else
 					longflag = 1;
 				goto nextch2;
+			case 'z':
+#if SIZEOF_SIZE_T == 8
+#ifdef HAVE_LONG_INT_64
+				longflag = 1;
+#elif defined(HAVE_LONG_LONG_INT_64)
+				longlongflag = 1;
+#else
+#error "Don't know how to print 64bit integers"
+#endif
+#else
+				/* assume size_t is same size as int */
+#endif
+				goto nextch2;
 			case 'h':
 			case '\'':
 				/* ignore these */