diff --git a/src/backend/access/undo/undoinsert.c b/src/backend/access/undo/undoinsert.c
index 7c7e4ff1a1..3d57109e04 100644
--- a/src/backend/access/undo/undoinsert.c
+++ b/src/backend/access/undo/undoinsert.c
@@ -11,38 +11,41 @@
  * NOTES:
  * Undo record layout:
  *
- *  Undo record are stored in sequential order in the undo log.  And, each
- *  transaction's first undo record a.k.a. transaction header points to the next
- *  transaction's start header.  Transaction headers are linked so that the
- *  discard worker can read undo log transaction by transaction and avoid
- *  reading each undo record.
+ * Undo records are stored in sequential order in the undo log.  Each undo
+ * record consists of a variable length header, tuple data, and payload
+ * information.  The first undo record of each transaction contains a
+ * transaction header that points to the next transaction's start header.
+ * This allows us to discard the entire transaction's log at one-shot rather
+ * than record-by-record.  The callers are not aware of transaction header,
+ * this is entirely maintained and used by undo record layer.   See
+ * undorecord.h for detailed information about undo record header.
  *
  * Handling multi log:
  *
- *  It is possible that the undo record of a transaction can be spread across
- *  multiple undo log.  And, we need some special handling while inserting the
- *  undo for discard and rollback to work sanely.
+ * It is possible that the undo record of a transaction can be spread across
+ * multiple undo log.  And, we need some special handling while inserting the
+ * undo for discard and rollback to work sanely.
  *
- *  If the undorecord goes to next log then we insert a transaction header for
- *  the first record in the new log and update the transaction header with this
- *  new log's location. This will allow us to connect transactions across logs
- *  when the same transaction span across log (for this we keep track of the
- *  previous logno in undo log meta) which is required to find the latest undo
- *  record pointer of the aborted transaction for executing the undo actions
- *  before discard. If the next log get processed first in that case we
- *  don't need to trace back the actual start pointer of the transaction,
- *  in such case we can only execute the undo actions from the current log
- *  because the undo pointer in the slot will be rewound and that will be enough
- *  to avoid executing same actions.  However, there is possibility that after
- *  executing the undo actions the undo pointer got discarded, now in later
- *  stage while processing the previous log it might try to fetch the undo
- *  record in the discarded log while chasing the transaction header chain.
- *  To avoid this situation we first check if the next_urec of the transaction
- *  is already discarded then no need to access that and start executing from
- *  the last undo record in the current log.
+ * If the undorecord goes to next log then we insert a transaction header for
+ * the first record in the new log and update the transaction header with this
+ * new log's location. This will allow us to connect transactions across logs
+ * when the same transaction span across log (for this we keep track of the
+ * previous logno in undo log meta) which is required to find the latest undo
+ * record pointer of the aborted transaction for executing the undo actions
+ * before discard. If the next log get processed first in that case we
+ * don't need to trace back the actual start pointer of the transaction,
+ * in such case we can only execute the undo actions from the current log
+ * because the undo pointer in the slot will be rewound and that will be enough
+ * to avoid executing same actions.  However, there is possibility that after
+ * executing the undo actions the undo pointer got discarded, now in later
+ * stage while processing the previous log it might try to fetch the undo
+ * record in the discarded log while chasing the transaction header chain.
+ * To avoid this situation we first check if the next_urec of the transaction
+ * is already discarded then no need to access that and start executing from
+ * the last undo record in the current log.
  *
- *  We only connect to next log if the same transaction spread to next log
- *  otherwise don't.
+ * We only connect to next log if the same transaction spread to next log
+ * otherwise don't.
  *-------------------------------------------------------------------------
  */
 
