*** a/src/backend/access/gin/Makefile
--- b/src/backend/access/gin/Makefile
***************
*** 12,18 **** subdir = src/backend/access/gin
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = ginutil.o gininsert.o ginxlog.o ginentrypage.o gindatapage.o \
  	ginbtree.o ginscan.o ginget.o ginvacuum.o ginarrayproc.o \
  	ginbulk.o ginfast.o
  
--- 12,18 ----
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = ginutil.o gininsert.o ginxlog.o gindesc.o ginentrypage.o gindatapage.o \
  	ginbtree.o ginscan.o ginget.o ginvacuum.o ginarrayproc.o \
  	ginbulk.o ginfast.o
  
*** /dev/null
--- b/src/backend/access/gin/gindesc.c
***************
*** 0 ****
--- 1,69 ----
+ #include "postgres.h"
+ 
+ #include "access/gin_private.h"
+ #include "lib/stringinfo.h"
+ #include "storage/relfilenode.h"
+ 
+ static void
+ desc_node(StringInfo buf, RelFileNode node, BlockNumber blkno)
+ {
+ 	appendStringInfo(buf, "node: %u/%u/%u blkno: %u",
+ 					 node.spcNode, node.dbNode, node.relNode, blkno);
+ }
+ 
+ void
+ gin_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	switch (info)
+ 	{
+ 		case XLOG_GIN_CREATE_INDEX:
+ 			appendStringInfo(buf, "Create index, ");
+ 			desc_node(buf, *(RelFileNode *) rec, GIN_ROOT_BLKNO);
+ 			break;
+ 		case XLOG_GIN_CREATE_PTREE:
+ 			appendStringInfo(buf, "Create posting tree, ");
+ 			desc_node(buf, ((ginxlogCreatePostingTree *) rec)->node, ((ginxlogCreatePostingTree *) rec)->blkno);
+ 			break;
+ 		case XLOG_GIN_INSERT:
+ 			appendStringInfo(buf, "Insert item, ");
+ 			desc_node(buf, ((ginxlogInsert *) rec)->node, ((ginxlogInsert *) rec)->blkno);
+ 			appendStringInfo(buf, " offset: %u nitem: %u isdata: %c isleaf %c isdelete %c updateBlkno:%u",
+ 							 ((ginxlogInsert *) rec)->offset,
+ 							 ((ginxlogInsert *) rec)->nitem,
+ 							 (((ginxlogInsert *) rec)->isData) ? 'T' : 'F',
+ 							 (((ginxlogInsert *) rec)->isLeaf) ? 'T' : 'F',
+ 							 (((ginxlogInsert *) rec)->isDelete) ? 'T' : 'F',
+ 							 ((ginxlogInsert *) rec)->updateBlkno);
+ 			break;
+ 		case XLOG_GIN_SPLIT:
+ 			appendStringInfo(buf, "Page split, ");
+ 			desc_node(buf, ((ginxlogSplit *) rec)->node, ((ginxlogSplit *) rec)->lblkno);
+ 			appendStringInfo(buf, " isrootsplit: %c", (((ginxlogSplit *) rec)->isRootSplit) ? 'T' : 'F');
+ 			break;
+ 		case XLOG_GIN_VACUUM_PAGE:
+ 			appendStringInfo(buf, "Vacuum page, ");
+ 			desc_node(buf, ((ginxlogVacuumPage *) rec)->node, ((ginxlogVacuumPage *) rec)->blkno);
+ 			break;
+ 		case XLOG_GIN_DELETE_PAGE:
+ 			appendStringInfo(buf, "Delete page, ");
+ 			desc_node(buf, ((ginxlogDeletePage *) rec)->node, ((ginxlogDeletePage *) rec)->blkno);
+ 			break;
+ 		case XLOG_GIN_UPDATE_META_PAGE:
+ 			appendStringInfo(buf, "Update metapage, ");
+ 			desc_node(buf, ((ginxlogUpdateMeta *) rec)->node, GIN_METAPAGE_BLKNO);
+ 			break;
+ 		case XLOG_GIN_INSERT_LISTPAGE:
+ 			appendStringInfo(buf, "Insert new list page, ");
+ 			desc_node(buf, ((ginxlogInsertListPage *) rec)->node, ((ginxlogInsertListPage *) rec)->blkno);
+ 			break;
+ 		case XLOG_GIN_DELETE_LISTPAGE:
+ 			appendStringInfo(buf, "Delete list pages (%d), ", ((ginxlogDeleteListPages *) rec)->ndeleted);
+ 			desc_node(buf, ((ginxlogDeleteListPages *) rec)->node, GIN_METAPAGE_BLKNO);
+ 			break;
+ 		default:
+ 			appendStringInfo(buf, "unknown gin op code %u", info);
+ 			break;
+ 	}
+ }
*** a/src/backend/access/gin/ginxlog.c
--- b/src/backend/access/gin/ginxlog.c
***************
*** 717,785 **** gin_redo(XLogRecPtr lsn, XLogRecord *record)
  	MemoryContextReset(opCtx);
  }
  
- static void
- desc_node(StringInfo buf, RelFileNode node, BlockNumber blkno)
- {
- 	appendStringInfo(buf, "node: %u/%u/%u blkno: %u",
- 					 node.spcNode, node.dbNode, node.relNode, blkno);
- }
- 
- void
- gin_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	switch (info)
- 	{
- 		case XLOG_GIN_CREATE_INDEX:
- 			appendStringInfo(buf, "Create index, ");
- 			desc_node(buf, *(RelFileNode *) rec, GIN_ROOT_BLKNO);
- 			break;
- 		case XLOG_GIN_CREATE_PTREE:
- 			appendStringInfo(buf, "Create posting tree, ");
- 			desc_node(buf, ((ginxlogCreatePostingTree *) rec)->node, ((ginxlogCreatePostingTree *) rec)->blkno);
- 			break;
- 		case XLOG_GIN_INSERT:
- 			appendStringInfo(buf, "Insert item, ");
- 			desc_node(buf, ((ginxlogInsert *) rec)->node, ((ginxlogInsert *) rec)->blkno);
- 			appendStringInfo(buf, " offset: %u nitem: %u isdata: %c isleaf %c isdelete %c updateBlkno:%u",
- 							 ((ginxlogInsert *) rec)->offset,
- 							 ((ginxlogInsert *) rec)->nitem,
- 							 (((ginxlogInsert *) rec)->isData) ? 'T' : 'F',
- 							 (((ginxlogInsert *) rec)->isLeaf) ? 'T' : 'F',
- 							 (((ginxlogInsert *) rec)->isDelete) ? 'T' : 'F',
- 							 ((ginxlogInsert *) rec)->updateBlkno);
- 			break;
- 		case XLOG_GIN_SPLIT:
- 			appendStringInfo(buf, "Page split, ");
- 			desc_node(buf, ((ginxlogSplit *) rec)->node, ((ginxlogSplit *) rec)->lblkno);
- 			appendStringInfo(buf, " isrootsplit: %c", (((ginxlogSplit *) rec)->isRootSplit) ? 'T' : 'F');
- 			break;
- 		case XLOG_GIN_VACUUM_PAGE:
- 			appendStringInfo(buf, "Vacuum page, ");
- 			desc_node(buf, ((ginxlogVacuumPage *) rec)->node, ((ginxlogVacuumPage *) rec)->blkno);
- 			break;
- 		case XLOG_GIN_DELETE_PAGE:
- 			appendStringInfo(buf, "Delete page, ");
- 			desc_node(buf, ((ginxlogDeletePage *) rec)->node, ((ginxlogDeletePage *) rec)->blkno);
- 			break;
- 		case XLOG_GIN_UPDATE_META_PAGE:
- 			appendStringInfo(buf, "Update metapage, ");
- 			desc_node(buf, ((ginxlogUpdateMeta *) rec)->node, GIN_METAPAGE_BLKNO);
- 			break;
- 		case XLOG_GIN_INSERT_LISTPAGE:
- 			appendStringInfo(buf, "Insert new list page, ");
- 			desc_node(buf, ((ginxlogInsertListPage *) rec)->node, ((ginxlogInsertListPage *) rec)->blkno);
- 			break;
- 		case XLOG_GIN_DELETE_LISTPAGE:
- 			appendStringInfo(buf, "Delete list pages (%d), ", ((ginxlogDeleteListPages *) rec)->ndeleted);
- 			desc_node(buf, ((ginxlogDeleteListPages *) rec)->node, GIN_METAPAGE_BLKNO);
- 			break;
- 		default:
- 			elog(PANIC, "gin_desc: unknown op code %u", info);
- 	}
- }
- 
  void
  gin_xlog_startup(void)
  {
--- 717,722 ----
*** a/src/backend/access/gist/Makefile
--- b/src/backend/access/gist/Makefile
***************
*** 12,18 **** subdir = src/backend/access/gist
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = gist.o gistutil.o gistxlog.o gistvacuum.o gistget.o gistscan.o \
!        gistproc.o gistsplit.o gistbuild.o gistbuildbuffers.o
  
  include $(top_srcdir)/src/backend/common.mk
--- 12,18 ----
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = gist.o gistutil.o gistxlog.o gistdesc.o gistvacuum.o gistget.o \
! 	   gistscan.o gistproc.o gistsplit.o gistbuild.o gistbuildbuffers.o
  
  include $(top_srcdir)/src/backend/common.mk
*** /dev/null
--- b/src/backend/access/gist/gistdesc.c
***************
*** 0 ****
--- 1,66 ----
+ #include "postgres.h"
+ 
+ #include "access/gist_private.h"
+ #include "access/xlog.h"
+ #include "lib/stringinfo.h"
+ #include "storage/relfilenode.h"
+ 
+ static void
+ out_target(StringInfo buf, RelFileNode node)
+ {
+ 	appendStringInfo(buf, "rel %u/%u/%u",
+ 					 node.spcNode, node.dbNode, node.relNode);
+ }
+ 
+ static void
+ out_gistxlogPageUpdate(StringInfo buf, gistxlogPageUpdate *xlrec)
+ {
+ 	out_target(buf, xlrec->node);
+ 	appendStringInfo(buf, "; block number %u", xlrec->blkno);
+ }
+ 
+ static void
+ out_gistxlogPageDelete(StringInfo buf, gistxlogPageDelete *xlrec)
+ {
+ 	appendStringInfo(buf, "page_delete: rel %u/%u/%u; blkno %u",
+ 				xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode,
+ 					 xlrec->blkno);
+ }
+ 
+ static void
+ out_gistxlogPageSplit(StringInfo buf, gistxlogPageSplit *xlrec)
+ {
+ 	appendStringInfo(buf, "page_split: ");
+ 	out_target(buf, xlrec->node);
+ 	appendStringInfo(buf, "; block number %u splits to %d pages",
+ 					 xlrec->origblkno, xlrec->npage);
+ }
+ 
+ void
+ gist_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	switch (info)
+ 	{
+ 		case XLOG_GIST_PAGE_UPDATE:
+ 			appendStringInfo(buf, "page_update: ");
+ 			out_gistxlogPageUpdate(buf, (gistxlogPageUpdate *) rec);
+ 			break;
+ 		case XLOG_GIST_PAGE_DELETE:
+ 			out_gistxlogPageDelete(buf, (gistxlogPageDelete *) rec);
+ 			break;
+ 		case XLOG_GIST_PAGE_SPLIT:
+ 			out_gistxlogPageSplit(buf, (gistxlogPageSplit *) rec);
+ 			break;
+ 		case XLOG_GIST_CREATE_INDEX:
+ 			appendStringInfo(buf, "create_index: rel %u/%u/%u",
+ 							 ((RelFileNode *) rec)->spcNode,
+ 							 ((RelFileNode *) rec)->dbNode,
+ 							 ((RelFileNode *) rec)->relNode);
+ 			break;
+ 		default:
+ 			appendStringInfo(buf, "unknown gist op code %u", info);
+ 			break;
+ 	}
+ }
*** a/src/backend/access/gist/gistxlog.c
--- b/src/backend/access/gist/gistxlog.c
***************
*** 333,398 **** gist_redo(XLogRecPtr lsn, XLogRecord *record)
  	MemoryContextReset(opCtx);
  }
  
