|
11 | 11 | * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group |
12 | 12 | * Portions Copyright (c) 1994, Regents of the University of California |
13 | 13 | * |
14 | | - * $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.66 2009/01/01 17:23:36 momjian Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.67 2009/01/20 18:59:37 heikki Exp $ |
15 | 15 | * |
16 | 16 | *------------------------------------------------------------------------- |
17 | 17 | */ |
@@ -217,31 +217,41 @@ XLogCheckInvalidPages(void) |
217 | 217 |
|
218 | 218 | /* |
219 | 219 | * XLogReadBuffer |
220 | | - *A shorthand of XLogReadBufferExtended(), for reading from the main |
221 | | - *fork. |
| 220 | + *Read a page during XLOG replay. |
| 221 | + * |
| 222 | + * This is a shorthand of XLogReadBufferExtended() followed by |
| 223 | + * LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE), for reading from the main |
| 224 | + * fork. |
| 225 | + * |
| 226 | + * (Getting the lock is not really necessary, since we expect that this is |
| 227 | + * only used during single-process XLOG replay, but some subroutines such |
| 228 | + * as MarkBufferDirty will complain if we don't. And hopefully we'll get |
| 229 | + * hot standby support in the future, where there will be backends running |
| 230 | + * read-only queries during XLOG replay.) |
| 231 | + * |
| 232 | + * The returned buffer is exclusively-locked. |
222 | 233 | * |
223 | 234 | * For historical reasons, instead of a ReadBufferMode argument, this only |
224 | 235 | * supports RBM_ZERO (init == true) and RBM_NORMAL (init == false) modes. |
225 | 236 | */ |
226 | 237 | Buffer |
227 | 238 | XLogReadBuffer(RelFileNodernode,BlockNumberblkno,boolinit) |
228 | 239 | { |
229 | | -returnXLogReadBufferExtended(rnode,MAIN_FORKNUM,blkno, |
230 | | -init ?RBM_ZERO :RBM_NORMAL); |
| 240 | +Bufferbuf; |
| 241 | +buf=XLogReadBufferExtended(rnode,MAIN_FORKNUM,blkno, |
| 242 | +init ?RBM_ZERO :RBM_NORMAL); |
| 243 | +if (BufferIsValid(buf)) |
| 244 | +LockBuffer(buf,BUFFER_LOCK_EXCLUSIVE); |
| 245 | + |
| 246 | +returnbuf; |
231 | 247 | } |
232 | 248 |
|
233 | 249 | /* |
234 | 250 | * XLogReadBufferExtended |
235 | 251 | *Read a page during XLOG replay |
236 | 252 | * |
237 | | - * This is functionally comparable to ReadBuffer followed by |
238 | | - * LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE): you get back a pinned |
239 | | - * and locked buffer. (Getting the lock is not really necessary, since we |
240 | | - * expect that this is only used during single-process XLOG replay, but |
241 | | - * some subroutines such as MarkBufferDirty will complain if we don't.) |
242 | | - * |
243 | | - * There's some differences in the behavior wrt. the "mode" argument, |
244 | | - * compared to ReadBufferExtended: |
| 253 | + * This is functionally comparable to ReadBufferExtended. There's some |
| 254 | + * differences in the behavior wrt. the "mode" argument: |
245 | 255 | * |
246 | 256 | * In RBM_NORMAL mode, if the page doesn't exist, or contains all-zeroes, we |
247 | 257 | * return InvalidBuffer. In this case the caller should silently skip the |
@@ -306,16 +316,19 @@ XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum, |
306 | 316 | Assert(BufferGetBlockNumber(buffer)==blkno); |
307 | 317 | } |
308 | 318 |
|
309 | | -LockBuffer(buffer,BUFFER_LOCK_EXCLUSIVE); |
310 | | - |
311 | 319 | if (mode==RBM_NORMAL) |
312 | 320 | { |
313 | 321 | /* check that page has been initialized */ |
314 | 322 | Pagepage= (Page)BufferGetPage(buffer); |
315 | 323 |
|
| 324 | +/* |
| 325 | + * We assume that PageIsNew is safe without a lock. During recovery, |
| 326 | + * there should be no other backends that could modify the buffer at |
| 327 | + * the same time. |
| 328 | + */ |
316 | 329 | if (PageIsNew(page)) |
317 | 330 | { |
318 | | -UnlockReleaseBuffer(buffer); |
| 331 | +ReleaseBuffer(buffer); |
319 | 332 | log_invalid_page(rnode,forknum,blkno, true); |
320 | 333 | returnInvalidBuffer; |
321 | 334 | } |
|