*** a/src/backend/access/transam/xlog.c
--- b/src/backend/access/transam/xlog.c
***************
*** 55,60 ****
--- 55,61 ----
  #include "storage/spin.h"
  #include "utils/builtins.h"
  #include "utils/guc.h"
+ #include "utils/pg_lzcompress.h"
  #include "utils/ps_status.h"
  #include "utils/relmapper.h"
  #include "utils/snapmgr.h"
***************
*** 79,84 **** bool		XLogArchiveMode = false;
--- 80,86 ----
  char	   *XLogArchiveCommand = NULL;
  bool		EnableHotStandby = false;
  bool		fullPageWrites = true;
+ bool		compress_backup_block = false;
  bool		log_checkpoints = false;
  int			sync_method = DEFAULT_SYNC_METHOD;
  int			wal_level = WAL_LEVEL_MINIMAL;
***************
*** 787,792 **** static bool ReserveXLogSwitch(XLogRecPtr *StartPos, XLogRecPtr *EndPos,
--- 789,795 ----
  				  XLogRecPtr *PrevPtr);
  static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto);
  static void WakeupWaiters(XLogRecPtr EndPos);
+ static char *CompressBackupBlock(char *page, uint32 orig_len, uint32 *len);
  static char *GetXLogBuffer(XLogRecPtr ptr);
  static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos);
  static XLogRecPtr XLogBytePosToEndRecPtr(uint64 bytepos);
***************
*** 994,999 **** begin:;
--- 997,1014 ----
  		rdt->next = &(dtbuf_rdt2[i]);
  		rdt = rdt->next;
  
+ 		if (compress_backup_block)
+ 		{
+ 			rdt->data = CompressBackupBlock(page, BLCKSZ - bkpb->hole_length, &(rdt->len));
+ 			if (rdt->data != NULL)
+ 			{
+ 				write_len += rdt->len;
+ 				bkpb->hole_length = BLCKSZ - rdt->len;
+ 				rdt->next = NULL;
+ 				continue;
+ 			}
+ 		}
+ 
  		if (bkpb->hole_length == 0)
  		{
  			rdt->data = page;
***************
*** 2082,2087 **** WaitXLogInsertionsToFinish(XLogRecPtr upto)
--- 2097,2144 ----
  }
  
  /*
+  * Create a compressed version of a backup block
+  *
+  * If successful, return a compressed result and set 'len' to its length.
+  * Otherwise (ie, compressed result is actually bigger than original),
+  * return NULL.
+  */
+ static char *
+ CompressBackupBlock(char *page, uint32 orig_len, uint32 *len)
+ {
+ 	struct varlena *buf;
+ 
+ #define	PGLZ_BLCKSZ	PGLZ_MAX_OUTPUT(BLCKSZ)
+ 
+ 	buf = (struct varlena *) palloc(PGLZ_BLCKSZ);
+ 
+ 	/*
+ 	 * We recheck the actual size even if pglz_compress() reports success,
+ 	 * because it might be satisfied with having saved as little as one byte
+ 	 * in the compressed data --- which could turn into a net loss once you
+ 	 * consider header and alignment padding.  Worst case, the compressed
+ 	 * format might require three padding bytes (plus header, which is
+ 	 * included in VARSIZE(buf)), whereas the uncompressed format would take
+ 	 * only one header byte and no padding if the value is short enough.  So
+ 	 * we insist on a savings of more than 2 bytes to ensure we have a gain.
+ 	 */
+ 	if (pglz_compress(page, BLCKSZ,
+ 					  (PGLZ_Header *) buf, PGLZ_strategy_default) &&
+ 		VARSIZE(buf) < orig_len - 2)
+ 	{
+ 		/* successful compression */
+ 		*len = VARHDRSZ + VARSIZE(buf);
+ 		return (char *) buf;
+ 	}
+ 	else
+ 	{
+ 		/* incompressible data */
+ 		pfree(buf);
+ 		return NULL;
+ 	}
+ }
+ 
+ /*
   * Get a pointer to the right location in the WAL buffer containing the
   * given XLogRecPtr.
   *
***************
*** 4319,4324 **** RestoreBackupBlockContents(XLogRecPtr lsn, BkpBlock bkpb, char *blk,
--- 4376,4386 ----
  	{
  		memcpy((char *) page, blk, BLCKSZ);
  	}
+ 	else if (VARATT_IS_COMPRESSED((struct varlena *) blk))
+ 	{
+ 		/* If it's compressed, decompress it */
+ 		pglz_decompress((PGLZ_Header *) blk, (char *) page);
+ 	}
  	else
  	{
  		memcpy((char *) page, blk, bkpb.hole_offset);
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
***************
*** 853,858 **** static struct config_bool ConfigureNamesBool[] =
--- 853,867 ----
  		NULL, NULL, NULL
  	},
  	{
+ 		{"compress_backup_block", PGC_SIGHUP, WAL_SETTINGS,
+ 			gettext_noop("Compress backup block in WAL."),
+ 			NULL
+ 		},
+ 		&compress_backup_block,
+ 		false,
+ 		NULL, NULL, NULL
+ 	},
+ 	{
  		{"log_checkpoints", PGC_SIGHUP, LOGGING_WHAT,
  			gettext_noop("Logs each checkpoint."),
  			NULL
*** a/src/include/access/xlog.h
--- b/src/include/access/xlog.h
***************
*** 189,194 **** extern bool XLogArchiveMode;
--- 189,195 ----
  extern char *XLogArchiveCommand;
  extern bool EnableHotStandby;
  extern bool fullPageWrites;
+ extern bool compress_backup_block;
  extern bool log_checkpoints;
  extern int	num_xloginsert_slots;
  
