Here's an updated patch with help from Simon.  Once I get a test system
going again in the lab I'll start posting some data.  I'm planning a
combination of block sizes (BLCKSZ and XLOG_BLCKSZ) and number of WAL
buffers.

Thanks,
Mark
Index: src/backend/access/transam/xlog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.229
diff -c -r1.229 xlog.c
*** src/backend/access/transam/xlog.c	28 Mar 2006 22:01:16 -0000	1.229
--- src/backend/access/transam/xlog.c	3 Apr 2006 15:03:09 -0000
***************
*** 113,122 ****
  
  /*
   * Limitation of buffer-alignment for direct IO depends on OS and filesystem,
!  * but BLCKSZ is assumed to be enough for it.
   */
  #ifdef O_DIRECT
! #define ALIGNOF_XLOG_BUFFER		BLCKSZ
  #else
  #define ALIGNOF_XLOG_BUFFER		ALIGNOF_BUFFER
  #endif
--- 113,122 ----
  
  /*
   * Limitation of buffer-alignment for direct IO depends on OS and filesystem,
!  * but XLOG_BLCKSZ is assumed to be enough for it.
   */
  #ifdef O_DIRECT
! #define ALIGNOF_XLOG_BUFFER		XLOG_BLCKSZ
  #else
  #define ALIGNOF_XLOG_BUFFER		ALIGNOF_BUFFER
  #endif
***************
*** 130,136 ****
  
  /* User-settable parameters */
  int			CheckPointSegments = 3;
! int			XLOGbuffers = 8;
  char	   *XLogArchiveCommand = NULL;
  char	   *XLOG_sync_method = NULL;
  const char	XLOG_sync_method_default[] = DEFAULT_SYNC_METHOD_STR;
--- 130,136 ----
  
  /* User-settable parameters */
  int			CheckPointSegments = 3;
! int			XLOGbuffers = 16;
  char	   *XLogArchiveCommand = NULL;
  char	   *XLOG_sync_method = NULL;
  const char	XLOG_sync_method_default[] = DEFAULT_SYNC_METHOD_STR;
***************
*** 374,380 ****
  	 * and xlblocks values depends on WALInsertLock and WALWriteLock.
  	 */
  	char	   *pages;			/* buffers for unwritten XLOG pages */
! 	XLogRecPtr *xlblocks;		/* 1st byte ptr-s + BLCKSZ */
  	Size		XLogCacheByte;	/* # bytes in xlog buffers */
  	int			XLogCacheBlck;	/* highest allocated xlog buffer index */
  	TimeLineID	ThisTimeLineID;
--- 374,380 ----
  	 * and xlblocks values depends on WALInsertLock and WALWriteLock.
  	 */
  	char	   *pages;			/* buffers for unwritten XLOG pages */
! 	XLogRecPtr *xlblocks;		/* 1st byte ptr-s + XLOG_BLCKSZ */
  	Size		XLogCacheByte;	/* # bytes in xlog buffers */
  	int			XLogCacheBlck;	/* highest allocated xlog buffer index */
  	TimeLineID	ThisTimeLineID;
***************
*** 397,403 ****
  
  /* Free space remaining in the current xlog page buffer */
  #define INSERT_FREESPACE(Insert)  \
! 	(BLCKSZ - ((Insert)->currpos - (char *) (Insert)->currpage))
  
  /* Construct XLogRecPtr value for current insertion point */
  #define INSERT_RECPTR(recptr,Insert,curridx)  \
--- 397,403 ----
  
  /* Free space remaining in the current xlog page buffer */
  #define INSERT_FREESPACE(Insert)  \
! 	(XLOG_BLCKSZ - ((Insert)->currpos - (char *) (Insert)->currpage))
  
  /* Construct XLogRecPtr value for current insertion point */
  #define INSERT_RECPTR(recptr,Insert,curridx)  \
***************
*** 441,447 ****
  static uint32 readSeg = 0;
  static uint32 readOff = 0;
  
! /* Buffer for currently read page (BLCKSZ bytes) */
  static char *readBuf = NULL;
  
  /* Buffer for current ReadRecord result (expandable) */
--- 441,447 ----
  static uint32 readSeg = 0;
  static uint32 readOff = 0;
  
! /* Buffer for currently read page (XLOG_BLCKSZ bytes) */
  static char *readBuf = NULL;
  
  /* Buffer for current ReadRecord result (expandable) */
