diff -rcN postgresql-CVS-01-19.org/src/backend/access/transam/readahead.c postgresql-CVS-01-19/src/backend/access/transam/readahead.c *** postgresql-CVS-01-19.org/src/backend/access/transam/readahead.c 2009-01-20 14:27:45.000000000 +0900 --- postgresql-CVS-01-19/src/backend/access/transam/readahead.c 2009-01-20 17:03:38.000000000 +0900 *************** *** 20,25 **** --- 20,26 ---- #include "catalog/catalog.h" #include "storage/relfilenode.h" #include "storage/block.h" + #include "storage/bufmgr.h" #include "storage/smgr.h" /* *************** *** 135,141 **** ReadAheadExecute(void) { int i; - SMgrRelation reln; XLogReadAhead last_entry = { { 0, 0, 0, }, 0, 0, false }; ereport(DEBUG1, (errmsg("%d blocks are prefetch candidate", --- 136,141 ---- *************** *** 155,166 **** continue; } - /* Create SMgrRelation object */ - reln = smgropen(ReadAheadQueue[i].node); - /* Read ahead with prefetch API */ ! smgrprefetch(reln, MAIN_FORKNUM, ReadAheadQueue[i].blkno); ! /* Store XLogReadAhead to skip duplicate pages. */ last_entry = ReadAheadQueue[i]; } --- 155,164 ---- continue; } /* Read ahead with prefetch API */ ! PrefetchBufferWithoutRelcache(ReadAheadQueue[i].node, false, ! MAIN_FORKNUM, ReadAheadQueue[i].blkno); ! /* Store XLogReadAhead to skip duplicate pages. */ last_entry = ReadAheadQueue[i]; } diff -rcN postgresql-CVS-01-19.org/src/backend/storage/buffer/bufmgr.c postgresql-CVS-01-19/src/backend/storage/buffer/bufmgr.c *** postgresql-CVS-01-19.org/src/backend/storage/buffer/bufmgr.c 2009-01-20 14:23:15.000000000 +0900 --- postgresql-CVS-01-19/src/backend/storage/buffer/bufmgr.c 2009-01-20 17:59:27.000000000 +0900 *************** *** 79,85 **** /* local state for LockBufferForCleanup */ static volatile BufferDesc *PinCountWaitBuf = NULL; ! static Buffer ReadBuffer_common(SMgrRelation reln, bool isLocalBuf, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode , BufferAccessStrategy strategy, --- 79,86 ---- /* local state for LockBufferForCleanup */ static volatile BufferDesc *PinCountWaitBuf = NULL; ! static void PrefetchBuffer_common(SMgrRelation smgr, bool isTemp, ! ForkNumber forkNum, BlockNumber blockNum); static Buffer ReadBuffer_common(SMgrRelation reln, bool isLocalBuf, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode , BufferAccessStrategy strategy, *************** *** 109,114 **** --- 110,119 ---- * buffer. Instead it tries to ensure that a future ReadBuffer for the given * block will not be delayed by the I/O. Prefetching is optional. * No-op if prefetching isn't compiled in. + * + * To provide the prefetch API for during recovery, prepare interfaces + * and a prefetch API call separately. This is based on ReadBuffer(), + * ReadBufferExtended(), and ReadBuffer_common(). */ void PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum) *************** *** 119,129 **** /* Open it at the smgr level if not already done */ RelationOpenSmgr(reln); ! if (reln->rd_istemp) { /* pass it off to localbuf.c */ ! LocalPrefetchBuffer(reln->rd_smgr, forkNum, blockNum); } else { --- 124,165 ---- /* Open it at the smgr level if not already done */ RelationOpenSmgr(reln); + + /* Prefetch the buffer */ + PrefetchBuffer_common(reln->rd_smgr, reln->rd_istemp, forkNum, blockNum); + #endif /* USE_PREFETCH */ + } + + /* + * PrefetchBufferWithoutRelcache -- like ReadBufferWithoutRelcache, it doesn't + * require relcache entry for the relation. + */ + void + PrefetchBufferWithoutRelcache(RelFileNode rnode, bool isTemp, + ForkNumber forkNum, BlockNumber blockNum) + { + #ifdef USE_PREFETCH + SMgrRelation smgr; ! /* Create SMgrRelation object */ ! smgr = smgropen(rnode); ! ! /* Prefetch the buffer */ ! PrefetchBuffer_common(smgr, isTemp, forkNum, blockNum); ! #endif /* USE_PREFETCH */ ! } ! ! /* ! * PrefetchBuffer_common -- common logic for all PrefetchBuffer variants ! */ ! static void ! PrefetchBuffer_common(SMgrRelation smgr, bool isTemp, ForkNumber forkNum, ! BlockNumber blockNum) ! { ! if (isTemp) { /* pass it off to localbuf.c */ ! LocalPrefetchBuffer(smgr, forkNum, blockNum); } else { *************** *** 133,139 **** int buf_id; /* create a tag so we can lookup the buffer */ ! INIT_BUFFERTAG(newTag, reln->rd_smgr->smgr_rnode, forkNum, blockNum); /* determine its hash code and partition lock ID */ newHash = BufTableHashCode(&newTag); --- 169,175 ---- int buf_id; /* create a tag so we can lookup the buffer */ ! INIT_BUFFERTAG(newTag, smgr->smgr_rnode, forkNum, blockNum); /* determine its hash code and partition lock ID */ newHash = BufTableHashCode(&newTag); *************** *** 146,157 **** /* If not in buffers, initiate prefetch */ if (buf_id < 0) ! smgrprefetch(reln->rd_smgr, forkNum, blockNum); } - #endif /* USE_PREFETCH */ } - /* * ReadBuffer -- a shorthand for ReadBufferExtended, for reading from main * fork with RBM_NORMAL mode and default strategy. --- 182,191 ---- /* If not in buffers, initiate prefetch */ if (buf_id < 0) ! smgrprefetch(smgr, forkNum, blockNum); } } /* * ReadBuffer -- a shorthand for ReadBufferExtended, for reading from main * fork with RBM_NORMAL mode and default strategy. diff -rcN postgresql-CVS-01-19.org/src/include/storage/bufmgr.h postgresql-CVS-01-19/src/include/storage/bufmgr.h *** postgresql-CVS-01-19.org/src/include/storage/bufmgr.h 2009-01-20 14:23:14.000000000 +0900 --- postgresql-CVS-01-19/src/include/storage/bufmgr.h 2009-01-20 17:07:25.000000000 +0900 *************** *** 155,160 **** --- 155,162 ---- */ extern void PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum); + extern void PrefetchBufferWithoutRelcache(RelFileNode rnode, bool isTemp, + ForkNumber forkNum, BlockNumber blockNum); extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum); extern Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode,