|
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 | }
|
|