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