- static void
- out_target(StringInfo buf, RelFileNode node)
- {
- 	appendStringInfo(buf, "rel %u/%u/%u",
- 					 node.spcNode, node.dbNode, node.relNode);
- }
- 
- static void
- out_gistxlogPageUpdate(StringInfo buf, gistxlogPageUpdate *xlrec)
- {
- 	out_target(buf, xlrec->node);
- 	appendStringInfo(buf, "; block number %u", xlrec->blkno);
- }
- 
- static void
- out_gistxlogPageDelete(StringInfo buf, gistxlogPageDelete *xlrec)
- {
- 	appendStringInfo(buf, "page_delete: rel %u/%u/%u; blkno %u",
- 				xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode,
- 					 xlrec->blkno);
- }
- 
- static void
- out_gistxlogPageSplit(StringInfo buf, gistxlogPageSplit *xlrec)
- {
- 	appendStringInfo(buf, "page_split: ");
- 	out_target(buf, xlrec->node);
- 	appendStringInfo(buf, "; block number %u splits to %d pages",
- 					 xlrec->origblkno, xlrec->npage);
- }
- 
- void
- gist_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	switch (info)
- 	{
- 		case XLOG_GIST_PAGE_UPDATE:
- 			appendStringInfo(buf, "page_update: ");
- 			out_gistxlogPageUpdate(buf, (gistxlogPageUpdate *) rec);
- 			break;
- 		case XLOG_GIST_PAGE_DELETE:
- 			out_gistxlogPageDelete(buf, (gistxlogPageDelete *) rec);
- 			break;
- 		case XLOG_GIST_PAGE_SPLIT:
- 			out_gistxlogPageSplit(buf, (gistxlogPageSplit *) rec);
- 			break;
- 		case XLOG_GIST_CREATE_INDEX:
- 			appendStringInfo(buf, "create_index: rel %u/%u/%u",
- 							 ((RelFileNode *) rec)->spcNode,
- 							 ((RelFileNode *) rec)->dbNode,
- 							 ((RelFileNode *) rec)->relNode);
- 			break;
- 		default:
- 			appendStringInfo(buf, "unknown gist op code %u", info);
- 			break;
- 	}
- }
- 
  void
  gist_xlog_startup(void)
  {
--- 333,338 ----
*** a/src/backend/access/hash/Makefile
--- b/src/backend/access/hash/Makefile
***************
*** 13,18 **** top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
  OBJS = hash.o hashfunc.o hashinsert.o hashovfl.o hashpage.o hashscan.o \
!        hashsearch.o hashsort.o hashutil.o
  
  include $(top_srcdir)/src/backend/common.mk
--- 13,18 ----
  include $(top_builddir)/src/Makefile.global
  
  OBJS = hash.o hashfunc.o hashinsert.o hashovfl.o hashpage.o hashscan.o \
!        hashsearch.o hashsort.o hashutil.o hashdesc.o
  
  include $(top_srcdir)/src/backend/common.mk
*** a/src/backend/access/hash/hash.c
--- b/src/backend/access/hash/hash.c
***************
*** 712,719 **** hash_redo(XLogRecPtr lsn, XLogRecord *record)
  {
  	elog(PANIC, "hash_redo: unimplemented");
  }
- 
- void
- hash_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- }
--- 712,714 ----
*** /dev/null
--- b/src/backend/access/hash/hashdesc.c
***************
*** 0 ****
--- 1,8 ----
+ #include "postgres.h"
+ 
+ #include "access/hash.h"
+ 
+ void
+ hash_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ }
*** a/src/backend/access/heap/Makefile
--- b/src/backend/access/heap/Makefile
***************
*** 12,17 **** subdir = src/backend/access/heap
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = heapam.o hio.o pruneheap.o rewriteheap.o syncscan.o tuptoaster.o visibilitymap.o
  
  include $(top_srcdir)/src/backend/common.mk
--- 12,18 ----
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = heapam.o heapdesc.o hio.o pruneheap.o rewriteheap.o syncscan.o \
! 	   tuptoaster.o visibilitymap.o
  
  include $(top_srcdir)/src/backend/common.mk
*** a/src/backend/access/heap/heapam.c
--- b/src/backend/access/heap/heapam.c
***************
*** 5615,5768 **** heap2_redo(XLogRecPtr lsn, XLogRecord *record)
  	}
  }
  
- static void
- out_target(StringInfo buf, xl_heaptid *target)
- {
- 	appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
- 			 target->node.spcNode, target->node.dbNode, target->node.relNode,
- 					 ItemPointerGetBlockNumber(&(target->tid)),
- 					 ItemPointerGetOffsetNumber(&(target->tid)));
- }
- 
- void
- heap_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	info &= XLOG_HEAP_OPMASK;
- 	if (info == XLOG_HEAP_INSERT)
- 	{
- 		xl_heap_insert *xlrec = (xl_heap_insert *) rec;
- 
- 		if (xl_info & XLOG_HEAP_INIT_PAGE)
- 			appendStringInfo(buf, "insert(init): ");
- 		else
- 			appendStringInfo(buf, "insert: ");
- 		out_target(buf, &(xlrec->target));
- 	}
- 	else if (info == XLOG_HEAP_DELETE)
- 	{
- 		xl_heap_delete *xlrec = (xl_heap_delete *) rec;
- 
- 		appendStringInfo(buf, "delete: ");
- 		out_target(buf, &(xlrec->target));
- 	}
- 	else if (info == XLOG_HEAP_UPDATE)
- 	{
- 		xl_heap_update *xlrec = (xl_heap_update *) rec;
- 
- 		if (xl_info & XLOG_HEAP_INIT_PAGE)
- 			appendStringInfo(buf, "update(init): ");
- 		else
- 			appendStringInfo(buf, "update: ");
- 		out_target(buf, &(xlrec->target));
- 		appendStringInfo(buf, "; new %u/%u",
- 						 ItemPointerGetBlockNumber(&(xlrec->newtid)),
- 						 ItemPointerGetOffsetNumber(&(xlrec->newtid)));
- 	}
- 	else if (info == XLOG_HEAP_HOT_UPDATE)
- 	{
- 		xl_heap_update *xlrec = (xl_heap_update *) rec;
- 
- 		if (xl_info & XLOG_HEAP_INIT_PAGE)		/* can this case happen? */
- 			appendStringInfo(buf, "hot_update(init): ");
- 		else
- 			appendStringInfo(buf, "hot_update: ");
- 		out_target(buf, &(xlrec->target));
- 		appendStringInfo(buf, "; new %u/%u",
- 						 ItemPointerGetBlockNumber(&(xlrec->newtid)),
- 						 ItemPointerGetOffsetNumber(&(xlrec->newtid)));
- 	}
- 	else if (info == XLOG_HEAP_NEWPAGE)
- 	{
- 		xl_heap_newpage *xlrec = (xl_heap_newpage *) rec;
- 
- 		appendStringInfo(buf, "newpage: rel %u/%u/%u; fork %u, blk %u",
- 						 xlrec->node.spcNode, xlrec->node.dbNode,
- 						 xlrec->node.relNode, xlrec->forknum,
- 						 xlrec->blkno);
- 	}
- 	else if (info == XLOG_HEAP_LOCK)
- 	{
- 		xl_heap_lock *xlrec = (xl_heap_lock *) rec;
- 
- 		if (xlrec->shared_lock)
- 			appendStringInfo(buf, "shared_lock: ");
- 		else
- 			appendStringInfo(buf, "exclusive_lock: ");
- 		if (xlrec->xid_is_mxact)
- 			appendStringInfo(buf, "mxid ");
- 		else
- 			appendStringInfo(buf, "xid ");
- 		appendStringInfo(buf, "%u ", xlrec->locking_xid);
- 		out_target(buf, &(xlrec->target));
- 	}
- 	else if (info == XLOG_HEAP_INPLACE)
- 	{
- 		xl_heap_inplace *xlrec = (xl_heap_inplace *) rec;
- 
- 		appendStringInfo(buf, "inplace: ");
- 		out_target(buf, &(xlrec->target));
- 	}
- 	else
- 		appendStringInfo(buf, "UNKNOWN");
- }
- 
- void
- heap2_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	info &= XLOG_HEAP_OPMASK;
- 	if (info == XLOG_HEAP2_FREEZE)
- 	{
- 		xl_heap_freeze *xlrec = (xl_heap_freeze *) rec;
- 
- 		appendStringInfo(buf, "freeze: rel %u/%u/%u; blk %u; cutoff %u",
- 						 xlrec->node.spcNode, xlrec->node.dbNode,
- 						 xlrec->node.relNode, xlrec->block,
- 						 xlrec->cutoff_xid);
- 	}
- 	else if (info == XLOG_HEAP2_CLEAN)
- 	{
- 		xl_heap_clean *xlrec = (xl_heap_clean *) rec;
- 
- 		appendStringInfo(buf, "clean: rel %u/%u/%u; blk %u remxid %u",
- 						 xlrec->node.spcNode, xlrec->node.dbNode,
- 						 xlrec->node.relNode, xlrec->block,
- 						 xlrec->latestRemovedXid);
- 	}
- 	else if (info == XLOG_HEAP2_CLEANUP_INFO)
- 	{
- 		xl_heap_cleanup_info *xlrec = (xl_heap_cleanup_info *) rec;
- 
- 		appendStringInfo(buf, "cleanup info: remxid %u",
- 						 xlrec->latestRemovedXid);
- 	}
- 	else if (info == XLOG_HEAP2_VISIBLE)
- 	{
- 		xl_heap_visible *xlrec = (xl_heap_visible *) rec;
- 
- 		appendStringInfo(buf, "visible: rel %u/%u/%u; blk %u",
- 						 xlrec->node.spcNode, xlrec->node.dbNode,
- 						 xlrec->node.relNode, xlrec->block);
- 	}
- 	else if (info == XLOG_HEAP2_MULTI_INSERT)
- 	{
- 		xl_heap_multi_insert *xlrec = (xl_heap_multi_insert *) rec;
- 
- 		if (xl_info & XLOG_HEAP_INIT_PAGE)
- 			appendStringInfo(buf, "multi-insert (init): ");
- 		else
- 			appendStringInfo(buf, "multi-insert: ");
- 		appendStringInfo(buf, "rel %u/%u/%u; blk %u; %d tuples",
- 				xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode,
- 						 xlrec->blkno, xlrec->ntuples);
- 	}
- 	else
- 		appendStringInfo(buf, "UNKNOWN");
- }
- 
  /*
   *	heap_sync		- sync a heap, for use when no WAL has been written
   *
--- 5615,5620 ----
*** /dev/null
--- b/src/backend/access/heap/heapdesc.c
***************
*** 0 ****
--- 1,154 ----
+ #include "postgres.h"
+ 
+ #include "access/heapam_xlog.h"
+ #include "access/xlog.h"
+ #include "lib/stringinfo.h"
+ #include "storage/relfilenode.h"
+ 
+ static void
+ out_target(StringInfo buf, xl_heaptid *target)
+ {
+ 	appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
+ 			 target->node.spcNode, target->node.dbNode, target->node.relNode,
+ 					 ItemPointerGetBlockNumber(&(target->tid)),
+ 					 ItemPointerGetOffsetNumber(&(target->tid)));
+ }
+ 
+ void
+ heap_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	info &= XLOG_HEAP_OPMASK;
+ 	if (info == XLOG_HEAP_INSERT)
+ 	{
+ 		xl_heap_insert *xlrec = (xl_heap_insert *) rec;
+ 
+ 		if (xl_info & XLOG_HEAP_INIT_PAGE)
+ 			appendStringInfo(buf, "insert(init): ");
+ 		else
+ 			appendStringInfo(buf, "insert: ");
+ 		out_target(buf, &(xlrec->target));
+ 	}
+ 	else if (info == XLOG_HEAP_DELETE)
+ 	{
+ 		xl_heap_delete *xlrec = (xl_heap_delete *) rec;
+ 
+ 		appendStringInfo(buf, "delete: ");
+ 		out_target(buf, &(xlrec->target));
+ 	}
+ 	else if (info == XLOG_HEAP_UPDATE)
+ 	{
+ 		xl_heap_update *xlrec = (xl_heap_update *) rec;
+ 
+ 		if (xl_info & XLOG_HEAP_INIT_PAGE)
+ 			appendStringInfo(buf, "update(init): ");
+ 		else
+ 			appendStringInfo(buf, "update: ");
+ 		out_target(buf, &(xlrec->target));
+ 		appendStringInfo(buf, "; new %u/%u",
+ 						 ItemPointerGetBlockNumber(&(xlrec->newtid)),
+ 						 ItemPointerGetOffsetNumber(&(xlrec->newtid)));
+ 	}
+ 	else if (info == XLOG_HEAP_HOT_UPDATE)
+ 	{
+ 		xl_heap_update *xlrec = (xl_heap_update *) rec;
+ 
+ 		if (xl_info & XLOG_HEAP_INIT_PAGE)		/* can this case happen? */
+ 			appendStringInfo(buf, "hot_update(init): ");
+ 		else
+ 			appendStringInfo(buf, "hot_update: ");
+ 		out_target(buf, &(xlrec->target));
+ 		appendStringInfo(buf, "; new %u/%u",
+ 						 ItemPointerGetBlockNumber(&(xlrec->newtid)),
+ 						 ItemPointerGetOffsetNumber(&(xlrec->newtid)));
+ 	}
+ 	else if (info == XLOG_HEAP_NEWPAGE)
+ 	{
+ 		xl_heap_newpage *xlrec = (xl_heap_newpage *) rec;
+ 
+ 		appendStringInfo(buf, "newpage: rel %u/%u/%u; fork %u, blk %u",
+ 						 xlrec->node.spcNode, xlrec->node.dbNode,
+ 						 xlrec->node.relNode, xlrec->forknum,
+ 						 xlrec->blkno);
+ 	}
+ 	else if (info == XLOG_HEAP_LOCK)
+ 	{
+ 		xl_heap_lock *xlrec = (xl_heap_lock *) rec;
+ 
+ 		if (xlrec->shared_lock)
+ 			appendStringInfo(buf, "shared_lock: ");
+ 		else
+ 			appendStringInfo(buf, "exclusive_lock: ");
+ 		if (xlrec->xid_is_mxact)
+ 			appendStringInfo(buf, "mxid ");
+ 		else
+ 			appendStringInfo(buf, "xid ");
+ 		appendStringInfo(buf, "%u ", xlrec->locking_xid);
+ 		out_target(buf, &(xlrec->target));
+ 	}
+ 	else if (info == XLOG_HEAP_INPLACE)
+ 	{
+ 		xl_heap_inplace *xlrec = (xl_heap_inplace *) rec;
+ 
+ 		appendStringInfo(buf, "inplace: ");
+ 		out_target(buf, &(xlrec->target));
+ 	}
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
+ }
+ 
+ void
+ heap2_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	info &= XLOG_HEAP_OPMASK;
+ 	if (info == XLOG_HEAP2_FREEZE)
+ 	{
+ 		xl_heap_freeze *xlrec = (xl_heap_freeze *) rec;
+ 
+ 		appendStringInfo(buf, "freeze: rel %u/%u/%u; blk %u; cutoff %u",
+ 						 xlrec->node.spcNode, xlrec->node.dbNode,
+ 						 xlrec->node.relNode, xlrec->block,
+ 						 xlrec->cutoff_xid);
+ 	}
+ 	else if (info == XLOG_HEAP2_CLEAN)
+ 	{
+ 		xl_heap_clean *xlrec = (xl_heap_clean *) rec;
+ 
+ 		appendStringInfo(buf, "clean: rel %u/%u/%u; blk %u remxid %u",
+ 						 xlrec->node.spcNode, xlrec->node.dbNode,
+ 						 xlrec->node.relNode, xlrec->block,
+ 						 xlrec->latestRemovedXid);
+ 	}
+ 	else if (info == XLOG_HEAP2_CLEANUP_INFO)
+ 	{
+ 		xl_heap_cleanup_info *xlrec = (xl_heap_cleanup_info *) rec;
+ 
+ 		appendStringInfo(buf, "cleanup info: remxid %u",
+ 						 xlrec->latestRemovedXid);
+ 	}
+ 	else if (info == XLOG_HEAP2_VISIBLE)
+ 	{
+ 		xl_heap_visible *xlrec = (xl_heap_visible *) rec;
+ 
+ 		appendStringInfo(buf, "visible: rel %u/%u/%u; blk %u",
+ 						 xlrec->node.spcNode, xlrec->node.dbNode,
+ 						 xlrec->node.relNode, xlrec->block);
+ 	}
+ 	else if (info == XLOG_HEAP2_MULTI_INSERT)
+ 	{
+ 		xl_heap_multi_insert *xlrec = (xl_heap_multi_insert *) rec;
+ 
+ 		if (xl_info & XLOG_HEAP_INIT_PAGE)
+ 			appendStringInfo(buf, "multi-insert (init): ");
+ 		else
+ 			appendStringInfo(buf, "multi-insert: ");
+ 		appendStringInfo(buf, "rel %u/%u/%u; blk %u; %d tuples",
+ 				xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode,
+ 						 xlrec->blkno, xlrec->ntuples);
+ 	}
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
+ }
*** a/src/backend/access/nbtree/Makefile
--- b/src/backend/access/nbtree/Makefile
***************
*** 13,18 **** top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
  OBJS = nbtcompare.o nbtinsert.o nbtpage.o nbtree.o nbtsearch.o \