***************
*** 706,712 ****
  	 * If cache is half filled then try to acquire write lock and do
  	 * XLogWrite. Ignore any fractional blocks in performing this check.
  	 */
! 	LogwrtRqst.Write.xrecoff -= LogwrtRqst.Write.xrecoff % BLCKSZ;
  	if (LogwrtRqst.Write.xlogid != LogwrtResult.Write.xlogid ||
  		(LogwrtRqst.Write.xrecoff >= LogwrtResult.Write.xrecoff +
  		 XLogCtl->XLogCacheByte / 2))
--- 706,712 ----
  	 * If cache is half filled then try to acquire write lock and do
  	 * XLogWrite. Ignore any fractional blocks in performing this check.
  	 */
! 	LogwrtRqst.Write.xrecoff -= LogwrtRqst.Write.xrecoff % XLOG_BLCKSZ;
  	if (LogwrtRqst.Write.xlogid != LogwrtResult.Write.xlogid ||
  		(LogwrtRqst.Write.xrecoff >= LogwrtResult.Write.xrecoff +
  		 XLogCtl->XLogCacheByte / 2))
***************
*** 1228,1239 ****
  	{
  		/* crossing a logid boundary */
  		NewPageEndPtr.xlogid += 1;
! 		NewPageEndPtr.xrecoff = BLCKSZ;
  	}
  	else
! 		NewPageEndPtr.xrecoff += BLCKSZ;
  	XLogCtl->xlblocks[nextidx] = NewPageEndPtr;
! 	NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * (Size) BLCKSZ);
  
  	Insert->curridx = nextidx;
  	Insert->currpage = NewPage;
--- 1228,1239 ----
  	{
  		/* crossing a logid boundary */
  		NewPageEndPtr.xlogid += 1;
! 		NewPageEndPtr.xrecoff = XLOG_BLCKSZ;
  	}
  	else
! 		NewPageEndPtr.xrecoff += XLOG_BLCKSZ;
  	XLogCtl->xlblocks[nextidx] = NewPageEndPtr;
! 	NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * (Size) XLOG_BLCKSZ);
  
  	Insert->curridx = nextidx;
  	Insert->currpage = NewPage;
***************
*** 1244,1250 ****
  	 * Be sure to re-zero the buffer so that bytes beyond what we've written
  	 * will look like zeroes and not valid XLOG records...
  	 */
! 	MemSet((char *) NewPage, 0, BLCKSZ);
  
  	/*
  	 * Fill the new page's header
--- 1244,1250 ----
  	 * Be sure to re-zero the buffer so that bytes beyond what we've written
  	 * will look like zeroes and not valid XLOG records...
  	 */
! 	MemSet((char *) NewPage, 0, XLOG_BLCKSZ);
  
  	/*
  	 * Fill the new page's header
***************
*** 1254,1260 ****
  	/* NewPage->xlp_info = 0; */	/* done by memset */
  	NewPage   ->xlp_tli = ThisTimeLineID;
  	NewPage   ->xlp_pageaddr.xlogid = NewPageEndPtr.xlogid;
! 	NewPage   ->xlp_pageaddr.xrecoff = NewPageEndPtr.xrecoff - BLCKSZ;
  
  	/*
  	 * If first page of an XLOG segment file, make it a long header.
--- 1254,1260 ----
  	/* NewPage->xlp_info = 0; */	/* done by memset */
  	NewPage   ->xlp_tli = ThisTimeLineID;
  	NewPage   ->xlp_pageaddr.xlogid = NewPageEndPtr.xlogid;
! 	NewPage   ->xlp_pageaddr.xrecoff = NewPageEndPtr.xrecoff - XLOG_BLCKSZ;
  
  	/*
  	 * If first page of an XLOG segment file, make it a long header.
***************
*** 1428,1434 ****
  		{
  			/* first of group */
  			startidx = curridx;
! 			startoffset = (LogwrtResult.Write.xrecoff - BLCKSZ) % XLogSegSize;
  		}
  		npages++;
  
--- 1428,1434 ----
  		{
  			/* first of group */
  			startidx = curridx;
! 			startoffset = (LogwrtResult.Write.xrecoff - XLOG_BLCKSZ) % XLogSegSize;
  		}
  		npages++;
  
***************
*** 1439,1445 ****
  		 * segment.
  		 */
  		finishing_seg = !ispartialpage &&
! 			(startoffset + npages * BLCKSZ) >= XLogSegSize;
  
  		if (!XLByteLT(LogwrtResult.Write, WriteRqst.Write) ||
  			curridx == XLogCtl->XLogCacheBlck ||
--- 1439,1445 ----
  		 * segment.
  		 */
  		finishing_seg = !ispartialpage &&
! 			(startoffset + npages * XLOG_BLCKSZ) >= XLogSegSize;
  
  		if (!XLByteLT(LogwrtResult.Write, WriteRqst.Write) ||
  			curridx == XLogCtl->XLogCacheBlck ||
***************
*** 1461,1468 ****
  			}
  
  			/* OK to write the page(s) */
! 			from = XLogCtl->pages + startidx * (Size) BLCKSZ;
! 			nbytes = npages * (Size) BLCKSZ;
  			errno = 0;
  			if (write(openLogFile, from, nbytes) != nbytes)
  			{
--- 1461,1468 ----
  			}
  
  			/* OK to write the page(s) */
! 			from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ;
! 			nbytes = npages * (Size) XLOG_BLCKSZ;
  			errno = 0;
  			if (write(openLogFile, from, nbytes) != nbytes)
  			{
***************
*** 1720,1726 ****
  {
  	char		path[MAXPGPATH];
  	char		tmppath[MAXPGPATH];
! 	char		zbuffer[BLCKSZ];
  	uint32		installed_log;
  	uint32		installed_seg;
  	int			max_advance;
--- 1720,1726 ----
  {
  	char		path[MAXPGPATH];
  	char		tmppath[MAXPGPATH];
! 	char		zbuffer[XLOG_BLCKSZ];
  	uint32		installed_log;
  	uint32		installed_seg;
  	int			max_advance;
***************
*** 1858,1864 ****
  {
  	char		path[MAXPGPATH];
  	char		tmppath[MAXPGPATH];
! 	char		buffer[BLCKSZ];
  	int			srcfd;
  	int			fd;
  	int			nbytes;
--- 1858,1864 ----
  {
  	char		path[MAXPGPATH];
  	char		tmppath[MAXPGPATH];
! 	char		buffer[XLOG_BLCKSZ];
  	int			srcfd;
  	int			fd;
  	int			nbytes;
***************
*** 2643,2649 ****
  		 * (2) a static char array isn't guaranteed to have any particular
  		 * alignment, whereas malloc() will provide MAXALIGN'd storage.
  		 */
! 		readBuf = (char *) malloc(BLCKSZ);
  		Assert(readBuf != NULL);
  	}
  
--- 2643,2649 ----
  		 * (2) a static char array isn't guaranteed to have any particular
  		 * alignment, whereas malloc() will provide MAXALIGN'd storage.
  		 */
! 		readBuf = (char *) malloc(XLOG_BLCKSZ);
  		Assert(readBuf != NULL);
  	}
  
***************
*** 2657,2664 ****
  			goto got_record;
  		}
  		/* align old recptr to next page */
! 		if (tmpRecPtr.xrecoff % BLCKSZ != 0)
! 			tmpRecPtr.xrecoff += (BLCKSZ - tmpRecPtr.xrecoff % BLCKSZ);
  		if (tmpRecPtr.xrecoff >= XLogFileSize)
  		{
  			(tmpRecPtr.xlogid)++;
--- 2657,2664 ----
  			goto got_record;
  		}
  		/* align old recptr to next page */
! 		if (tmpRecPtr.xrecoff % XLOG_BLCKSZ != 0)
! 			tmpRecPtr.xrecoff += (XLOG_BLCKSZ - tmpRecPtr.xrecoff % XLOG_BLCKSZ);
  		if (tmpRecPtr.xrecoff >= XLogFileSize)
  		{
  			(tmpRecPtr.xlogid)++;
***************
*** 2702,2708 ****
  		readOff = (uint32) (-1);	/* force read to occur below */
  	}
  
! 	targetPageOff = ((RecPtr->xrecoff % XLogSegSize) / BLCKSZ) * BLCKSZ;
  	if (readOff != targetPageOff)
  	{
  		readOff = targetPageOff;
--- 2702,2708 ----
  		readOff = (uint32) (-1);	/* force read to occur below */
  	}
  
! 	targetPageOff = ((RecPtr->xrecoff % XLogSegSize) / XLOG_BLCKSZ) * XLOG_BLCKSZ;
  	if (readOff != targetPageOff)
  	{
  		readOff = targetPageOff;
***************
*** 2714,2720 ****
  							readId, readSeg, readOff)));
  			goto next_record_is_invalid;
  		}
! 		if (read(readFile, readBuf, BLCKSZ) != BLCKSZ)
  		{
  			ereport(emode,
  					(errcode_for_file_access(),
--- 2714,2720 ----
  							readId, readSeg, readOff)));
  			goto next_record_is_invalid;
  		}
! 		if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
  		{
  			ereport(emode,
  					(errcode_for_file_access(),
***************
*** 2726,2732 ****
  			goto next_record_is_invalid;
  	}
  	pageHeaderSize = XLogPageHeaderSize((XLogPageHeader) readBuf);
! 	targetRecOff = RecPtr->xrecoff % BLCKSZ;
  	if (targetRecOff == 0)
  	{
  		/*
--- 2726,2732 ----
  			goto next_record_is_invalid;
  	}
  	pageHeaderSize = XLogPageHeaderSize((XLogPageHeader) readBuf);
! 	targetRecOff = RecPtr->xrecoff % XLOG_BLCKSZ;
  	if (targetRecOff == 0)
  	{
  		/*
***************
*** 2752,2758 ****
  						RecPtr->xlogid, RecPtr->xrecoff)));
  		goto next_record_is_invalid;
  	}
! 	record = (XLogRecord *) ((char *) readBuf + RecPtr->xrecoff % BLCKSZ);
  
  got_record:;
  
--- 2752,2758 ----
  						RecPtr->xlogid, RecPtr->xrecoff)));
  		goto next_record_is_invalid;
  	}
! 	record = (XLogRecord *) ((char *) readBuf + RecPtr->xrecoff % XLOG_BLCKSZ);
  
  got_record:;
  
***************
*** 2817,2833 ****
  
  	/*
  	 * Allocate or enlarge readRecordBuf as needed.  To avoid useless small
! 	 * increases, round its size to a multiple of BLCKSZ, and make sure it's
! 	 * at least 4*BLCKSZ to start with.  (That is enough for all "normal"
! 	 * records, but very large commit or abort records might need more space.)
  	 */
  	total_len = record->xl_tot_len;
  	if (total_len > readRecordBufSize)
  	{
  		uint32		newSize = total_len;
  
! 		newSize += BLCKSZ - (newSize % BLCKSZ);
! 		newSize = Max(newSize, 4 * BLCKSZ);
  		if (readRecordBuf)
  			free(readRecordBuf);
  		readRecordBuf = (char *) malloc(newSize);
--- 2817,2834 ----
  
  	/*
  	 * Allocate or enlarge readRecordBuf as needed.  To avoid useless small
! 	 * increases, round its size to a multiple of XLOG_BLCKSZ, and make sure
! 	 * it's at least 4*XLOG_BLCKSZ to start with.  (That is enough for all
! 	 * "normal" records, but very large commit or abort records might need
! 	 * more space.)
  	 */
  	total_len = record->xl_tot_len;
  	if (total_len > readRecordBufSize)
  	{
  		uint32		newSize = total_len;
  
! 		newSize += XLOG_BLCKSZ - (newSize % XLOG_BLCKSZ);
! 		newSize = Max(newSize, 4 * Max(BLCKSZ, XLOG_BLCKSZ));
  		if (readRecordBuf)
  			free(readRecordBuf);
  		readRecordBuf = (char *) malloc(newSize);
***************
*** 2845,2851 ****
  
  	buffer = readRecordBuf;
  	nextRecord = NULL;
! 	len = BLCKSZ - RecPtr->xrecoff % BLCKSZ;
  	if (total_len > len)
  	{
  		/* Need to reassemble record */
--- 2846,2852 ----
  
  	buffer = readRecordBuf;
  	nextRecord = NULL;
! 	len = XLOG_BLCKSZ - RecPtr->xrecoff % XLOG_BLCKSZ;
  	if (total_len > len)
  	{
  		/* Need to reassemble record */
***************
*** 2857,2863 ****
  		buffer += len;
  		for (;;)
  		{
! 			readOff += BLCKSZ;
  			if (readOff >= XLogSegSize)
  			{
  				close(readFile);
--- 2858,2864 ----
  		buffer += len;
  		for (;;)
  		{
! 			readOff += XLOG_BLCKSZ;
  			if (readOff >= XLogSegSize)
  			{
  				close(readFile);
***************
*** 2868,2874 ****
  					goto next_record_is_invalid;
  				readOff = 0;
  			}
! 			if (read(readFile, readBuf, BLCKSZ) != BLCKSZ)
  			{
  				ereport(emode,
  						(errcode_for_file_access(),
--- 2869,2875 ----
  					goto next_record_is_invalid;
  				readOff = 0;
  			}
! 			if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
  			{
  				ereport(emode,
  						(errcode_for_file_access(),
***************
*** 2896,2902 ****
  								readId, readSeg, readOff)));
  				goto next_record_is_invalid;
  			}
! 			len = BLCKSZ - pageHeaderSize - SizeOfXLogContRecord;
  			if (contrecord->xl_rem_len > len)
  			{
  				memcpy(buffer, (char *) contrecord + SizeOfXLogContRecord, len);
--- 2897,2903 ----
  								readId, readSeg, readOff)));
  				goto next_record_is_invalid;
  			}
! 			len = XLOG_BLCKSZ - pageHeaderSize - SizeOfXLogContRecord;
  			if (contrecord->xl_rem_len > len)
  			{
  				memcpy(buffer, (char *) contrecord + SizeOfXLogContRecord, len);
***************
*** 2911,2917 ****
  		if (!RecordIsValid(record, *RecPtr, emode))
  			goto next_record_is_invalid;
  		pageHeaderSize = XLogPageHeaderSize((XLogPageHeader) readBuf);
! 		if (BLCKSZ - SizeOfXLogRecord >= pageHeaderSize +
  			MAXALIGN(SizeOfXLogContRecord + contrecord->xl_rem_len))
  		{
  			nextRecord = (XLogRecord *) ((char *) contrecord +
--- 2912,2918 ----
  		if (!RecordIsValid(record, *RecPtr, emode))
  			goto next_record_is_invalid;
  		pageHeaderSize = XLogPageHeaderSize((XLogPageHeader) readBuf);
! 		if (XLOG_BLCKSZ - SizeOfXLogRecord >= pageHeaderSize +
  			MAXALIGN(SizeOfXLogContRecord + contrecord->xl_rem_len))
  		{
  			nextRecord = (XLogRecord *) ((char *) contrecord +
***************
*** 2928,2934 ****
  	/* Record does not cross a page boundary */
  	if (!RecordIsValid(record, *RecPtr, emode))
  		goto next_record_is_invalid;
! 	if (BLCKSZ - SizeOfXLogRecord >= RecPtr->xrecoff % BLCKSZ +
  		MAXALIGN(total_len))
  		nextRecord = (XLogRecord *) ((char *) record + MAXALIGN(total_len));
  	EndRecPtr.xlogid = RecPtr->xlogid;
--- 2929,2935 ----
  	/* Record does not cross a page boundary */
  	if (!RecordIsValid(record, *RecPtr, emode))
  		goto next_record_is_invalid;
! 	if (XLOG_BLCKSZ - SizeOfXLogRecord >= RecPtr->xrecoff % XLOG_BLCKSZ +
  		MAXALIGN(total_len))
  		nextRecord = (XLogRecord *) ((char *) record + MAXALIGN(total_len));
  	EndRecPtr.xlogid = RecPtr->xlogid;
***************
*** 3396,3402 ****
  WriteControlFile(void)
  {
  	int			fd;
! 	char		buffer[BLCKSZ]; /* need not be aligned */
  	char	   *localeptr;
  
  	/*
--- 3397,3403 ----
  WriteControlFile(void)
  {
  	int			fd;
! 	char		buffer[XLOG_BLCKSZ]; /* need not be aligned */
  	char	   *localeptr;
  
  	/*
***************
*** 3409,3414 ****
--- 3410,3416 ----
  	ControlFile->floatFormat = FLOATFORMAT_VALUE;
  
  	ControlFile->blcksz = BLCKSZ;
+ 	ControlFile->xlog_blcksz = XLOG_BLCKSZ;
  	ControlFile->relseg_size = RELSEG_SIZE;
  	ControlFile->xlog_seg_size = XLOG_SEG_SIZE;
  
***************
*** 3441,3457 ****
  	FIN_CRC32(ControlFile->crc);
  
  	/*
! 	 * We write out BLCKSZ bytes into pg_control, zero-padding the excess over
! 	 * sizeof(ControlFileData).  This reduces the odds of premature-EOF errors
! 	 * when reading pg_control.  We'll still fail when we check the contents
! 	 * of the file, but hopefully with a more specific error than "couldn't
! 	 * read pg_control".
  	 */
! 	if (sizeof(ControlFileData) > BLCKSZ)
  		ereport(PANIC,
! 				(errmsg("sizeof(ControlFileData) is larger than BLCKSZ; fix either one")));
  
! 	memset(buffer, 0, BLCKSZ);
  	memcpy(buffer, ControlFile, sizeof(ControlFileData));
  
  	fd = BasicOpenFile(XLOG_CONTROL_FILE,
--- 3443,3459 ----
  	FIN_CRC32(ControlFile->crc);
  
  	/*
! 	 * We write out XLOG_BLCKSZ bytes into pg_control, zero-padding the excess
! 	 * over sizeof(ControlFileData).  This reduces the odds of premature-EOF
! 	 * errors when reading pg_control.  We'll still fail when we check the
! 	 * contents of the file, but hopefully with a more specific error than
! 	 * "couldn't read pg_control".
  	 */
! 	if (sizeof(ControlFileData) > XLOG_BLCKSZ)
  		ereport(PANIC,
! 				(errmsg("sizeof(ControlFileData) is larger than XLOG_BLCKSZ; fix either one")));
  
! 	memset(buffer, 0, XLOG_BLCKSZ);
  	memcpy(buffer, ControlFile, sizeof(ControlFileData));
  
  	fd = BasicOpenFile(XLOG_CONTROL_FILE,
***************
*** 3464,3470 ****
  						XLOG_CONTROL_FILE)));
  
  	errno = 0;
! 	if (write(fd, buffer, BLCKSZ) != BLCKSZ)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
--- 3466,3472 ----
  						XLOG_CONTROL_FILE)));
  
  	errno = 0;
! 	if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
***************
*** 3571,3576 ****
--- 3573,3585 ----
  					   " but the server was compiled with BLCKSZ %d.",
  					   ControlFile->blcksz, BLCKSZ),
  				 errhint("It looks like you need to recompile or initdb.")));
+ 	if (ControlFile->xlog_blcksz != XLOG_BLCKSZ)
+ 		ereport(FATAL,
+ 				(errmsg("database files are incompatible with server"),
+ 			 errdetail("The database cluster was initialized with XLOG_BLCKSZ %d,"
+ 					   " but the server was compiled with XLOG_BLCKSZ %d.",
+ 					   ControlFile->xlog_blcksz, XLOG_BLCKSZ),
+ 				 errhint("It looks like you need to recompile or initdb.")));
  	if (ControlFile->relseg_size != RELSEG_SIZE)
  		ereport(FATAL,
  				(errmsg("database files are incompatible with server"),
***************
*** 3702,3708 ****
  	/* extra alignment padding for XLOG I/O buffers */
  	size = add_size(size, ALIGNOF_XLOG_BUFFER);
  	/* and the buffers themselves */
! 	size = add_size(size, mul_size(BLCKSZ, XLOGbuffers));
  
  	/*
  	 * Note: we don't count ControlFileData, it comes out of the "slop factor"
--- 3711,3717 ----
  	/* extra alignment padding for XLOG I/O buffers */
  	size = add_size(size, ALIGNOF_XLOG_BUFFER);
  	/* and the buffers themselves */
! 	size = add_size(size, mul_size(XLOG_BLCKSZ, XLOGbuffers));
  
  	/*
  	 * Note: we don't count ControlFileData, it comes out of the "slop factor"
***************
*** 3749,3761 ****
  	 */
  	allocptr = (char *) TYPEALIGN(ALIGNOF_XLOG_BUFFER, allocptr);
  	XLogCtl->pages = allocptr;
! 	memset(XLogCtl->pages, 0, (Size) BLCKSZ * XLOGbuffers);
  
  	/*
  	 * Do basic initialization of XLogCtl shared data. (StartupXLOG will fill
  	 * in additional info.)
  	 */
! 	XLogCtl->XLogCacheByte = (Size) BLCKSZ *XLOGbuffers;
  
  	XLogCtl->XLogCacheBlck = XLOGbuffers - 1;
  	XLogCtl->Insert.currpage = (XLogPageHeader) (XLogCtl->pages);
--- 3758,3770 ----
  	 */
  	allocptr = (char *) TYPEALIGN(ALIGNOF_XLOG_BUFFER, allocptr);
  	XLogCtl->pages = allocptr;
! 	memset(XLogCtl->pages, 0, (Size) XLOG_BLCKSZ * XLOGbuffers);
  
  	/*
  	 * Do basic initialization of XLogCtl shared data. (StartupXLOG will fill
  	 * in additional info.)
  	 */
! 	XLogCtl->XLogCacheByte = (Size) XLOG_BLCKSZ * XLOGbuffers;
  
  	XLogCtl->XLogCacheBlck = XLOGbuffers - 1;
  	XLogCtl->Insert.currpage = (XLogPageHeader) (XLogCtl->pages);
***************
*** 3807,3815 ****
  	ThisTimeLineID = 1;
  
  	/* page buffer must be aligned suitably for O_DIRECT */
! 	buffer = (char *) palloc(BLCKSZ + ALIGNOF_XLOG_BUFFER);
  	page = (XLogPageHeader) TYPEALIGN(ALIGNOF_XLOG_BUFFER, buffer);
! 	memset(page, 0, BLCKSZ);
  
  	/* Set up information for the initial checkpoint record */
  	checkPoint.redo.xlogid = 0;
--- 3816,3824 ----
  	ThisTimeLineID = 1;
  
  	/* page buffer must be aligned suitably for O_DIRECT */
! 	buffer = (char *) palloc(XLOG_BLCKSZ + ALIGNOF_XLOG_BUFFER);
  	page = (XLogPageHeader) TYPEALIGN(ALIGNOF_XLOG_BUFFER, buffer);
! 	memset(page, 0, XLOG_BLCKSZ);
  
  	/* Set up information for the initial checkpoint record */
  	checkPoint.redo.xlogid = 0;
***************
*** 3861,3867 ****
  
  	/* Write the first page with the initial record */
  	errno = 0;
! 	if (write(openLogFile, page, BLCKSZ) != BLCKSZ)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
--- 3870,3876 ----
  
  	/* Write the first page with the initial record */
  	errno = 0;
! 	if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
***************
*** 4718,4734 ****
  	Insert->PrevRecord = LastRec;
  	XLogCtl->xlblocks[0].xlogid = openLogId;
  	XLogCtl->xlblocks[0].xrecoff =
! 		((EndOfLog.xrecoff - 1) / BLCKSZ + 1) * BLCKSZ;
  
  	/*
  	 * Tricky point here: readBuf contains the *last* block that the LastRec
  	 * record spans, not the one it starts in.	The last block is indeed the
  	 * one we want to use.
  	 */
! 	Assert(readOff == (XLogCtl->xlblocks[0].xrecoff - BLCKSZ) % XLogSegSize);
! 	memcpy((char *) Insert->currpage, readBuf, BLCKSZ);
  	Insert->currpos = (char *) Insert->currpage +
! 		(EndOfLog.xrecoff + BLCKSZ - XLogCtl->xlblocks[0].xrecoff);
  
  	LogwrtResult.Write = LogwrtResult.Flush = EndOfLog;
  
--- 4727,4743 ----
  	Insert->PrevRecord = LastRec;
  	XLogCtl->xlblocks[0].xlogid = openLogId;
  	XLogCtl->xlblocks[0].xrecoff =
! 		((EndOfLog.xrecoff - 1) / XLOG_BLCKSZ + 1) * XLOG_BLCKSZ;
  
  	/*
  	 * Tricky point here: readBuf contains the *last* block that the LastRec
  	 * record spans, not the one it starts in.	The last block is indeed the
  	 * one we want to use.
  	 */
! 	Assert(readOff == (XLogCtl->xlblocks[0].xrecoff - XLOG_BLCKSZ) % XLogSegSize);
! 	memcpy((char *) Insert->currpage, readBuf, XLOG_BLCKSZ);
  	Insert->currpos = (char *) Insert->currpage +
! 		(EndOfLog.xrecoff + XLOG_BLCKSZ - XLogCtl->xlblocks[0].xrecoff);
  
  	LogwrtResult.Write = LogwrtResult.Flush = EndOfLog;
  
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.314
diff -c -r1.314 guc.c
*** src/backend/utils/misc/guc.c	7 Mar 2006 02:54:23 -0000	1.314
--- src/backend/utils/misc/guc.c	3 Apr 2006 15:03:10 -0000
***************
*** 1387,1393 ****
  			NULL
  		},
  		&XLOGbuffers,
! 		8, 4, INT_MAX, NULL, NULL
  	},
  
  	{
--- 1387,1393 ----
  			NULL
  		},
  		&XLOGbuffers,
! 		16, 8, INT_MAX, NULL, NULL
  	},
  
  	{
Index: src/backend/utils/misc/postgresql.conf.sample
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/postgresql.conf.sample,v
retrieving revision 1.175
diff -c -r1.175 postgresql.conf.sample
*** src/backend/utils/misc/postgresql.conf.sample	6 Mar 2006 22:52:10 -0000	1.175
--- src/backend/utils/misc/postgresql.conf.sample	3 Apr 2006 15:03:10 -0000
***************
*** 141,147 ****
  					#   fsync_writethrough
  					#   open_sync
  #full_page_writes = on			# recover from partial page writes
! #wal_buffers = 8			# min 4, 8KB each
  #commit_delay = 0			# range 0-100000, in microseconds
  #commit_siblings = 5			# range 1-1000
  
--- 141,147 ----
  					#   fsync_writethrough
  					#   open_sync
  #full_page_writes = on			# recover from partial page writes
! #wal_buffers = 16			# min 4, 8KB each
  #commit_delay = 0			# range 0-100000, in microseconds
  #commit_siblings = 5			# range 1-1000
  
Index: src/bin/pg_controldata/pg_controldata.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_controldata/pg_controldata.c,v
retrieving revision 1.27
diff -c -r1.27 pg_controldata.c
*** src/bin/pg_controldata/pg_controldata.c	15 Oct 2005 02:49:37 -0000	1.27
--- src/bin/pg_controldata/pg_controldata.c	3 Apr 2006 15:03:10 -0000
***************
*** 172,177 ****
--- 172,178 ----
  	/* we don't print floatFormat since can't say much useful about it */
  	printf(_("Database block size:                  %u\n"), ControlFile.blcksz);
  	printf(_("Blocks per segment of large relation: %u\n"), ControlFile.relseg_size);
+ 	printf(_("WAL block size:                       %u\n"), ControlFile.xlog_blcksz);
  	printf(_("Bytes per WAL segment:                %u\n"), ControlFile.xlog_seg_size);
  	printf(_("Maximum length of identifiers:        %u\n"), ControlFile.nameDataLen);
  	printf(_("Maximum columns in an index:          %u\n"), ControlFile.indexMaxKeys);
Index: src/include/pg_config_manual.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/pg_config_manual.h,v
retrieving revision 1.20
diff -c -r1.20 pg_config_manual.h
*** src/include/pg_config_manual.h	5 Jan 2006 03:01:37 -0000	1.20
--- src/include/pg_config_manual.h	3 Apr 2006 15:03:10 -0000
***************
*** 23,29 ****
   *
   * Changing BLCKSZ requires an initdb.
   */
! #define BLCKSZ	8192
  
  /*
   * RELSEG_SIZE is the maximum number of blocks allowed in one disk
--- 23,32 ----
   *
   * Changing BLCKSZ requires an initdb.
   */
! #define BLCKSZ	     8192
! 
! #define XLOG_BLCKSZ	 4096
! 
  
  /*
   * RELSEG_SIZE is the maximum number of blocks allowed in one disk
Index: src/include/catalog/pg_control.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_control.h,v
retrieving revision 1.27
diff -c -r1.27 pg_control.h
*** src/include/catalog/pg_control.h	5 Mar 2006 15:58:54 -0000	1.27
--- src/include/catalog/pg_control.h	3 Apr 2006 15:03:10 -0000
***************
*** 22,28 ****
  
  
  /* Version identifier for this pg_control format */
! #define PG_CONTROL_VERSION	812
  
  /*
   * Body of CheckPoint XLOG records.  This is declared here because we keep
--- 22,28 ----
  
  
  /* Version identifier for this pg_control format */
! #define PG_CONTROL_VERSION	820
  
  /*
   * Body of CheckPoint XLOG records.  This is declared here because we keep
***************
*** 129,134 ****
--- 129,135 ----
  	uint32		blcksz;			/* block size for this DB */
  	uint32		relseg_size;	/* blocks per segment of large relation */
  
+ 	uint32		xlog_blcksz;	/* block size for each WAL buffer/page */
  	uint32		xlog_seg_size;	/* size of each WAL segment */
  
  	uint32		nameDataLen;	/* catalog name field width */
---------------------------(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