Why do we have a WAL record for CLOG page extension? It seems to be
unnecessary, since other code already covers that failure situation.

We ignore heap extensions, on the assumption that the insertion will
automatically extend the relation when we recover. We also ignore
previously truncated clog pages, so the absence of a clog page at
recovery time is clearly not an issue. So why not avoid writing WAL when
we move to the next clog page and fix this at recovery time if it is an
issue?

Well, slru.c *already* includes code that specifically ignores errors
for set/get TransactionIds during recovery when pages are absent, plus
this is supposed to still work even if this is not the first page of a
clog segment. So, the WAL record seems like it is not required.

Patch removes the xlog record written at new page time. This ensures
that we don't need to wait for an I/O when holding the XidGenLock, which
can be a problem with hundreds of people requesting that lock,
especially since we may need to queue for one of the WAL locks first.

Leave the RMID for clog, in case required later.

-- 
  Simon Riggs             
  EnterpriseDB   http://www.enterprisedb.com
Index: src/backend/access/transam/clog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/clog.c,v
retrieving revision 1.38
diff -c -r1.38 clog.c
*** src/backend/access/transam/clog.c	24 Mar 2006 04:32:12 -0000	1.38
--- src/backend/access/transam/clog.c	6 Jun 2006 14:19:36 -0000
***************
*** 66,74 ****
  #define ClogCtl (&ClogCtlData)
  
  
! static int	ZeroCLOGPage(int pageno, bool writeXlog);
  static bool CLOGPagePrecedes(int page1, int page2);
- static void WriteZeroPageXlogRec(int pageno);
  
  
  /*
--- 66,73 ----
  #define ClogCtl (&ClogCtlData)
  
  
! static int	ZeroCLOGPage(int pageno);
  static bool CLOGPagePrecedes(int page1, int page2);
  
  
  /*
***************
*** 172,178 ****
  	LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
  
  	/* Create and zero the first page of the commit log */
! 	slotno = ZeroCLOGPage(0, false);
  
  	/* Make sure it's written out */
  	SimpleLruWritePage(ClogCtl, slotno, NULL);
--- 171,177 ----
  	LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
  
  	/* Create and zero the first page of the commit log */
! 	slotno = ZeroCLOGPage(0);
  
  	/* Make sure it's written out */
  	SimpleLruWritePage(ClogCtl, slotno, NULL);
***************
*** 191,205 ****
   * Control lock must be held at entry, and will be held at exit.
   */
  static int
! ZeroCLOGPage(int pageno, bool writeXlog)
  {
  	int			slotno;
  
  	slotno = SimpleLruZeroPage(ClogCtl, pageno);
  
- 	if (writeXlog)
- 		WriteZeroPageXlogRec(pageno);
- 
  	return slotno;
  }
  
--- 190,201 ----
   * Control lock must be held at entry, and will be held at exit.
   */
  static int
! ZeroCLOGPage(int pageno)
  {
  	int			slotno;
  
  	slotno = SimpleLruZeroPage(ClogCtl, pageno);
  
  	return slotno;
  }
  
***************
*** 300,306 ****
  	LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
  
  	/* Zero the page and make an XLOG entry about it */
! 	ZeroCLOGPage(pageno, true);
  
  	LWLockRelease(CLogControlLock);
  }
--- 296,302 ----
  	LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
  
  	/* Zero the page and make an XLOG entry about it */
! 	ZeroCLOGPage(pageno);
  
  	LWLockRelease(CLogControlLock);
  }
***************
*** 365,428 ****
  
  	return TransactionIdPrecedes(xid1, xid2);
  }
- 
- 
- /*
-  * Write a ZEROPAGE xlog record
-  *
-  * Note: xlog record is marked as outside transaction control, since we
-  * want it to be redone whether the invoking transaction commits or not.
-  * (Besides which, this is normally done just before entering a transaction.)
-  */
- static void
- WriteZeroPageXlogRec(int pageno)
- {
- 	XLogRecData rdata;
- 
- 	rdata.data = (char *) (&pageno);
- 	rdata.len = sizeof(int);
- 	rdata.buffer = InvalidBuffer;
- 	rdata.next = NULL;
- 	(void) XLogInsert(RM_CLOG_ID, CLOG_ZEROPAGE | XLOG_NO_TRAN, &rdata);
- }
- 
- /*
-  * CLOG resource manager's routines
-  */
- void
- clog_redo(XLogRecPtr lsn, XLogRecord *record)
- {
- 	uint8		info = record->xl_info & ~XLR_INFO_MASK;
- 
- 	if (info == CLOG_ZEROPAGE)
- 	{
- 		int			pageno;
- 		int			slotno;
- 
- 		memcpy(&pageno, XLogRecGetData(record), sizeof(int));
- 
- 		LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
- 
- 		slotno = ZeroCLOGPage(pageno, false);
- 		SimpleLruWritePage(ClogCtl, slotno, NULL);
- 		Assert(!ClogCtl->shared->page_dirty[slotno]);
- 
- 		LWLockRelease(CLogControlLock);
- 	}
- }
- 
- 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
- 		appendStringInfo(buf, "UNKNOWN");
- }
--- 361,363 ----
Index: src/backend/access/transam/rmgr.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/rmgr.c,v
retrieving revision 1.22
diff -c -r1.22 rmgr.c
*** src/backend/access/transam/rmgr.c	2 May 2006 11:28:54 -0000	1.22
--- src/backend/access/transam/rmgr.c	6 Jun 2006 14:19:36 -0000
***************
*** 26,32 ****
  	{"XLOG", xlog_redo, xlog_desc, NULL, NULL},
  	{"Transaction", xact_redo, xact_desc, NULL, NULL},
  	{"Storage", smgr_redo, smgr_desc, NULL, NULL},
! 	{"CLOG", clog_redo, clog_desc, NULL, NULL},
  	{"Database", dbase_redo, dbase_desc, NULL, NULL},
  	{"Tablespace", tblspc_redo, tblspc_desc, NULL, NULL},
  	{"MultiXact", multixact_redo, multixact_desc, NULL, NULL},
--- 26,32 ----
  	{"XLOG", xlog_redo, xlog_desc, NULL, NULL},
  	{"Transaction", xact_redo, xact_desc, NULL, NULL},
  	{"Storage", smgr_redo, smgr_desc, NULL, NULL},
! 	{"CLOG", NULL, NULL, NULL, NULL},
  	{"Database", dbase_redo, dbase_desc, NULL, NULL},
  	{"Tablespace", tblspc_redo, tblspc_desc, NULL, NULL},
  	{"MultiXact", multixact_redo, multixact_desc, NULL, NULL},
Index: src/include/access/clog.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/access/clog.h,v
retrieving revision 1.17
diff -c -r1.17 clog.h
*** src/include/access/clog.h	24 Mar 2006 04:32:13 -0000	1.17
--- src/include/access/clog.h	6 Jun 2006 14:19:38 -0000
***************
*** 47,53 ****
  /* XLOG stuff */
  #define CLOG_ZEROPAGE		0x00
  
- extern void clog_redo(XLogRecPtr lsn, XLogRecord *record);
- extern void clog_desc(StringInfo buf, uint8 xl_info, char *rec);
- 
  #endif   /* CLOG_H */
--- 47,50 ----
---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
       choose an index scan if your joining column's datatypes do not
       match

Reply via email to