!        nbtutils.o nbtsort.o nbtxlog.o
  
  include $(top_srcdir)/src/backend/common.mk
--- 13,18 ----
  include $(top_builddir)/src/Makefile.global
  
  OBJS = nbtcompare.o nbtinsert.o nbtpage.o nbtree.o nbtsearch.o \
!        nbtutils.o nbtsort.o nbtxlog.o nbtdesc.o
  
  include $(top_srcdir)/src/backend/common.mk
*** /dev/null
--- b/src/backend/access/nbtree/nbtdesc.c
***************
*** 0 ****
--- 1,148 ----
+ #include "postgres.h"
+ 
+ #include "access/nbtree.h"
+ 
+ static void
+ out_target(StringInfo buf, xl_btreetid *target)
+ {
+ 	appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
+ 			 target->node.spcNode, target->node.dbNode, target->node.relNode,
+ 					 ItemPointerGetBlockNumber(&(target->tid)),
+ 					 ItemPointerGetOffsetNumber(&(target->tid)));
+ }
+ 
+ void
+ btree_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	switch (info)
+ 	{
+ 		case XLOG_BTREE_INSERT_LEAF:
+ 			{
+ 				xl_btree_insert *xlrec = (xl_btree_insert *) rec;
+ 
+ 				appendStringInfo(buf, "insert: ");
+ 				out_target(buf, &(xlrec->target));
+ 				break;
+ 			}
+ 		case XLOG_BTREE_INSERT_UPPER:
+ 			{
+ 				xl_btree_insert *xlrec = (xl_btree_insert *) rec;
+ 
+ 				appendStringInfo(buf, "insert_upper: ");
+ 				out_target(buf, &(xlrec->target));
+ 				break;
+ 			}
+ 		case XLOG_BTREE_INSERT_META:
+ 			{
+ 				xl_btree_insert *xlrec = (xl_btree_insert *) rec;
+ 
+ 				appendStringInfo(buf, "insert_meta: ");
+ 				out_target(buf, &(xlrec->target));
+ 				break;
+ 			}
+ 		case XLOG_BTREE_SPLIT_L:
+ 			{
+ 				xl_btree_split *xlrec = (xl_btree_split *) rec;
+ 
+ 				appendStringInfo(buf, "split_l: rel %u/%u/%u ",
+ 								 xlrec->node.spcNode, xlrec->node.dbNode,
+ 								 xlrec->node.relNode);
+ 				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
+ 							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
+ 								 xlrec->level, xlrec->firstright);
+ 				break;
+ 			}
+ 		case XLOG_BTREE_SPLIT_R:
+ 			{
+ 				xl_btree_split *xlrec = (xl_btree_split *) rec;
+ 
+ 				appendStringInfo(buf, "split_r: rel %u/%u/%u ",
+ 								 xlrec->node.spcNode, xlrec->node.dbNode,
+ 								 xlrec->node.relNode);
+ 				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
+ 							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
+ 								 xlrec->level, xlrec->firstright);
+ 				break;
+ 			}
+ 		case XLOG_BTREE_SPLIT_L_ROOT:
+ 			{
+ 				xl_btree_split *xlrec = (xl_btree_split *) rec;
+ 
+ 				appendStringInfo(buf, "split_l_root: rel %u/%u/%u ",
+ 								 xlrec->node.spcNode, xlrec->node.dbNode,
+ 								 xlrec->node.relNode);
+ 				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
+ 							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
+ 								 xlrec->level, xlrec->firstright);
+ 				break;
+ 			}
+ 		case XLOG_BTREE_SPLIT_R_ROOT:
+ 			{
+ 				xl_btree_split *xlrec = (xl_btree_split *) rec;
+ 
+ 				appendStringInfo(buf, "split_r_root: rel %u/%u/%u ",
+ 								 xlrec->node.spcNode, xlrec->node.dbNode,
+ 								 xlrec->node.relNode);
+ 				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
+ 							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
+ 								 xlrec->level, xlrec->firstright);
+ 				break;
+ 			}
+ 		case XLOG_BTREE_VACUUM:
+ 			{
+ 				xl_btree_vacuum *xlrec = (xl_btree_vacuum *) rec;
+ 
+ 				appendStringInfo(buf, "vacuum: rel %u/%u/%u; blk %u, lastBlockVacuumed %u",
+ 								 xlrec->node.spcNode, xlrec->node.dbNode,
+ 								 xlrec->node.relNode, xlrec->block,
+ 								 xlrec->lastBlockVacuumed);
+ 				break;
+ 			}
+ 		case XLOG_BTREE_DELETE:
+ 			{
+ 				xl_btree_delete *xlrec = (xl_btree_delete *) rec;
+ 
+ 				appendStringInfo(buf, "delete: index %u/%u/%u; iblk %u, heap %u/%u/%u;",
+ 				xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode,
+ 								 xlrec->block,
+ 								 xlrec->hnode.spcNode, xlrec->hnode.dbNode, xlrec->hnode.relNode);
+ 				break;
+ 			}
+ 		case XLOG_BTREE_DELETE_PAGE:
+ 		case XLOG_BTREE_DELETE_PAGE_META:
+ 		case XLOG_BTREE_DELETE_PAGE_HALF:
+ 			{
+ 				xl_btree_delete_page *xlrec = (xl_btree_delete_page *) rec;
+ 
+ 				appendStringInfo(buf, "delete_page: ");
+ 				out_target(buf, &(xlrec->target));
+ 				appendStringInfo(buf, "; dead %u; left %u; right %u",
+ 							xlrec->deadblk, xlrec->leftblk, xlrec->rightblk);
+ 				break;
+ 			}
+ 		case XLOG_BTREE_NEWROOT:
+ 			{
+ 				xl_btree_newroot *xlrec = (xl_btree_newroot *) rec;
+ 
+ 				appendStringInfo(buf, "newroot: rel %u/%u/%u; root %u lev %u",
+ 								 xlrec->node.spcNode, xlrec->node.dbNode,
+ 								 xlrec->node.relNode,
+ 								 xlrec->rootblk, xlrec->level);
+ 				break;
+ 			}
+ 		case XLOG_BTREE_REUSE_PAGE:
+ 			{
+ 				xl_btree_reuse_page *xlrec = (xl_btree_reuse_page *) rec;
+ 
+ 				appendStringInfo(buf, "reuse_page: rel %u/%u/%u; latestRemovedXid %u",
+ 								 xlrec->node.spcNode, xlrec->node.dbNode,
+ 							   xlrec->node.relNode, xlrec->latestRemovedXid);
+ 				break;
+ 			}
+ 		default:
+ 			appendStringInfo(buf, "UNKNOWN");
+ 			break;
+ 	}
+ }
*** a/src/backend/access/nbtree/nbtxlog.c
--- b/src/backend/access/nbtree/nbtxlog.c
***************
*** 1059,1209 **** btree_redo(XLogRecPtr lsn, XLogRecord *record)
  	}
  }
  
