diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 2f91bc8..92f6800 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -518,6 +518,11 @@ static XLogCtlData *XLogCtl = NULL; static ControlFileData *ControlFile = NULL; /* + * Local bufferspace for use in XLOG_HINT records. + */ +char *HintBuffer; + +/* * Macros for managing XLogInsert state. In most cases, the calling routine * has local copies of XLogCtl->Insert and/or XLogCtl->Insert->curridx, * so these are passed as parameters instead of being fetched via XLogCtl. @@ -880,7 +885,10 @@ begin:; info |= XLR_BKP_BLOCK(i); bkpb = &(dtbuf_xlg[i]); - page = (char *) BufferGetBlock(dtbuf[i]); + if (isHint) + page = (char *) HintBuffer; + else + page = (char *) BufferGetBlock(dtbuf[i]); rdt->next = &(dtbuf_rdt1[i]); rdt = rdt->next; @@ -7663,6 +7671,19 @@ XLogSaveBufferForHint(Buffer buffer) int watermark = XLOG_HINT_WATERMARK; /* + * Copy the buffer to a local area, so that we can calculate the WAL + * CRC without worrying that we only have share lock on the buffer. + */ + if (HintBuffer == NULL) + { + HintBuffer = malloc(BLCKSZ); + if (HintBuffer == NULL) + elog(ERROR, "out of memory"); + MemSet(HintBuffer, 0, BLCKSZ); + } + memcpy(HintBuffer, (char *) BufferGetBlock(buffer), BLCKSZ); + + /* * Not allowed to have zero-length records, so use a small watermark */ rdata[0].data = (char *) (&watermark);