@@ -464,9 +467,12 @@ resize:
 
 		/*
 		 * Prepare the transacion header for the first undo record of
-		 * transaction. XXX there is also an option that instead of adding the
+		 * transaction.
+		 *
+		 * XXX There is also an option that instead of adding the
 		 * information to this record we can prepare a new record which only
-		 * contain transaction informations.
+		 * contain transaction informations, but we can't see any clear
+		 * advantage of the same.
 		 */
 		if (need_xact_hdr && i == 0)
 		{
@@ -837,57 +843,6 @@ InsertPreparedUndo(void)
 	}
 }
 
-/*
- * Reset the global variables related to undo buffers. This is required at the
- * transaction abort and while releasing the undo buffers.
- */
-void
-ResetUndoBuffers(void)
-{
-	int			i;
-
-	for (i = 0; i < buffer_idx; i++)
-	{
-		undo_buffer[i].blk = InvalidBlockNumber;
-		undo_buffer[i].buf = InvalidBuffer;
-	}
-
-	xact_urec_info.urecptr = InvalidUndoRecPtr;
-
-	/* Reset the prepared index. */
-	prepare_idx = 0;
-	buffer_idx = 0;
-	prepared_urec_ptr = InvalidUndoRecPtr;
-
-	/*
-	 * max_prepared_undo limit is changed so free the allocated memory and
-	 * reset all the variable back to their default value.
-	 */
-	if (max_prepared_undo > MAX_PREPARED_UNDO)
-	{
-		pfree(undo_buffer);
-		pfree(prepared_undo);
-		undo_buffer = def_buffers;
-		prepared_undo = def_prepared;
-		max_prepared_undo = MAX_PREPARED_UNDO;
-	}
-}
-
-/*
- * Unlock and release the undo buffers.  This step must be performed after
- * exiting any critical section where we have perfomed undo actions.
- */
-void
-UnlockReleaseUndoBuffers(void)
-{
-	int			i;
-
-	for (i = 0; i < buffer_idx; i++)
-		UnlockReleaseBuffer(undo_buffer[i].buf);
-
-	ResetUndoBuffers();
-}
-
 /*
  * Helper function for UndoFetchRecord.  It will fetch the undo record pointed
  * by urp and unpack the record into urec.  This function will not release the
@@ -1022,6 +977,10 @@ ResetUndoRecord(UnpackedUndoRecord *urec, UndoRecPtr urp, RelFileNode *rnode,
  *
  * callback function decides whether particular undo record satisfies the
  * condition of caller.
+ *
+ * Returns the required undo record if found, otherwise, return NULL which
+ * means either the record is already discarded or there is no such record
+ * in the undo chain.
  */
 UnpackedUndoRecord *
 UndoFetchRecord(UndoRecPtr urp, BlockNumber blkno, OffsetNumber offset,
@@ -1191,3 +1150,54 @@ UndoLogBuffersSetLSN(XLogRecPtr recptr)
 	for (idx = 0; idx < buffer_idx; idx++)
 		PageSetLSN(BufferGetPage(undo_buffer[idx].buf), recptr);
 }
+
+/*
+ * Reset the global variables related to undo buffers. This is required at the
+ * transaction abort and while releasing the undo buffers.
+ */
+void
+ResetUndoBuffers(void)
+{
+	int			i;
+
+	for (i = 0; i < buffer_idx; i++)
+	{
+		undo_buffer[i].blk = InvalidBlockNumber;
+		undo_buffer[i].buf = InvalidBuffer;
+	}
+
+	xact_urec_info.urecptr = InvalidUndoRecPtr;
+
+	/* Reset the prepared index. */
+	prepare_idx = 0;
+	buffer_idx = 0;
+	prepared_urec_ptr = InvalidUndoRecPtr;
+
+	/*
+	 * max_prepared_undo limit is changed so free the allocated memory and
+	 * reset all the variable back to their default value.
+	 */
+	if (max_prepared_undo > MAX_PREPARED_UNDO)
+	{
+		pfree(undo_buffer);
+		pfree(prepared_undo);
+		undo_buffer = def_buffers;
+		prepared_undo = def_prepared;
+		max_prepared_undo = MAX_PREPARED_UNDO;
+	}
+}
+
+/*
+ * Unlock and release the undo buffers.  This step must be performed after
+ * exiting any critical section where we have perfomed undo actions.
+ */
+void
+UnlockReleaseUndoBuffers(void)
+{
+	int			i;
+
+	for (i = 0; i < buffer_idx; i++)
+		UnlockReleaseBuffer(undo_buffer[i].buf);
+
+	ResetUndoBuffers();
+}
diff --git a/src/backend/access/undo/undorecord.c b/src/backend/access/undo/undorecord.c
index 73076dc5f4..b44c41d7f5 100644
--- a/src/backend/access/undo/undorecord.c
+++ b/src/backend/access/undo/undorecord.c
@@ -58,18 +58,28 @@ UndoRecordExpectedSize(UnpackedUndoRecord *uur)
 }
 
 /*
+ * To insert an undo record, call InsertUndoRecord() repeatedly until it
+ * returns true.
+ *
  * Insert as much of an undo record as will fit in the given page.
- * starting_byte is the byte within the give page at which to begin
- * writing, while *already_written is the number of bytes written to
- * previous pages.  Returns true if the remainder of the record was
- * written and false if more bytes remain to be written; in either
- * case, *already_written is set to the number of bytes written thus
- * far.
+ * starting_byte is the byte within the give page at which to begin writing,
+ * while *already_written is the number of bytes written to previous pages.
+ *
+ * Returns true if the remainder of the record was written and false if more
+ * bytes remain to be written; in either case, *already_written is set to the
+ * number of bytes written thus far.
+ *
+ * This function assumes that if *already_written is non-zero on entry, the
+ * same UnpackedUndoRecord is passed each time.  It also assumes that
+ * UnpackUndoRecord is not called between successive calls to InsertUndoRecord
+ * for the same UnpackedUndoRecord.
+ *
+ * If this function is called again to continue writing the record, the
+ * previous value for *already_written should be passed again, and
+ * starting_byte should be passed as sizeof(PageHeaderData) (since the record
+ * will continue immediately following the page header).
  *
- * This function assumes that if *already_written is non-zero on entry,
- * the same UnpackedUndoRecord is passed each time.  It also assumes
- * that UnpackUndoRecord is not called between successive calls to
- * InsertUndoRecord for the same UnpackedUndoRecord.
+ * This function sets uur->uur_info as a side effect.
  */
 bool
 InsertUndoRecord(UnpackedUndoRecord *uur, Page page,
diff --git a/src/include/access/undoinsert.h b/src/include/access/undoinsert.h
index fe4a97ec2e..93b6410368 100644
--- a/src/include/access/undoinsert.h
+++ b/src/include/access/undoinsert.h
@@ -28,35 +28,12 @@ typedef bool (*SatisfyUndoRecordCallback) (UnpackedUndoRecord *urec,
 										   OffsetNumber offset,
 										   TransactionId xid);
 
-/*
- * Call PrepareUndoInsert to tell the undo subsystem about the undo record you
- * intended to insert.  Upon return, the necessary undo buffers are pinned and
- * locked.
- * This should be done before any critical section is established, since it
- * can fail.
- *
- * If not in recovery, 'xid' should refer to the top transaction id because
- * undo log only stores mapping for the top most transactions.
- * If in recovery, 'xid' refers to the transaction id stored in WAL.
- */
 extern UndoRecPtr PrepareUndoInsert(UnpackedUndoRecord *, TransactionId xid,
 				  UndoPersistence);
-
-/*
- * Insert a previously-prepared undo record.  This will write the actual undo
- * record into the buffers already pinned and locked in PreparedUndoInsert,
- * and mark them dirty.  For persistent undo, this step should be performed
- * after entering a critical section; it should never fail.
- */
 extern void InsertPreparedUndo(void);
 
 extern void RegisterUndoLogBuffers(uint8 first_block_id);
 extern void UndoLogBuffersSetLSN(XLogRecPtr recptr);
-
-/*
- * Unlock and release undo buffers.  This step performed after exiting any
- * critical section where we have prepared the undo record.
- */
 extern void UnlockReleaseUndoBuffers(void);
 
 /*
@@ -65,45 +42,16 @@ extern void UnlockReleaseUndoBuffers(void);
  * inserting undo after having prepared a record for insertion.
  */
 extern void CancelPreparedUndo(void);
-
-/*
- * Fetch the next undo record for given blkno and offset.  Start the search
- * from urp.  Caller need to call UndoRecordRelease to release the resources
- * allocated by this function.
- */
 extern UnpackedUndoRecord *UndoFetchRecord(UndoRecPtr urp,
-				BlockNumber blkno,
-				OffsetNumber offset,
-				TransactionId xid,
-				UndoRecPtr *urec_ptr_out,
+				BlockNumber blkno, OffsetNumber offset,
+				TransactionId xid, UndoRecPtr *urec_ptr_out,
 				SatisfyUndoRecordCallback callback);
-
-/*
- * Release the resources allocated by UndoFetchRecord.
- */
 extern void UndoRecordRelease(UnpackedUndoRecord *urec);
-
-/*
- * Set the value of PrevUndoLen.
- */
 extern void UndoRecordSetPrevUndoLen(uint16 len);
-
-/*
- * Call UndoSetPrepareSize to set the value of how many maximum prepared can
- * be done before inserting the prepared undo.  If size is > MAX_PREPARED_UNDO
- * then it will allocate extra memory to hold the extra prepared undo.
- */
 extern void UndoSetPrepareSize(UnpackedUndoRecord *undorecords, int nrecords,
 				   TransactionId xid, UndoPersistence upersistence);
-
-/*
- * return the previous undo record pointer.
- */
 extern UndoRecPtr UndoGetPrevUndoRecptr(UndoRecPtr urp, uint16 prevlen);
-
 extern void UndoRecordOnUndoLogChange(UndoPersistence persistence);
-
-/* Reset globals related to undo buffers */
 extern void ResetUndoBuffers(void);
 
 #endif							/* UNDOINSERT_H */
diff --git a/src/include/access/undorecord.h b/src/include/access/undorecord.h
index 9ca245509c..04de50e112 100644
--- a/src/include/access/undorecord.h
+++ b/src/include/access/undorecord.h
@@ -37,8 +37,8 @@ typedef struct UndoRecordHeader
 
 	/*
 	 * Transaction id that has modified the tuple present in this undo record.
-	 * If this is older then RecentGlobalXmin, then we can consider the tuple
-	 * in this undo record as visible.
+	 * If this is older then oldestXidWithEpochHavingUndo, then we can consider
+	 * the tuple in this undo record as visible.
 	 */
 	TransactionId urec_prevxid;
 
@@ -60,8 +60,16 @@ typedef struct UndoRecordHeader
  *
  * If UREC_INFO_BLOCK is set, an UndoRecordBlock structure follows.
  *
+ * If UREC_INFO_TRANSACTION is set, an UndoRecordTransaction structure
+ * follows.
+ *
  * If UREC_INFO_PAYLOAD is set, an UndoRecordPayload structure follows.
  *
+ * If UREC_INFO_PAYLOAD_CONTAINS_SLOT is set, payload contains an additional
+ * information about transaction slot.  This is specific to zheap, we might
+ * want to invent a special way to encode different information in payload
+ * structure, but for now this seems easiest.
+ *
  * When (as will often be the case) multiple structures are present, they
  * appear in the same order in which the constants are defined here.  That is,
  * UndoRecordRelationDetails appears first.
@@ -71,10 +79,10 @@ typedef struct UndoRecordHeader
 #define UREC_INFO_PAYLOAD					0x04
 #define UREC_INFO_TRANSACTION				0x08
 #define UREC_INFO_PAYLOAD_CONTAINS_SLOT		0x10
+
 /*
  * Additional information about a relation to which this record pertains,
- * namely the tablespace OID and fork number.  If the tablespace OID is
- * DEFAULTTABLESPACE_OID and the fork number is MAIN_FORKNUM, this structure
+ * namely the fork number.  If the fork number is MAIN_FORKNUM, this structure
  * can (and should) be omitted.
  */
 typedef struct UndoRecordRelationDetails
@@ -141,7 +149,8 @@ typedef struct UndoRecordPayload
  *
  * When creating an undo record from an UnpackedUndoRecord, caller should
  * set uur_info to 0.  It will be initialized by the first call to
- * UndoRecordExpectedSize or InsertUndoRecord.
+ * UndoRecordSetInfo or InsertUndoRecord.  We do set it in
+ * UndoRecordAllocate for transaction specific header information.
  *
  * When an undo record is decoded into an UnpackedUndoRecord, all fields
  * will be initialized, but those for which no information is available
@@ -166,56 +175,20 @@ typedef struct UnpackedUndoRecord
 	Oid			uur_dbid;		/* database id */
 
 	/*
-	 * undo action apply progress 0 = not started, 1 = completed. In future it
-	 * can also be used to show the progress of how much undo has been applied
-	 * so far with some formulae but currently only 0 and 1 is used.
+	 * This indicates undo action apply progress, 0 means not started, 1 means
+	 * completed.  In future, it can also be used to show the progress of how
+	 * much undo has been applied so far with some formula.
 	 */
 	uint32		uur_progress;
 	StringInfoData uur_payload; /* payload bytes */
 	StringInfoData uur_tuple;	/* tuple bytes */
 } UnpackedUndoRecord;
 