- static void
- out_target(StringInfo buf, xl_btreetid *target)
- {
- 	appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
- 			 target->node.spcNode, target->node.dbNode, target->node.relNode,
- 					 ItemPointerGetBlockNumber(&(target->tid)),
- 					 ItemPointerGetOffsetNumber(&(target->tid)));
- }
- 
- void
- btree_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	switch (info)
- 	{
- 		case XLOG_BTREE_INSERT_LEAF:
- 			{
- 				xl_btree_insert *xlrec = (xl_btree_insert *) rec;
- 
- 				appendStringInfo(buf, "insert: ");
- 				out_target(buf, &(xlrec->target));
- 				break;
- 			}
- 		case XLOG_BTREE_INSERT_UPPER:
- 			{
- 				xl_btree_insert *xlrec = (xl_btree_insert *) rec;
- 
- 				appendStringInfo(buf, "insert_upper: ");
- 				out_target(buf, &(xlrec->target));
- 				break;
- 			}
- 		case XLOG_BTREE_INSERT_META:
- 			{
- 				xl_btree_insert *xlrec = (xl_btree_insert *) rec;
- 
- 				appendStringInfo(buf, "insert_meta: ");
- 				out_target(buf, &(xlrec->target));
- 				break;
- 			}
- 		case XLOG_BTREE_SPLIT_L:
- 			{
- 				xl_btree_split *xlrec = (xl_btree_split *) rec;
- 
- 				appendStringInfo(buf, "split_l: rel %u/%u/%u ",
- 								 xlrec->node.spcNode, xlrec->node.dbNode,
- 								 xlrec->node.relNode);
- 				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
- 							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
- 								 xlrec->level, xlrec->firstright);
- 				break;
- 			}
- 		case XLOG_BTREE_SPLIT_R:
- 			{
- 				xl_btree_split *xlrec = (xl_btree_split *) rec;
- 
- 				appendStringInfo(buf, "split_r: rel %u/%u/%u ",
- 								 xlrec->node.spcNode, xlrec->node.dbNode,
- 								 xlrec->node.relNode);
- 				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
- 							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
- 								 xlrec->level, xlrec->firstright);
- 				break;
- 			}
- 		case XLOG_BTREE_SPLIT_L_ROOT:
- 			{
- 				xl_btree_split *xlrec = (xl_btree_split *) rec;
- 
- 				appendStringInfo(buf, "split_l_root: rel %u/%u/%u ",
- 								 xlrec->node.spcNode, xlrec->node.dbNode,
- 								 xlrec->node.relNode);
- 				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
- 							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
- 								 xlrec->level, xlrec->firstright);
- 				break;
- 			}
- 		case XLOG_BTREE_SPLIT_R_ROOT:
- 			{
- 				xl_btree_split *xlrec = (xl_btree_split *) rec;
- 
- 				appendStringInfo(buf, "split_r_root: rel %u/%u/%u ",
- 								 xlrec->node.spcNode, xlrec->node.dbNode,
- 								 xlrec->node.relNode);
- 				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",
- 							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,
- 								 xlrec->level, xlrec->firstright);
- 				break;
- 			}
- 		case XLOG_BTREE_VACUUM:
- 			{
- 				xl_btree_vacuum *xlrec = (xl_btree_vacuum *) rec;
- 
- 				appendStringInfo(buf, "vacuum: rel %u/%u/%u; blk %u, lastBlockVacuumed %u",
- 								 xlrec->node.spcNode, xlrec->node.dbNode,
- 								 xlrec->node.relNode, xlrec->block,
- 								 xlrec->lastBlockVacuumed);
- 				break;
- 			}
- 		case XLOG_BTREE_DELETE:
- 			{
- 				xl_btree_delete *xlrec = (xl_btree_delete *) rec;
- 
- 				appendStringInfo(buf, "delete: index %u/%u/%u; iblk %u, heap %u/%u/%u;",
- 				xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode,
- 								 xlrec->block,
- 								 xlrec->hnode.spcNode, xlrec->hnode.dbNode, xlrec->hnode.relNode);
- 				break;
- 			}
- 		case XLOG_BTREE_DELETE_PAGE:
- 		case XLOG_BTREE_DELETE_PAGE_META:
- 		case XLOG_BTREE_DELETE_PAGE_HALF:
- 			{
- 				xl_btree_delete_page *xlrec = (xl_btree_delete_page *) rec;
- 
- 				appendStringInfo(buf, "delete_page: ");
- 				out_target(buf, &(xlrec->target));
- 				appendStringInfo(buf, "; dead %u; left %u; right %u",
- 							xlrec->deadblk, xlrec->leftblk, xlrec->rightblk);
- 				break;
- 			}
- 		case XLOG_BTREE_NEWROOT:
- 			{
- 				xl_btree_newroot *xlrec = (xl_btree_newroot *) rec;
- 
- 				appendStringInfo(buf, "newroot: rel %u/%u/%u; root %u lev %u",
- 								 xlrec->node.spcNode, xlrec->node.dbNode,
- 								 xlrec->node.relNode,
- 								 xlrec->rootblk, xlrec->level);
- 				break;
- 			}
- 		case XLOG_BTREE_REUSE_PAGE:
- 			{
- 				xl_btree_reuse_page *xlrec = (xl_btree_reuse_page *) rec;
- 
- 				appendStringInfo(buf, "reuse_page: rel %u/%u/%u; latestRemovedXid %u",
- 								 xlrec->node.spcNode, xlrec->node.dbNode,
- 							   xlrec->node.relNode, xlrec->latestRemovedXid);
- 				break;
- 			}
- 		default:
- 			appendStringInfo(buf, "UNKNOWN");
- 			break;
- 	}
- }
- 
  void
  btree_xlog_startup(void)
  {
--- 1059,1064 ----
*** a/src/backend/access/spgist/Makefile
--- b/src/backend/access/spgist/Makefile
***************
*** 13,19 **** top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
  OBJS = spgutils.o spginsert.o spgscan.o spgvacuum.o \
! 	spgdoinsert.o spgxlog.o \
  	spgtextproc.o spgquadtreeproc.o spgkdtreeproc.o
  
  include $(top_srcdir)/src/backend/common.mk
--- 13,19 ----
  include $(top_builddir)/src/Makefile.global
  
  OBJS = spgutils.o spginsert.o spgscan.o spgvacuum.o \
! 	spgdoinsert.o spgxlog.o spgdesc.o \
  	spgtextproc.o spgquadtreeproc.o spgkdtreeproc.o
  
  include $(top_srcdir)/src/backend/common.mk
*** /dev/null
--- b/src/backend/access/spgist/spgdesc.c
***************
*** 0 ****
--- 1,75 ----
+ #include "postgres.h"
+ 
+ #include "access/spgist_private.h"
+ 
+ static void
+ out_target(StringInfo buf, RelFileNode node)
+ {
+ 	appendStringInfo(buf, "rel %u/%u/%u ",
+ 					 node.spcNode, node.dbNode, node.relNode);
+ }
+ 
+ void
+ spg_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	switch (info)
+ 	{
+ 		case XLOG_SPGIST_CREATE_INDEX:
+ 			appendStringInfo(buf, "create_index: rel %u/%u/%u",
+ 							 ((RelFileNode *) rec)->spcNode,
+ 							 ((RelFileNode *) rec)->dbNode,
+ 							 ((RelFileNode *) rec)->relNode);
+ 			break;
+ 		case XLOG_SPGIST_ADD_LEAF:
+ 			out_target(buf, ((spgxlogAddLeaf *) rec)->node);
+ 			appendStringInfo(buf, "add leaf to page: %u",
+ 							 ((spgxlogAddLeaf *) rec)->blknoLeaf);
+ 			break;
+ 		case XLOG_SPGIST_MOVE_LEAFS:
+ 			out_target(buf, ((spgxlogMoveLeafs *) rec)->node);
+ 			appendStringInfo(buf, "move %u leafs from page %u to page %u",
+ 							 ((spgxlogMoveLeafs *) rec)->nMoves,
+ 							 ((spgxlogMoveLeafs *) rec)->blknoSrc,
+ 							 ((spgxlogMoveLeafs *) rec)->blknoDst);
+ 			break;
+ 		case XLOG_SPGIST_ADD_NODE:
+ 			out_target(buf, ((spgxlogAddNode *) rec)->node);
+ 			appendStringInfo(buf, "add node to %u:%u",
+ 							 ((spgxlogAddNode *) rec)->blkno,
+ 							 ((spgxlogAddNode *) rec)->offnum);
+ 			break;
+ 		case XLOG_SPGIST_SPLIT_TUPLE:
+ 			out_target(buf, ((spgxlogSplitTuple *) rec)->node);
+ 			appendStringInfo(buf, "split node %u:%u to %u:%u",
+ 							 ((spgxlogSplitTuple *) rec)->blknoPrefix,
+ 							 ((spgxlogSplitTuple *) rec)->offnumPrefix,
+ 							 ((spgxlogSplitTuple *) rec)->blknoPostfix,
+ 							 ((spgxlogSplitTuple *) rec)->offnumPostfix);
+ 			break;
+ 		case XLOG_SPGIST_PICKSPLIT:
+ 			out_target(buf, ((spgxlogPickSplit *) rec)->node);
+ 			appendStringInfo(buf, "split leaf page");
+ 			break;
+ 		case XLOG_SPGIST_VACUUM_LEAF:
+ 			out_target(buf, ((spgxlogVacuumLeaf *) rec)->node);
+ 			appendStringInfo(buf, "vacuum leaf tuples on page %u",
+ 							 ((spgxlogVacuumLeaf *) rec)->blkno);
+ 			break;
+ 		case XLOG_SPGIST_VACUUM_ROOT:
+ 			out_target(buf, ((spgxlogVacuumRoot *) rec)->node);
+ 			appendStringInfo(buf, "vacuum leaf tuples on root page %u",
+ 							 ((spgxlogVacuumRoot *) rec)->blkno);
+ 			break;
+ 		case XLOG_SPGIST_VACUUM_REDIRECT:
+ 			out_target(buf, ((spgxlogVacuumRedirect *) rec)->node);
+ 			appendStringInfo(buf, "vacuum redirect tuples on page %u, newest XID %u",
+ 							 ((spgxlogVacuumRedirect *) rec)->blkno,
+ 						 ((spgxlogVacuumRedirect *) rec)->newestRedirectXid);
+ 			break;
+ 		default:
+ 			appendStringInfo(buf, "unknown spgist op code %u", info);
+ 			break;
+ 	}
+ }
*** a/src/backend/access/spgist/spgxlog.c
--- b/src/backend/access/spgist/spgxlog.c
***************
*** 1022,1099 **** spg_redo(XLogRecPtr lsn, XLogRecord *record)
  	MemoryContextReset(opCtx);
  }
  