-/*
- * Set uur_info for an UnpackedUndoRecord appropriately based on which
- * other fields are set.
- */
-extern void UndoRecordSetInfo(UnpackedUndoRecord *uur);
 
-/*
- * Compute the number of bytes of storage that will be required to insert
- * an undo record.  Sets uur->uur_info as a side effect.
- */
+extern void UndoRecordSetInfo(UnpackedUndoRecord *uur);
 extern Size UndoRecordExpectedSize(UnpackedUndoRecord *uur);
-
-/*
- * To insert an undo record, call InsertUndoRecord() repeatedly until it
- * returns true.  For the first call, the given page should be the one which
- * the caller has determined to contain the current insertion point,
- * starting_byte should be the byte offset within that page which corresponds
- * to the current insertion point, and *already_written should be 0.  The
- * return value will be true if the entire record is successfully written
- * into that page, and false if not.  In either case, *already_written will
- * be updated to the number of bytes written by all InsertUndoRecord calls
- * for this record to date.  If this function is called again to continue
- * writing the record, the previous value for *already_written should be
- * passed again, and starting_byte should be passed as sizeof(PageHeaderData)
- * (since the record will continue immediately following the page header).
- *
- * This function sets uur->uur_info as a side effect.
- */
 extern bool InsertUndoRecord(UnpackedUndoRecord *uur, Page page,
 				 int starting_byte, int *already_written, bool header_only);
-
-/*
- * Call UnpackUndoRecord() one or more times to unpack an undo record.  For
- * the first call, starting_byte should be set to the beginning of the undo
- * record within the specified page, and *already_decoded should be set to 0;
- * the function will update it based on the number of bytes decoded.  The
- * return value is true if the entire record was unpacked and false if the
- * record continues on the next page.  In the latter case, the function
- * should be called again with the next page, passing starting_byte as the
- * sizeof(PageHeaderData).
- */
 extern bool UnpackUndoRecord(UnpackedUndoRecord *uur, Page page,
 				 int starting_byte, int *already_decoded, bool header_only);
 