- static void
- out_target(StringInfo buf, RelFileNode node)
- {
- 	appendStringInfo(buf, "rel %u/%u/%u ",
- 					 node.spcNode, node.dbNode, node.relNode);
- }
- 
- void
- spg_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	switch (info)
- 	{
- 		case XLOG_SPGIST_CREATE_INDEX:
- 			appendStringInfo(buf, "create_index: rel %u/%u/%u",
- 							 ((RelFileNode *) rec)->spcNode,
- 							 ((RelFileNode *) rec)->dbNode,
- 							 ((RelFileNode *) rec)->relNode);
- 			break;
- 		case XLOG_SPGIST_ADD_LEAF:
- 			out_target(buf, ((spgxlogAddLeaf *) rec)->node);
- 			appendStringInfo(buf, "add leaf to page: %u",
- 							 ((spgxlogAddLeaf *) rec)->blknoLeaf);
- 			break;
- 		case XLOG_SPGIST_MOVE_LEAFS:
- 			out_target(buf, ((spgxlogMoveLeafs *) rec)->node);
- 			appendStringInfo(buf, "move %u leafs from page %u to page %u",
- 							 ((spgxlogMoveLeafs *) rec)->nMoves,
- 							 ((spgxlogMoveLeafs *) rec)->blknoSrc,
- 							 ((spgxlogMoveLeafs *) rec)->blknoDst);
- 			break;
- 		case XLOG_SPGIST_ADD_NODE:
- 			out_target(buf, ((spgxlogAddNode *) rec)->node);
- 			appendStringInfo(buf, "add node to %u:%u",
- 							 ((spgxlogAddNode *) rec)->blkno,
- 							 ((spgxlogAddNode *) rec)->offnum);
- 			break;
- 		case XLOG_SPGIST_SPLIT_TUPLE:
- 			out_target(buf, ((spgxlogSplitTuple *) rec)->node);
- 			appendStringInfo(buf, "split node %u:%u to %u:%u",
- 							 ((spgxlogSplitTuple *) rec)->blknoPrefix,
- 							 ((spgxlogSplitTuple *) rec)->offnumPrefix,
- 							 ((spgxlogSplitTuple *) rec)->blknoPostfix,
- 							 ((spgxlogSplitTuple *) rec)->offnumPostfix);
- 			break;
- 		case XLOG_SPGIST_PICKSPLIT:
- 			out_target(buf, ((spgxlogPickSplit *) rec)->node);
- 			appendStringInfo(buf, "split leaf page");
- 			break;
- 		case XLOG_SPGIST_VACUUM_LEAF:
- 			out_target(buf, ((spgxlogVacuumLeaf *) rec)->node);
- 			appendStringInfo(buf, "vacuum leaf tuples on page %u",
- 							 ((spgxlogVacuumLeaf *) rec)->blkno);
- 			break;
- 		case XLOG_SPGIST_VACUUM_ROOT:
- 			out_target(buf, ((spgxlogVacuumRoot *) rec)->node);
- 			appendStringInfo(buf, "vacuum leaf tuples on root page %u",
- 							 ((spgxlogVacuumRoot *) rec)->blkno);
- 			break;
- 		case XLOG_SPGIST_VACUUM_REDIRECT:
- 			out_target(buf, ((spgxlogVacuumRedirect *) rec)->node);
- 			appendStringInfo(buf, "vacuum redirect tuples on page %u, newest XID %u",
- 							 ((spgxlogVacuumRedirect *) rec)->blkno,
- 						 ((spgxlogVacuumRedirect *) rec)->newestRedirectXid);
- 			break;
- 		default:
- 			appendStringInfo(buf, "unknown spgist op code %u", info);
- 			break;
- 	}
- }
- 
  void
  spg_xlog_startup(void)
  {
--- 1022,1027 ----
*** a/src/backend/access/transam/Makefile
--- b/src/backend/access/transam/Makefile
***************
*** 14,20 **** include $(top_builddir)/src/Makefile.global
  
  OBJS = clog.o transam.o varsup.o xact.o rmgr.o slru.o subtrans.o multixact.o \
  	timeline.o twophase.o twophase_rmgr.o xlog.o xlogarchive.o xlogfuncs.o \
! 	xlogutils.o
  
  include $(top_srcdir)/src/backend/common.mk
  
--- 14,20 ----
  
  OBJS = clog.o transam.o varsup.o xact.o rmgr.o slru.o subtrans.o multixact.o \
  	timeline.o twophase.o twophase_rmgr.o xlog.o xlogarchive.o xlogfuncs.o \
! 	xlogutils.o clog_desc.o mxact_desc.o xact_desc.o xlog_desc.o
  
  include $(top_srcdir)/src/backend/common.mk
  
*** a/src/backend/access/transam/clog.c
--- b/src/backend/access/transam/clog.c
***************
*** 768,793 **** clog_redo(XLogRecPtr lsn, XLogRecord *record)
  	else
  		elog(PANIC, "clog_redo: unknown op code %u", info);
  }
- 
- void
- clog_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	if (info == CLOG_ZEROPAGE)
- 	{
- 		int			pageno;
- 
- 		memcpy(&pageno, rec, sizeof(int));
- 		appendStringInfo(buf, "zeropage: %d", pageno);
- 	}
- 	else if (info == CLOG_TRUNCATE)
- 	{
- 		int			pageno;
- 
- 		memcpy(&pageno, rec, sizeof(int));
- 		appendStringInfo(buf, "truncate before: %d", pageno);
- 	}
- 	else
- 		appendStringInfo(buf, "UNKNOWN");
- }
--- 768,770 ----
*** /dev/null
--- b/src/backend/access/transam/clog_desc.c
***************
*** 0 ****
--- 1,30 ----
+ #include "postgres.h"
+ 
+ #include "access/clog.h"
+ #include "access/xlog.h"
+ #include "lib/stringinfo.h"
+ #include "storage/relfilenode.h"
+ 
+ 
+ void
+ clog_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	if (info == CLOG_ZEROPAGE)
+ 	{
+ 		int			pageno;
+ 
+ 		memcpy(&pageno, rec, sizeof(int));
+ 		appendStringInfo(buf, "zeropage: %d", pageno);
+ 	}
+ 	else if (info == CLOG_TRUNCATE)
+ 	{
+ 		int			pageno;
+ 
+ 		memcpy(&pageno, rec, sizeof(int));
+ 		appendStringInfo(buf, "truncate before: %d", pageno);
+ 	}
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
+ }
*** a/src/backend/access/transam/multixact.c
--- b/src/backend/access/transam/multixact.c
***************
*** 2053,2088 **** multixact_redo(XLogRecPtr lsn, XLogRecord *record)
  	else
  		elog(PANIC, "multixact_redo: unknown op code %u", info);
  }
- 
- void
- multixact_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	if (info == XLOG_MULTIXACT_ZERO_OFF_PAGE)
- 	{
- 		int			pageno;
- 
- 		memcpy(&pageno, rec, sizeof(int));
- 		appendStringInfo(buf, "zero offsets page: %d", pageno);
- 	}
- 	else if (info == XLOG_MULTIXACT_ZERO_MEM_PAGE)
- 	{
- 		int			pageno;
- 
- 		memcpy(&pageno, rec, sizeof(int));
- 		appendStringInfo(buf, "zero members page: %d", pageno);
- 	}
- 	else if (info == XLOG_MULTIXACT_CREATE_ID)
- 	{
- 		xl_multixact_create *xlrec = (xl_multixact_create *) rec;
- 		int			i;
- 
- 		appendStringInfo(buf, "create multixact %u offset %u:",
- 						 xlrec->mid, xlrec->moff);
- 		for (i = 0; i < xlrec->nxids; i++)
- 			appendStringInfo(buf, " %u", xlrec->xids[i]);
- 	}
- 	else
- 		appendStringInfo(buf, "UNKNOWN");
- }
--- 2053,2055 ----
*** /dev/null
--- b/src/backend/access/transam/mxact_desc.c
***************
*** 0 ****
--- 1,39 ----
+ #include "postgres.h"
+ 
+ #include "access/xlog.h"
+ #include "access/multixact.h"
+ #include "lib/stringinfo.h"
+ 
+ 
+ void
+ multixact_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	if (info == XLOG_MULTIXACT_ZERO_OFF_PAGE)
+ 	{
+ 		int			pageno;
+ 
+ 		memcpy(&pageno, rec, sizeof(int));
+ 		appendStringInfo(buf, "zero offsets page: %d", pageno);
+ 	}
+ 	else if (info == XLOG_MULTIXACT_ZERO_MEM_PAGE)
+ 	{
+ 		int			pageno;
+ 
+ 		memcpy(&pageno, rec, sizeof(int));
+ 		appendStringInfo(buf, "zero members page: %d", pageno);
+ 	}
+ 	else if (info == XLOG_MULTIXACT_CREATE_ID)
+ 	{
+ 		xl_multixact_create *xlrec = (xl_multixact_create *) rec;
+ 		int			i;
+ 
+ 		appendStringInfo(buf, "create multixact %u offset %u:",
+ 						 xlrec->mid, xlrec->moff);
+ 		for (i = 0; i < xlrec->nxids; i++)
+ 			appendStringInfo(buf, " %u", xlrec->xids[i]);
+ 	}
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
+ }
*** a/src/backend/access/transam/xact.c
--- b/src/backend/access/transam/xact.c
***************
*** 4823,4998 **** xact_redo(XLogRecPtr lsn, XLogRecord *record)
  	else
  		elog(PANIC, "xact_redo: unknown op code %u", info);
  }
- 
- static void
- xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
- {
- 	int			i;
- 	TransactionId *subxacts;
- 
- 	subxacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
- 
- 	appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
- 
- 	if (xlrec->nrels > 0)
- 	{
- 		appendStringInfo(buf, "; rels:");
- 		for (i = 0; i < xlrec->nrels; i++)
- 		{
- 			char	   *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
- 
- 			appendStringInfo(buf, " %s", path);
- 			pfree(path);
- 		}
- 	}
- 	if (xlrec->nsubxacts > 0)
- 	{
- 		appendStringInfo(buf, "; subxacts:");
- 		for (i = 0; i < xlrec->nsubxacts; i++)
- 			appendStringInfo(buf, " %u", subxacts[i]);
- 	}
- 	if (xlrec->nmsgs > 0)
- 	{
- 		SharedInvalidationMessage *msgs;
- 
- 		msgs = (SharedInvalidationMessage *) &subxacts[xlrec->nsubxacts];
- 
- 		if (XactCompletionRelcacheInitFileInval(xlrec->xinfo))
- 			appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
- 							 xlrec->dbId, xlrec->tsId);
- 
- 		appendStringInfo(buf, "; inval msgs:");
- 		for (i = 0; i < xlrec->nmsgs; i++)
- 		{
- 			SharedInvalidationMessage *msg = &msgs[i];
- 
- 			if (msg->id >= 0)
- 				appendStringInfo(buf, " catcache %d", msg->id);
- 			else if (msg->id == SHAREDINVALCATALOG_ID)
- 				appendStringInfo(buf, " catalog %u", msg->cat.catId);
- 			else if (msg->id == SHAREDINVALRELCACHE_ID)
- 				appendStringInfo(buf, " relcache %u", msg->rc.relId);
- 			/* remaining cases not expected, but print something anyway */
- 			else if (msg->id == SHAREDINVALSMGR_ID)
- 				appendStringInfo(buf, " smgr");
- 			else if (msg->id == SHAREDINVALRELMAP_ID)
- 				appendStringInfo(buf, " relmap");
- 			else
- 				appendStringInfo(buf, " unknown id %d", msg->id);
- 		}
- 	}
- }
- 
- static void
- xact_desc_commit_compact(StringInfo buf, xl_xact_commit_compact *xlrec)
- {
- 	int			i;
- 
- 	appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
- 
- 	if (xlrec->nsubxacts > 0)
- 	{
- 		appendStringInfo(buf, "; subxacts:");
- 		for (i = 0; i < xlrec->nsubxacts; i++)
- 			appendStringInfo(buf, " %u", xlrec->subxacts[i]);
- 	}
- }
- 
- static void
- xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
- {
- 	int			i;
- 
- 	appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
- 	if (xlrec->nrels > 0)
- 	{
- 		appendStringInfo(buf, "; rels:");
- 		for (i = 0; i < xlrec->nrels; i++)
- 		{
- 			char	   *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
- 
- 			appendStringInfo(buf, " %s", path);
- 			pfree(path);
- 		}
- 	}
- 	if (xlrec->nsubxacts > 0)
- 	{
- 		TransactionId *xacts = (TransactionId *)
- 		&xlrec->xnodes[xlrec->nrels];
- 
- 		appendStringInfo(buf, "; subxacts:");
- 		for (i = 0; i < xlrec->nsubxacts; i++)
- 			appendStringInfo(buf, " %u", xacts[i]);
- 	}
- }
- 
- static void
- xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
- {
- 	int			i;
- 
- 	appendStringInfo(buf, "subxacts:");
- 
- 	for (i = 0; i < xlrec->nsubxacts; i++)
- 		appendStringInfo(buf, " %u", xlrec->xsub[i]);
- }
- 
- void
- xact_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	if (info == XLOG_XACT_COMMIT_COMPACT)
- 	{
- 		xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) rec;
- 
- 		appendStringInfo(buf, "commit: ");
- 		xact_desc_commit_compact(buf, xlrec);
- 	}
- 	else if (info == XLOG_XACT_COMMIT)
- 	{
- 		xl_xact_commit *xlrec = (xl_xact_commit *) rec;
- 
- 		appendStringInfo(buf, "commit: ");
- 		xact_desc_commit(buf, xlrec);
- 	}
- 	else if (info == XLOG_XACT_ABORT)
- 	{
- 		xl_xact_abort *xlrec = (xl_xact_abort *) rec;
- 
- 		appendStringInfo(buf, "abort: ");
- 		xact_desc_abort(buf, xlrec);
- 	}
- 	else if (info == XLOG_XACT_PREPARE)
- 	{
- 		appendStringInfo(buf, "prepare");
- 	}
- 	else if (info == XLOG_XACT_COMMIT_PREPARED)
- 	{
- 		xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
- 
- 		appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
- 		xact_desc_commit(buf, &xlrec->crec);
- 	}
- 	else if (info == XLOG_XACT_ABORT_PREPARED)
- 	{
- 		xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
- 
- 		appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
- 		xact_desc_abort(buf, &xlrec->arec);
- 	}
- 	else if (info == XLOG_XACT_ASSIGNMENT)
- 	{
- 		xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
- 
- 		/*
- 		 * Note that we ignore the WAL record's xid, since we're more
- 		 * interested in the top-level xid that issued the record and which
- 		 * xids are being reported here.
- 		 */
- 		appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
- 		xact_desc_assignment(buf, xlrec);
- 	}
- 	else
- 		appendStringInfo(buf, "UNKNOWN");
- }
--- 4823,4825 ----
*** /dev/null
--- b/src/backend/access/transam/xact_desc.c
***************
*** 0 ****
--- 1,182 ----
+ #include "postgres.h"
+ 
+ #include "access/xact.h"
+ #include "catalog/catalog.h"
+ #include "lib/stringinfo.h"
+ #include "storage/sinval.h"
+ #include "storage/relfilenode.h"
+ #include "utils/timestamp.h"
+ 
+ 
+ static void
+ xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
+ {
+ 	int			i;
+ 	TransactionId *subxacts;
+ 
+ 	subxacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
+ 
+ 	appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
+ 
+ 	if (xlrec->nrels > 0)
+ 	{
+ 		appendStringInfo(buf, "; rels:");
+ 		for (i = 0; i < xlrec->nrels; i++)
+ 		{
+ 			char	   *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
+ 
+ 			appendStringInfo(buf, " %s", path);
+ 			pfree(path);
+ 		}
+ 	}
+ 	if (xlrec->nsubxacts > 0)
+ 	{
+ 		appendStringInfo(buf, "; subxacts:");
+ 		for (i = 0; i < xlrec->nsubxacts; i++)
+ 			appendStringInfo(buf, " %u", subxacts[i]);
+ 	}
+ 	if (xlrec->nmsgs > 0)
+ 	{
+ 		SharedInvalidationMessage *msgs;
+ 
+ 		msgs = (SharedInvalidationMessage *) &subxacts[xlrec->nsubxacts];
+ 
+ 		if (XactCompletionRelcacheInitFileInval(xlrec->xinfo))
+ 			appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
+ 							 xlrec->dbId, xlrec->tsId);
+ 
+ 		appendStringInfo(buf, "; inval msgs:");
+ 		for (i = 0; i < xlrec->nmsgs; i++)
+ 		{
+ 			SharedInvalidationMessage *msg = &msgs[i];
+ 
+ 			if (msg->id >= 0)
+ 				appendStringInfo(buf, " catcache %d", msg->id);
+ 			else if (msg->id == SHAREDINVALCATALOG_ID)
+ 				appendStringInfo(buf, " catalog %u", msg->cat.catId);
+ 			else if (msg->id == SHAREDINVALRELCACHE_ID)
+ 				appendStringInfo(buf, " relcache %u", msg->rc.relId);
+ 			/* remaining cases not expected, but print something anyway */
+ 			else if (msg->id == SHAREDINVALSMGR_ID)
+ 				appendStringInfo(buf, " smgr");
+ 			else if (msg->id == SHAREDINVALRELMAP_ID)
+ 				appendStringInfo(buf, " relmap");
+ 			else
+ 				appendStringInfo(buf, " unknown id %d", msg->id);
+ 		}
+ 	}
+ }
+ 
+ static void
+ xact_desc_commit_compact(StringInfo buf, xl_xact_commit_compact *xlrec)
+ {
+ 	int			i;
+ 
+ 	appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
+ 
+ 	if (xlrec->nsubxacts > 0)
+ 	{
+ 		appendStringInfo(buf, "; subxacts:");
+ 		for (i = 0; i < xlrec->nsubxacts; i++)
+ 			appendStringInfo(buf, " %u", xlrec->subxacts[i]);
+ 	}
+ }
+ 
+ static void
+ xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
+ {
+ 	int			i;
+ 
+ 	appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
+ 	if (xlrec->nrels > 0)
+ 	{
+ 		appendStringInfo(buf, "; rels:");
+ 		for (i = 0; i < xlrec->nrels; i++)
+ 		{
+ 			char	   *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
+ 
+ 			appendStringInfo(buf, " %s", path);
+ 			pfree(path);
+ 		}
+ 	}
+ 	if (xlrec->nsubxacts > 0)
+ 	{
+ 		TransactionId *xacts = (TransactionId *)
+ 		&xlrec->xnodes[xlrec->nrels];
+ 
+ 		appendStringInfo(buf, "; subxacts:");
+ 		for (i = 0; i < xlrec->nsubxacts; i++)
+ 			appendStringInfo(buf, " %u", xacts[i]);
+ 	}
+ }
+ 
+ static void
+ xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
+ {
+ 	int			i;
+ 
+ 	appendStringInfo(buf, "subxacts:");
+ 
+ 	for (i = 0; i < xlrec->nsubxacts; i++)
+ 		appendStringInfo(buf, " %u", xlrec->xsub[i]);
+ }
+ 
+ void
+ xact_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	if (info == XLOG_XACT_COMMIT_COMPACT)
+ 	{
+ 		xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) rec;
+ 
+ 		appendStringInfo(buf, "commit: ");
+ 		xact_desc_commit_compact(buf, xlrec);
+ 	}
+ 	else if (info == XLOG_XACT_COMMIT)
+ 	{
+ 		xl_xact_commit *xlrec = (xl_xact_commit *) rec;
+ 
+ 		appendStringInfo(buf, "commit: ");
+ 		xact_desc_commit(buf, xlrec);
+ 	}
+ 	else if (info == XLOG_XACT_ABORT)
+ 	{
+ 		xl_xact_abort *xlrec = (xl_xact_abort *) rec;
+ 
+ 		appendStringInfo(buf, "abort: ");
+ 		xact_desc_abort(buf, xlrec);
+ 	}
+ 	else if (info == XLOG_XACT_PREPARE)
+ 	{
+ 		appendStringInfo(buf, "prepare");
+ 	}
+ 	else if (info == XLOG_XACT_COMMIT_PREPARED)
+ 	{
+ 		xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
+ 
+ 		appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
+ 		xact_desc_commit(buf, &xlrec->crec);
+ 	}
+ 	else if (info == XLOG_XACT_ABORT_PREPARED)
+ 	{
+ 		xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
+ 
+ 		appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
+ 		xact_desc_abort(buf, &xlrec->arec);
+ 	}
+ 	else if (info == XLOG_XACT_ASSIGNMENT)
+ 	{
+ 		xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
+ 
+ 		/*
+ 		 * Note that we ignore the WAL record's xid, since we're more
+ 		 * interested in the top-level xid that issued the record and which
+ 		 * xids are being reported here.
+ 		 */
+ 		appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
+ 		xact_desc_assignment(buf, xlrec);
+ 	}
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
+ }
*** a/src/backend/access/transam/xlog.c
--- b/src/backend/access/transam/xlog.c
***************
*** 99,114 **** bool		XLOG_DEBUG = false;
   */
  #define XLOGfileslop	(2*CheckPointSegments + 1)
  
  /*
   * GUC support
   */
- const struct config_enum_entry wal_level_options[] = {
- 	{"minimal", WAL_LEVEL_MINIMAL, false},
- 	{"archive", WAL_LEVEL_ARCHIVE, false},
- 	{"hot_standby", WAL_LEVEL_HOT_STANDBY, false},
- 	{NULL, 0, false}
- };
- 
  const struct config_enum_entry sync_method_options[] = {
  	{"fsync", SYNC_METHOD_FSYNC, false},
  #ifdef HAVE_FSYNC_WRITETHROUGH
--- 99,108 ----
   */
  #define XLOGfileslop	(2*CheckPointSegments + 1)
  
+ 
  /*
   * GUC support
   */
  const struct config_enum_entry sync_method_options[] = {
  	{"fsync", SYNC_METHOD_FSYNC, false},
  #ifdef HAVE_FSYNC_WRITETHROUGH
***************
*** 587,611 **** static bool InRedo = false;
  /* Have we launched bgwriter during recovery? */
  static bool bgwriterLaunched = false;
  
- /*
-  * Information logged when we detect a change in one of the parameters
-  * important for Hot Standby.
-  */
- typedef struct xl_parameter_change
- {
- 	int			MaxConnections;
- 	int			max_prepared_xacts;
- 	int			max_locks_per_xact;
- 	int			wal_level;
- } xl_parameter_change;
- 
- /* logs restore point */
- typedef struct xl_restore_point
- {
- 	TimestampTz rp_time;
- 	char		rp_name[MAXFNAMELEN];
- } xl_restore_point;
- 
  
  static void readRecoveryCommandFile(void);
  static void exitArchiveRecovery(TimeLineID endTLI, XLogSegNo endLogSegNo);
--- 581,586 ----
***************
*** 7982,8078 **** xlog_redo(XLogRecPtr lsn, XLogRecord *record)
  	}
  }
  
- void
- xlog_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	if (info == XLOG_CHECKPOINT_SHUTDOWN ||
- 		info == XLOG_CHECKPOINT_ONLINE)
- 	{
- 		CheckPoint *checkpoint = (CheckPoint *) rec;
- 
- 		appendStringInfo(buf, "checkpoint: redo %X/%X; "
- 				   "tli %u; fpw %s; xid %u/%u; oid %u; multi %u; offset %u; "
- 						 "oldest xid %u in DB %u; oldest running xid %u; %s",
- 						 (uint32) (checkpoint->redo >> 32), (uint32) checkpoint->redo,
- 						 checkpoint->ThisTimeLineID,
- 						 checkpoint->fullPageWrites ? "true" : "false",
- 						 checkpoint->nextXidEpoch, checkpoint->nextXid,
- 						 checkpoint->nextOid,
- 						 checkpoint->nextMulti,
- 						 checkpoint->nextMultiOffset,
- 						 checkpoint->oldestXid,
- 						 checkpoint->oldestXidDB,
- 						 checkpoint->oldestActiveXid,
- 				 (info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
- 	}
- 	else if (info == XLOG_NOOP)
- 	{
- 		appendStringInfo(buf, "xlog no-op");
- 	}
- 	else if (info == XLOG_NEXTOID)
- 	{
- 		Oid			nextOid;
- 
- 		memcpy(&nextOid, rec, sizeof(Oid));
- 		appendStringInfo(buf, "nextOid: %u", nextOid);
- 	}
- 	else if (info == XLOG_SWITCH)
- 	{
- 		appendStringInfo(buf, "xlog switch");
- 	}
- 	else if (info == XLOG_RESTORE_POINT)
- 	{
- 		xl_restore_point *xlrec = (xl_restore_point *) rec;
- 
- 		appendStringInfo(buf, "restore point: %s", xlrec->rp_name);
- 
- 	}
- 	else if (info == XLOG_BACKUP_END)
- 	{
- 		XLogRecPtr	startpoint;
- 
- 		memcpy(&startpoint, rec, sizeof(XLogRecPtr));
- 		appendStringInfo(buf, "backup end: %X/%X",
- 						 (uint32) (startpoint >> 32), (uint32) startpoint);
- 	}
- 	else if (info == XLOG_PARAMETER_CHANGE)
- 	{
- 		xl_parameter_change xlrec;
- 		const char *wal_level_str;
- 		const struct config_enum_entry *entry;
- 
- 		memcpy(&xlrec, rec, sizeof(xl_parameter_change));
- 
- 		/* Find a string representation for wal_level */
- 		wal_level_str = "?";
- 		for (entry = wal_level_options; entry->name; entry++)
- 		{
- 			if (entry->val == xlrec.wal_level)
- 			{
- 				wal_level_str = entry->name;
- 				break;
- 			}
- 		}
- 
- 		appendStringInfo(buf, "parameter change: max_connections=%d max_prepared_xacts=%d max_locks_per_xact=%d wal_level=%s",
- 						 xlrec.MaxConnections,
- 						 xlrec.max_prepared_xacts,
- 						 xlrec.max_locks_per_xact,
- 						 wal_level_str);
- 	}
- 	else if (info == XLOG_FPW_CHANGE)
- 	{
- 		bool		fpw;
- 
- 		memcpy(&fpw, rec, sizeof(bool));
- 		appendStringInfo(buf, "full_page_writes: %s", fpw ? "true" : "false");
- 	}
- 	else
- 		appendStringInfo(buf, "UNKNOWN");
- }
- 
  #ifdef WAL_DEBUG
  
  static void
--- 7957,7962 ----
*** /dev/null
--- b/src/backend/access/transam/xlog_desc.c
***************
*** 0 ****
--- 1,107 ----
+ #include "postgres.h"
+ 
+ #include "access/xlog_internal.h"
+ #include "catalog/pg_control.h"
+ #include "lib/stringinfo.h"
+ #include "utils/guc.h"
+ 
+ /*
+  * GUC support
+  */
+ const struct config_enum_entry wal_level_options[] = {
+ 	{"minimal", WAL_LEVEL_MINIMAL, false},
+ 	{"archive", WAL_LEVEL_ARCHIVE, false},
+ 	{"hot_standby", WAL_LEVEL_HOT_STANDBY, false},
+ 	{NULL, 0, false}
+ };
+ 
+ void
+ xlog_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	if (info == XLOG_CHECKPOINT_SHUTDOWN ||
+ 		info == XLOG_CHECKPOINT_ONLINE)
+ 	{
+ 		CheckPoint *checkpoint = (CheckPoint *) rec;
+ 
+ 		appendStringInfo(buf, "checkpoint: redo %X/%X; "
+ 				   "tli %u; fpw %s; xid %u/%u; oid %u; multi %u; offset %u; "
+ 						 "oldest xid %u in DB %u; oldest running xid %u; %s",
+ 						 (uint32) (checkpoint->redo >> 32), (uint32) checkpoint->redo,
+ 						 checkpoint->ThisTimeLineID,
+ 						 checkpoint->fullPageWrites ? "true" : "false",
+ 						 checkpoint->nextXidEpoch, checkpoint->nextXid,
+ 						 checkpoint->nextOid,
+ 						 checkpoint->nextMulti,
+ 						 checkpoint->nextMultiOffset,
+ 						 checkpoint->oldestXid,
+ 						 checkpoint->oldestXidDB,
+ 						 checkpoint->oldestActiveXid,
+ 				 (info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
+ 	}
+ 	else if (info == XLOG_NOOP)
+ 	{
+ 		appendStringInfo(buf, "xlog no-op");
+ 	}
+ 	else if (info == XLOG_NEXTOID)
+ 	{
+ 		Oid			nextOid;
+ 
+ 		memcpy(&nextOid, rec, sizeof(Oid));
+ 		appendStringInfo(buf, "nextOid: %u", nextOid);
+ 	}
+ 	else if (info == XLOG_SWITCH)
+ 	{
+ 		appendStringInfo(buf, "xlog switch");
+ 	}
+ 	else if (info == XLOG_RESTORE_POINT)
+ 	{
+ 		xl_restore_point *xlrec = (xl_restore_point *) rec;
+ 
+ 		appendStringInfo(buf, "restore point: %s", xlrec->rp_name);
+ 
+ 	}
+ 	else if (info == XLOG_BACKUP_END)
+ 	{
+ 		XLogRecPtr	startpoint;
+ 
+ 		memcpy(&startpoint, rec, sizeof(XLogRecPtr));
+ 		appendStringInfo(buf, "backup end: %X/%X",
+ 						 (uint32) (startpoint >> 32), (uint32) startpoint);
+ 	}
+ 	else if (info == XLOG_PARAMETER_CHANGE)
+ 	{
+ 		xl_parameter_change xlrec;
+ 		const char *wal_level_str;
+ 		const struct config_enum_entry *entry;
+ 
+ 		memcpy(&xlrec, rec, sizeof(xl_parameter_change));
+ 
+ 		/* Find a string representation for wal_level */
+ 		wal_level_str = "?";
+ 		for (entry = wal_level_options; entry->name; entry++)
+ 		{
+ 			if (entry->val == xlrec.wal_level)
+ 			{
+ 				wal_level_str = entry->name;
+ 				break;
+ 			}
+ 		}
+ 
+ 		appendStringInfo(buf, "parameter change: max_connections=%d max_prepared_xacts=%d max_locks_per_xact=%d wal_level=%s",
+ 						 xlrec.MaxConnections,
+ 						 xlrec.max_prepared_xacts,
+ 						 xlrec.max_locks_per_xact,
+ 						 wal_level_str);
+ 	}
+ 	else if (info == XLOG_FPW_CHANGE)
+ 	{
+ 		bool		fpw;
+ 
+ 		memcpy(&fpw, rec, sizeof(bool));
+ 		appendStringInfo(buf, "full_page_writes: %s", fpw ? "true" : "false");
+ 	}
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
+ }
*** a/src/backend/catalog/Makefile
--- b/src/backend/catalog/Makefile
***************
*** 14,20 **** OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
         objectaddress.o pg_aggregate.o pg_collation.o pg_constraint.o pg_conversion.o \
         pg_depend.o pg_enum.o pg_inherits.o pg_largeobject.o pg_namespace.o \
         pg_operator.o pg_proc.o pg_range.o pg_db_role_setting.o pg_shdepend.o \
!        pg_type.o storage.o toasting.o
  
  BKIFILES = postgres.bki postgres.description postgres.shdescription
  
--- 14,20 ----
         objectaddress.o pg_aggregate.o pg_collation.o pg_constraint.o pg_conversion.o \
         pg_depend.o pg_enum.o pg_inherits.o pg_largeobject.o pg_namespace.o \
         pg_operator.o pg_proc.o pg_range.o pg_db_role_setting.o pg_shdepend.o \
!        pg_type.o storage.o toasting.o storage_desc.o
  
  BKIFILES = postgres.bki postgres.description postgres.shdescription
  
*** a/src/backend/catalog/storage.c
--- b/src/backend/catalog/storage.c
***************
*** 61,90 **** typedef struct PendingRelDelete
  static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
  
  /*
-  * Declarations for smgr-related XLOG records
-  *
-  * Note: we log file creation and truncation here, but logging of deletion
-  * actions is handled by xact.c, because it is part of transaction commit.
-  */
- 
- /* XLOG gives us high 4 bits */
- #define XLOG_SMGR_CREATE	0x10
- #define XLOG_SMGR_TRUNCATE	0x20
- 
- typedef struct xl_smgr_create
- {
- 	RelFileNode rnode;
- 	ForkNumber	forkNum;
- } xl_smgr_create;
- 
- typedef struct xl_smgr_truncate
- {
- 	BlockNumber blkno;
- 	RelFileNode rnode;
- } xl_smgr_truncate;
- 
- 
- /*
   * RelationCreateStorage
   *		Create physical storage for a relation.
   *
--- 61,66 ----
***************
*** 523,551 **** smgr_redo(XLogRecPtr lsn, XLogRecord *record)
  	else
  		elog(PANIC, "smgr_redo: unknown op code %u", info);
  }
- 
- void
- smgr_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	if (info == XLOG_SMGR_CREATE)
- 	{
- 		xl_smgr_create *xlrec = (xl_smgr_create *) rec;
- 		char	   *path = relpathperm(xlrec->rnode, xlrec->forkNum);
- 
- 		appendStringInfo(buf, "file create: %s", path);
- 		pfree(path);
- 	}
- 	else if (info == XLOG_SMGR_TRUNCATE)
- 	{
- 		xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec;
- 		char	   *path = relpathperm(xlrec->rnode, MAIN_FORKNUM);
- 
- 		appendStringInfo(buf, "file truncate: %s to %u blocks", path,
- 						 xlrec->blkno);
- 		pfree(path);
- 	}
- 	else
- 		appendStringInfo(buf, "UNKNOWN");
- }
--- 499,501 ----
*** /dev/null
--- b/src/backend/catalog/storage_desc.c
***************
*** 0 ****
--- 1,32 ----
+ #include "postgres.h"
+ 
+ #include "catalog/catalog.h"
+ #include "catalog/storage.h"
+ #include "lib/stringinfo.h"
+ 
+ 
+ void
+ smgr_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	if (info == XLOG_SMGR_CREATE)
+ 	{
+ 		xl_smgr_create *xlrec = (xl_smgr_create *) rec;
+ 		char	   *path = relpathperm(xlrec->rnode, xlrec->forkNum);
+ 
+ 		appendStringInfo(buf, "file create: %s", path);
+ 		pfree(path);
+ 	}
+ 	else if (info == XLOG_SMGR_TRUNCATE)
+ 	{
+ 		xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec;
+ 		char	   *path = relpathperm(xlrec->rnode, MAIN_FORKNUM);
+ 
+ 		appendStringInfo(buf, "file truncate: %s to %u blocks", path,
+ 						 xlrec->blkno);
+ 		pfree(path);
+ 	}
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
+ }
*** a/src/backend/commands/Makefile
--- b/src/backend/commands/Makefile
***************
*** 20,25 **** OBJS = aggregatecmds.o alter.o analyze.o async.o cluster.o comment.o  \
  	portalcmds.o prepare.o proclang.o \
  	schemacmds.o seclabel.o sequence.o tablecmds.o tablespace.o trigger.o \
  	tsearchcmds.o typecmds.o user.o vacuum.o vacuumlazy.o \
! 	variable.o view.o
  
  include $(top_srcdir)/src/backend/common.mk
--- 20,25 ----
  	portalcmds.o prepare.o proclang.o \
  	schemacmds.o seclabel.o sequence.o tablecmds.o tablespace.o trigger.o \
  	tsearchcmds.o typecmds.o user.o vacuum.o vacuumlazy.o \
! 	variable.o view.o dbase_desc.o seq_desc.o tablespace_desc.o
  
  include $(top_srcdir)/src/backend/common.mk
*** /dev/null
--- b/src/backend/commands/dbase_desc.c
***************
*** 0 ****
--- 1,29 ----
+ #include "postgres.h"
+ 
+ #include "commands/dbcommands.h"
+ #include "lib/stringinfo.h"
+ 
+ 
+ void
+ dbase_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	if (info == XLOG_DBASE_CREATE)
+ 	{
+ 		xl_dbase_create_rec *xlrec = (xl_dbase_create_rec *) rec;
+ 
+ 		appendStringInfo(buf, "create db: copy dir %u/%u to %u/%u",
+ 						 xlrec->src_db_id, xlrec->src_tablespace_id,
+ 						 xlrec->db_id, xlrec->tablespace_id);
+ 	}
+ 	else if (info == XLOG_DBASE_DROP)
+ 	{
+ 		xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec;
+ 
+ 		appendStringInfo(buf, "drop db: dir %u/%u",
+ 						 xlrec->db_id, xlrec->tablespace_id);
+ 	}
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
+ }
*** a/src/backend/commands/dbcommands.c
--- b/src/backend/commands/dbcommands.c
***************
*** 1992,2018 **** dbase_redo(XLogRecPtr lsn, XLogRecord *record)
  	else
  		elog(PANIC, "dbase_redo: unknown op code %u", info);
  }
- 
- void
- dbase_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	if (info == XLOG_DBASE_CREATE)
- 	{
- 		xl_dbase_create_rec *xlrec = (xl_dbase_create_rec *) rec;
- 
- 		appendStringInfo(buf, "create db: copy dir %u/%u to %u/%u",
- 						 xlrec->src_db_id, xlrec->src_tablespace_id,
- 						 xlrec->db_id, xlrec->tablespace_id);
- 	}
- 	else if (info == XLOG_DBASE_DROP)
- 	{
- 		xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec;
- 
- 		appendStringInfo(buf, "drop db: dir %u/%u",
- 						 xlrec->db_id, xlrec->tablespace_id);
- 	}
- 	else
- 		appendStringInfo(buf, "UNKNOWN");
- }
--- 1992,1994 ----
*** /dev/null
--- b/src/backend/commands/seq_desc.c
***************
*** 0 ****
--- 1,23 ----
+ #include "postgres.h"
+ 
+ #include "commands/sequence.h"
+ #include "lib/stringinfo.h"
+ 
+ 
+ void
+ seq_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 	xl_seq_rec *xlrec = (xl_seq_rec *) rec;
+ 
+ 	if (info == XLOG_SEQ_LOG)
+ 		appendStringInfo(buf, "log: ");
+ 	else
+ 	{
+ 		appendStringInfo(buf, "UNKNOWN");
+ 		return;
+ 	}
+ 
+ 	appendStringInfo(buf, "rel %u/%u/%u",
+ 			   xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode);
+ }
*** a/src/backend/commands/sequence.c
--- b/src/backend/commands/sequence.c
***************
*** 1595,1615 **** seq_redo(XLogRecPtr lsn, XLogRecord *record)
  
  	pfree(localpage);
  }
- 
- void
- seq_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 	xl_seq_rec *xlrec = (xl_seq_rec *) rec;
- 
- 	if (info == XLOG_SEQ_LOG)
- 		appendStringInfo(buf, "log: ");
- 	else
- 	{
- 		appendStringInfo(buf, "UNKNOWN");
- 		return;
- 	}
- 
- 	appendStringInfo(buf, "rel %u/%u/%u",
- 			   xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode);
- }
--- 1595,1597 ----
*** a/src/backend/commands/tablespace.c
--- b/src/backend/commands/tablespace.c
***************
*** 1424,1448 **** tblspc_redo(XLogRecPtr lsn, XLogRecord *record)
  	else
  		elog(PANIC, "tblspc_redo: unknown op code %u", info);
  }
- 
- void
- tblspc_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	if (info == XLOG_TBLSPC_CREATE)
- 	{
- 		xl_tblspc_create_rec *xlrec = (xl_tblspc_create_rec *) rec;
- 
- 		appendStringInfo(buf, "create tablespace: %u \"%s\"",
- 						 xlrec->ts_id, xlrec->ts_path);
- 	}
- 	else if (info == XLOG_TBLSPC_DROP)
- 	{
- 		xl_tblspc_drop_rec *xlrec = (xl_tblspc_drop_rec *) rec;
- 
- 		appendStringInfo(buf, "drop tablespace: %u", xlrec->ts_id);
- 	}
- 	else
- 		appendStringInfo(buf, "UNKNOWN");
- }
--- 1424,1426 ----
*** /dev/null
--- b/src/backend/commands/tablespace_desc.c
***************
*** 0 ****
--- 1,27 ----
+ #include "postgres.h"
+ 
+ #include "commands/tablespace.h"
+ #include "lib/stringinfo.h"
+ 
+ 
+ void
+ tblspc_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	if (info == XLOG_TBLSPC_CREATE)
+ 	{
+ 		xl_tblspc_create_rec *xlrec = (xl_tblspc_create_rec *) rec;
+ 
+ 		appendStringInfo(buf, "create tablespace: %u \"%s\"",
+ 						 xlrec->ts_id, xlrec->ts_path);
+ 	}
+ 	else if (info == XLOG_TBLSPC_DROP)
+ 	{
+ 		xl_tblspc_drop_rec *xlrec = (xl_tblspc_drop_rec *) rec;
+ 
+ 		appendStringInfo(buf, "drop tablespace: %u", xlrec->ts_id);
+ 	}
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
+ }
*** a/src/backend/storage/ipc/Makefile
--- b/src/backend/storage/ipc/Makefile
***************
*** 16,21 **** endif
  endif
  
  OBJS = ipc.o ipci.o pmsignal.o procarray.o procsignal.o shmem.o shmqueue.o \
! 	sinval.o sinvaladt.o standby.o
  
  include $(top_srcdir)/src/backend/common.mk
--- 16,21 ----
  endif
  
  OBJS = ipc.o ipci.o pmsignal.o procarray.o procsignal.o shmem.o shmqueue.o \
! 	sinval.o sinvaladt.o standby.o standby_desc.o
  
  include $(top_srcdir)/src/backend/common.mk
*** a/src/backend/storage/ipc/standby.c
--- b/src/backend/storage/ipc/standby.c
***************
*** 783,836 **** standby_redo(XLogRecPtr lsn, XLogRecord *record)
  		elog(PANIC, "standby_redo: unknown op code %u", info);
  }
  
- static void
- standby_desc_running_xacts(StringInfo buf, xl_running_xacts *xlrec)
- {
- 	int			i;
- 
- 	appendStringInfo(buf, " nextXid %u latestCompletedXid %u oldestRunningXid %u",
- 					 xlrec->nextXid,
- 					 xlrec->latestCompletedXid,
- 					 xlrec->oldestRunningXid);
- 	if (xlrec->xcnt > 0)
- 	{
- 		appendStringInfo(buf, "; %d xacts:", xlrec->xcnt);
- 		for (i = 0; i < xlrec->xcnt; i++)
- 			appendStringInfo(buf, " %u", xlrec->xids[i]);
- 	}
- 
- 	if (xlrec->subxid_overflow)
- 		appendStringInfo(buf, "; subxid ovf");
- }
- 
- void
- standby_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	if (info == XLOG_STANDBY_LOCK)
- 	{
- 		xl_standby_locks *xlrec = (xl_standby_locks *) rec;
- 		int			i;
- 
- 		appendStringInfo(buf, "AccessExclusive locks:");
- 
- 		for (i = 0; i < xlrec->nlocks; i++)
- 			appendStringInfo(buf, " xid %u db %u rel %u",
- 							 xlrec->locks[i].xid, xlrec->locks[i].dbOid,
- 							 xlrec->locks[i].relOid);
- 	}
- 	else if (info == XLOG_RUNNING_XACTS)
- 	{
- 		xl_running_xacts *xlrec = (xl_running_xacts *) rec;
- 
- 		appendStringInfo(buf, " running xacts:");
- 		standby_desc_running_xacts(buf, xlrec);
- 	}
- 	else
- 		appendStringInfo(buf, "UNKNOWN");
- }
- 
  /*
   * Log details of the current snapshot to WAL. This allows the snapshot state
   * to be reconstructed on the standby.
--- 783,788 ----
*** /dev/null
--- b/src/backend/storage/ipc/standby_desc.c
***************
*** 0 ****
--- 1,51 ----
+ #include "postgres.h"
+ 
+ #include "storage/standby.h"
+ 
+ static void
+ standby_desc_running_xacts(StringInfo buf, xl_running_xacts *xlrec)
+ {
+ 	int			i;
+ 
+ 	appendStringInfo(buf, " nextXid %u latestCompletedXid %u oldestRunningXid %u",
+ 					 xlrec->nextXid,
+ 					 xlrec->latestCompletedXid,
+ 					 xlrec->oldestRunningXid);
+ 	if (xlrec->xcnt > 0)
+ 	{
+ 		appendStringInfo(buf, "; %d xacts:", xlrec->xcnt);
+ 		for (i = 0; i < xlrec->xcnt; i++)
+ 			appendStringInfo(buf, " %u", xlrec->xids[i]);
+ 	}
+ 
+ 	if (xlrec->subxid_overflow)
+ 		appendStringInfo(buf, "; subxid ovf");
+ }
+ 
+ void
+ standby_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	if (info == XLOG_STANDBY_LOCK)
+ 	{
+ 		xl_standby_locks *xlrec = (xl_standby_locks *) rec;
+ 		int			i;
+ 
+ 		appendStringInfo(buf, "AccessExclusive locks:");
+ 
+ 		for (i = 0; i < xlrec->nlocks; i++)
+ 			appendStringInfo(buf, " xid %u db %u rel %u",
+ 							 xlrec->locks[i].xid, xlrec->locks[i].dbOid,
+ 							 xlrec->locks[i].relOid);
+ 	}
+ 	else if (info == XLOG_RUNNING_XACTS)
+ 	{
+ 		xl_running_xacts *xlrec = (xl_running_xacts *) rec;
+ 
+ 		appendStringInfo(buf, " running xacts:");
+ 		standby_desc_running_xacts(buf, xlrec);
+ 	}
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
+ }
*** a/src/backend/utils/cache/Makefile
--- b/src/backend/utils/cache/Makefile
***************
*** 13,18 **** top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
  OBJS = attoptcache.o catcache.o evtcache.o inval.o plancache.o relcache.o \
! 	relmapper.o spccache.o syscache.o lsyscache.o typcache.o ts_cache.o
  
  include $(top_srcdir)/src/backend/common.mk
--- 13,19 ----
  include $(top_builddir)/src/Makefile.global
  
  OBJS = attoptcache.o catcache.o evtcache.o inval.o plancache.o relcache.o \
! 	relmapper.o spccache.o syscache.o lsyscache.o typcache.o ts_cache.o \
! 	relmap_desc.o
  
  include $(top_srcdir)/src/backend/common.mk
*** /dev/null
--- b/src/backend/utils/cache/relmap_desc.c
***************
*** 0 ****
--- 1,22 ----
+ #include "postgres.h"
+ 
+ #include "access/xlog.h"
+ #include "lib/stringinfo.h"
+ #include "storage/relfilenode.h"
+ #include "utils/relmapper.h"
+ 
+ void
+ relmap_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	if (info == XLOG_RELMAP_UPDATE)
+ 	{
+ 		xl_relmap_update *xlrec = (xl_relmap_update *) rec;
+ 
+ 		appendStringInfo(buf, "update relmap: database %u tablespace %u size %u",
+ 						 xlrec->dbid, xlrec->tsid, xlrec->nbytes);
+ 	}
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
+ }
*** a/src/backend/utils/cache/relmapper.c
--- b/src/backend/utils/cache/relmapper.c
***************
*** 896,914 **** relmap_redo(XLogRecPtr lsn, XLogRecord *record)
  	else
  		elog(PANIC, "relmap_redo: unknown op code %u", info);
  }
- 
- void
- relmap_desc(StringInfo buf, uint8 xl_info, char *rec)
- {
- 	uint8		info = xl_info & ~XLR_INFO_MASK;
- 
- 	if (info == XLOG_RELMAP_UPDATE)
- 	{
- 		xl_relmap_update *xlrec = (xl_relmap_update *) rec;
- 
- 		appendStringInfo(buf, "update relmap: database %u tablespace %u size %u",
- 						 xlrec->dbid, xlrec->tsid, xlrec->nbytes);
- 	}
- 	else
- 		appendStringInfo(buf, "UNKNOWN");
- }
--- 896,898 ----
*** a/src/include/access/xlog_internal.h
--- b/src/include/access/xlog_internal.h
***************
*** 205,210 **** typedef XLogLongPageHeaderData *XLogLongPageHeader;
--- 205,229 ----
  			 (uint32) ((logSegNo) / XLogSegmentsPerXLogId), \
  			 (uint32) ((logSegNo) % XLogSegmentsPerXLogId), offset)
  
+ /*
+  * Information logged when we detect a change in one of the parameters
+  * important for Hot Standby.
+  */
+ typedef struct xl_parameter_change
+ {
+ 	int			MaxConnections;
+ 	int			max_prepared_xacts;
+ 	int			max_locks_per_xact;
+ 	int			wal_level;
+ } xl_parameter_change;
+ 
+ /* logs restore point */
+ typedef struct xl_restore_point
+ {
+ 	TimestampTz rp_time;
+ 	char		rp_name[MAXFNAMELEN];
+ } xl_restore_point;
+ 
  
  /*
   * Method table for resource managers.
*** a/src/include/catalog/storage.h
--- b/src/include/catalog/storage.h
***************
*** 34,39 **** extern void AtSubCommit_smgr(void);
--- 34,62 ----
  extern void AtSubAbort_smgr(void);
  extern void PostPrepare_smgr(void);
  
+ /*
+  * Declarations for smgr-related XLOG records
+  *
+  * Note: we log file creation and truncation here, but logging of deletion
+  * actions is handled by xact.c, because it is part of transaction commit.
+  */
+ 
+ /* XLOG gives us high 4 bits */
+ #define XLOG_SMGR_CREATE	0x10
+ #define XLOG_SMGR_TRUNCATE	0x20
+ 
+ typedef struct xl_smgr_create
+ {
+ 	RelFileNode rnode;
+ 	ForkNumber	forkNum;
+ } xl_smgr_create;
+ 
+ typedef struct xl_smgr_truncate
+ {
+ 	BlockNumber blkno;
+ 	RelFileNode rnode;
+ } xl_smgr_truncate;
+ 
  extern void log_smgrcreate(RelFileNode *rnode, ForkNumber forkNum);
  
  extern void smgr_redo(XLogRecPtr lsn, XLogRecord *record);
