PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
xlogutils.h File Reference
#include "access/xlogreader.h"
#include "storage/bufmgr.h"
Include dependency graph for xlogutils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  XLogRedoAction { BLK_NEEDS_REDO, BLK_DONE, BLK_RESTORED, BLK_NOTFOUND }
 

Functions

bool XLogHaveInvalidPages (void)
 
void XLogCheckInvalidPages (void)
 
void XLogDropRelation (RelFileNode rnode, ForkNumber forknum)
 
void XLogDropDatabase (Oid dbid)
 
void XLogTruncateRelation (RelFileNode rnode, ForkNumber forkNum, BlockNumber nblocks)
 
XLogRedoAction XLogReadBufferForRedo (XLogReaderState *record, uint8 buffer_id, Buffer *buf)
 
Buffer XLogInitBufferForRedo (XLogReaderState *record, uint8 block_id)
 
XLogRedoAction XLogReadBufferForRedoExtended (XLogReaderState *record, uint8 buffer_id, ReadBufferMode mode, bool get_cleanup_lock, Buffer *buf)
 
Buffer XLogReadBufferExtended (RelFileNode rnode, ForkNumber forknum, BlockNumber blkno, ReadBufferMode mode)
 
Relation CreateFakeRelcacheEntry (RelFileNode rnode)
 
void FreeFakeRelcacheEntry (Relation fakerel)
 
int read_local_xlog_page (XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *cur_page, TimeLineID *pageTLI)
 

Enumeration Type Documentation

Enumerator
BLK_NEEDS_REDO 
BLK_DONE 
BLK_RESTORED 
BLK_NOTFOUND 

Definition at line 27 of file xlogutils.h.

28 {
29  BLK_NEEDS_REDO, /* changes from WAL record need to be applied */
30  BLK_DONE, /* block is already up-to-date */
31  BLK_RESTORED, /* block was restored from a full-page image */
32  BLK_NOTFOUND /* block was not found (and hence does not
33  * need to be replayed) */
XLogRedoAction
Definition: xlogutils.h:27

Function Documentation

Relation CreateFakeRelcacheEntry ( RelFileNode  rnode)

Definition at line 549 of file xlogutils.c.

References Assert, LockRelId::dbId, RelFileNode::dbNode, InRecovery, InvalidBackendId, LockInfoData::lockRelId, NULL, palloc0(), FakeRelCacheEntryData::pgc, RelationData::rd_backend, RelationData::rd_lockInfo, RelationData::rd_node, RelationData::rd_rel, RelationData::rd_smgr, RelationGetRelationName, LockRelId::relId, RelFileNode::relNode, and RELPERSISTENCE_PERMANENT.

Referenced by heap_xlog_delete(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), and smgr_redo().

550 {
551  FakeRelCacheEntry fakeentry;
552  Relation rel;
553 
555 
556  /* Allocate the Relation struct and all related space in one block. */
557  fakeentry = palloc0(sizeof(FakeRelCacheEntryData));
558  rel = (Relation) fakeentry;
559 
560  rel->rd_rel = &fakeentry->pgc;
561  rel->rd_node = rnode;
562  /* We will never be working with temp rels during recovery */
564 
565  /* It must be a permanent table if we're in recovery. */
566  rel->rd_rel->relpersistence = RELPERSISTENCE_PERMANENT;
567 
568  /* We don't know the name of the relation; use relfilenode instead */
569  sprintf(RelationGetRelationName(rel), "%u", rnode.relNode);
570 
571  /*
572  * We set up the lockRelId in case anything tries to lock the dummy
573  * relation. Note that this is fairly bogus since relNode may be
574  * different from the relation's OID. It shouldn't really matter though,
575  * since we are presumably running by ourselves and can't have any lock
576  * conflicts ...
577  */
578  rel->rd_lockInfo.lockRelId.dbId = rnode.dbNode;
579  rel->rd_lockInfo.lockRelId.relId = rnode.relNode;
580 
581  rel->rd_smgr = NULL;
582 
583  return rel;
584 }
LockRelId lockRelId
Definition: rel.h:44
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
bool InRecovery
Definition: xlog.c:190
Oid dbId
Definition: rel.h:39
Form_pg_class rd_rel
Definition: rel.h:113
#define RELPERSISTENCE_PERMANENT
Definition: pg_class.h:170
struct RelationData * Relation
Definition: relcache.h:21
LockInfoData rd_lockInfo
Definition: rel.h:116
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define InvalidBackendId
Definition: backendid.h:23
void * palloc0(Size size)
Definition: mcxt.c:920
RelFileNode rd_node
Definition: rel.h:85
#define NULL
Definition: c.h:226
BackendId rd_backend
Definition: rel.h:89
#define Assert(condition)
Definition: c.h:670
FormData_pg_class pgc
Definition: xlogutils.c:531
Oid relId
Definition: rel.h:38
void FreeFakeRelcacheEntry ( Relation  fakerel)

Definition at line 590 of file xlogutils.c.

References NULL, pfree(), RelationData::rd_smgr, and smgrclearowner().

Referenced by heap_xlog_delete(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), and smgr_redo().

591 {
592  /* make sure the fakerel is not referenced by the SmgrRelation anymore */
593  if (fakerel->rd_smgr != NULL)
594  smgrclearowner(&fakerel->rd_smgr, fakerel->rd_smgr);
595  pfree(fakerel);
596 }
void smgrclearowner(SMgrRelation *owner, SMgrRelation reln)
Definition: smgr.c:222
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
void pfree(void *pointer)
Definition: mcxt.c:992
#define NULL
Definition: c.h:226
int read_local_xlog_page ( XLogReaderState state,
XLogRecPtr  targetPagePtr,
int  reqLen,
XLogRecPtr  targetRecPtr,
char *  cur_page,
TimeLineID pageTLI 
)

Definition at line 765 of file xlogutils.c.

References CHECK_FOR_INTERRUPTS, GetFlushRecPtr(), GetXLogReplayRecPtr(), pg_usleep(), RecoveryInProgress(), ThisTimeLineID, and XLogRead().

Referenced by logical_read_local_xlog_page(), and XlogReadTwoPhaseData().

768 {
769  XLogRecPtr read_upto,
770  loc;
771  int count;
772 
773  loc = targetPagePtr + reqLen;
774  while (1)
775  {
776  /*
777  * TODO: we're going to have to do something more intelligent about
778  * timelines on standbys. Use readTimeLineHistory() and
779  * tliOfPointInHistory() to get the proper LSN? For now we'll catch
780  * that case earlier, but the code and TODO is left in here for when
781  * that changes.
782  */
783  if (!RecoveryInProgress())
784  {
785  *pageTLI = ThisTimeLineID;
786  read_upto = GetFlushRecPtr();
787  }
788  else
789  read_upto = GetXLogReplayRecPtr(pageTLI);
790 
791  if (loc <= read_upto)
792  break;
793 
795  pg_usleep(1000L);
796  }
797 
798  if (targetPagePtr + XLOG_BLCKSZ <= read_upto)
799  {
800  /*
801  * more than one block available; read only that block, have caller
802  * come back if they need more.
803  */
804  count = XLOG_BLCKSZ;
805  }
806  else if (targetPagePtr + reqLen > read_upto)
807  {
808  /* not enough data there */
809  return -1;
810  }
811  else
812  {
813  /* enough bytes available to satisfy the request */
814  count = read_upto - targetPagePtr;
815  }
816 
817  /*
818  * Even though we just determined how much of the page can be validly read
819  * as 'count', read the whole page anyway. It's guaranteed to be
820  * zero-padded up to the page boundary if it's incomplete.
821  */
822  XLogRead(cur_page, *pageTLI, targetPagePtr, XLOG_BLCKSZ);
823 
824  /* number of valid bytes in the buffer */
825  return count;
826 }
static void XLogRead(char *buf, TimeLineID tli, XLogRecPtr startptr, Size count)
Definition: xlogutils.c:655
XLogRecPtr GetFlushRecPtr(void)
Definition: xlog.c:8174
bool RecoveryInProgress(void)
Definition: xlog.c:7825
void pg_usleep(long microsec)
Definition: signal.c:53
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11004
TimeLineID ThisTimeLineID
Definition: xlog.c:177
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
void XLogCheckInvalidPages ( void  )

Definition at line 219 of file xlogutils.c.

References xl_invalid_page_key::blkno, elog, xl_invalid_page_key::forkno, hash_destroy(), hash_seq_init(), hash_seq_search(), xl_invalid_page::key, xl_invalid_page_key::node, NULL, PANIC, xl_invalid_page::present, report_invalid_page(), status(), and WARNING.

Referenced by CheckRecoveryConsistency().

220 {
222  xl_invalid_page *hentry;
223  bool foundone = false;
224 
225  if (invalid_page_tab == NULL)
226  return; /* nothing to do */
227 
229 
230  /*
231  * Our strategy is to emit WARNING messages for all remaining entries and
232  * only PANIC after we've dumped all the available info.
233  */
234  while ((hentry = (xl_invalid_page *) hash_seq_search(&status)) != NULL)
235  {
236  report_invalid_page(WARNING, hentry->key.node, hentry->key.forkno,
237  hentry->key.blkno, hentry->present);
238  foundone = true;
239  }
240 
241  if (foundone)
242  elog(PANIC, "WAL contains references to invalid pages");
243 
246 }
void hash_destroy(HTAB *hashp)
Definition: dynahash.c:793
ForkNumber forkno
Definition: xlogutils.c:46
#define PANIC
Definition: elog.h:53
RelFileNode node
Definition: xlogutils.c:45
static void report_invalid_page(int elevel, RelFileNode node, ForkNumber forkno, BlockNumber blkno, bool present)
Definition: xlogutils.c:61
BlockNumber blkno
Definition: xlogutils.c:47
xl_invalid_page_key key
Definition: xlogutils.c:52
#define WARNING
Definition: elog.h:40
#define NULL
Definition: c.h:226
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1353
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1343
static HTAB * invalid_page_tab
Definition: xlogutils.c:56
#define elog
Definition: elog.h:219
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:222
void XLogDropDatabase ( Oid  dbid)

Definition at line 616 of file xlogutils.c.

References forget_invalid_pages_db(), and smgrcloseall().

Referenced by dbase_redo().

617 {
618  /*
619  * This is unnecessarily heavy-handed, as it will close SMgrRelation
620  * objects for other databases as well. DROP DATABASE occurs seldom enough
621  * that it's not worth introducing a variant of smgrclose for just this
622  * purpose. XXX: Or should we rather leave the smgr entries dangling?
623  */
624  smgrcloseall();
625 
627 }
static void forget_invalid_pages_db(Oid dbid)
Definition: xlogutils.c:176
void smgrcloseall(void)
Definition: smgr.c:326
void XLogDropRelation ( RelFileNode  rnode,
ForkNumber  forknum 
)

Definition at line 605 of file xlogutils.c.

References forget_invalid_pages().

Referenced by xact_redo_abort(), and xact_redo_commit().

606 {
607  forget_invalid_pages(rnode, forknum, 0);
608 }
static void forget_invalid_pages(RelFileNode node, ForkNumber forkno, BlockNumber minblkno)
Definition: xlogutils.c:141
bool XLogHaveInvalidPages ( void  )

Definition at line 209 of file xlogutils.c.

References hash_get_num_entries(), and NULL.

Referenced by RecoveryRestartPoint().

210 {
211  if (invalid_page_tab != NULL &&
213  return true;
214  return false;
215 }
long hash_get_num_entries(HTAB *hashp)
Definition: dynahash.c:1297
#define NULL
Definition: c.h:226
static HTAB * invalid_page_tab
Definition: xlogutils.c:56
Buffer XLogReadBufferExtended ( RelFileNode  rnode,
ForkNumber  forknum,
BlockNumber  blkno,
ReadBufferMode  mode 
)

Definition at line 436 of file xlogutils.c.

References Assert, BUFFER_LOCK_UNLOCK, BufferGetBlockNumber(), BufferGetPage, InRecovery, InvalidBackendId, InvalidBuffer, LockBuffer(), log_invalid_page(), NULL, P_NEW, PageIsNew, RBM_NORMAL, RBM_NORMAL_NO_LOG, RBM_ZERO_AND_CLEANUP_LOCK, RBM_ZERO_AND_LOCK, ReadBufferWithoutRelcache(), ReleaseBuffer(), smgrcreate(), smgrnblocks(), and smgropen().

Referenced by btree_xlog_delete_get_latestRemovedXid(), btree_xlog_vacuum(), checkXLogConsistency(), XLogReadBufferForRedoExtended(), and XLogRecordPageWithFreeSpace().

438 {
439  BlockNumber lastblock;
440  Buffer buffer;
441  SMgrRelation smgr;
442 
443  Assert(blkno != P_NEW);
444 
445  /* Open the relation at smgr level */
446  smgr = smgropen(rnode, InvalidBackendId);
447 
448  /*
449  * Create the target file if it doesn't already exist. This lets us cope
450  * if the replay sequence contains writes to a relation that is later
451  * deleted. (The original coding of this routine would instead suppress
452  * the writes, but that seems like it risks losing valuable data if the
453  * filesystem loses an inode during a crash. Better to write the data
454  * until we are actually told to delete the file.)
455  */
456  smgrcreate(smgr, forknum, true);
457 
458  lastblock = smgrnblocks(smgr, forknum);
459 
460  if (blkno < lastblock)
461  {
462  /* page exists in file */
463  buffer = ReadBufferWithoutRelcache(rnode, forknum, blkno,
464  mode, NULL);
465  }
466  else
467  {
468  /* hm, page doesn't exist in file */
469  if (mode == RBM_NORMAL)
470  {
471  log_invalid_page(rnode, forknum, blkno, false);
472  return InvalidBuffer;
473  }
474  if (mode == RBM_NORMAL_NO_LOG)
475  return InvalidBuffer;
476  /* OK to extend the file */
477  /* we do this in recovery only - no rel-extension lock needed */
479  buffer = InvalidBuffer;
480  do
481  {
482  if (buffer != InvalidBuffer)
483  {
484  if (mode == RBM_ZERO_AND_LOCK || mode == RBM_ZERO_AND_CLEANUP_LOCK)
486  ReleaseBuffer(buffer);
487  }
488  buffer = ReadBufferWithoutRelcache(rnode, forknum,
489  P_NEW, mode, NULL);
490  }
491  while (BufferGetBlockNumber(buffer) < blkno);
492  /* Handle the corner case that P_NEW returns non-consecutive pages */
493  if (BufferGetBlockNumber(buffer) != blkno)
494  {
495  if (mode == RBM_ZERO_AND_LOCK || mode == RBM_ZERO_AND_CLEANUP_LOCK)
497  ReleaseBuffer(buffer);
498  buffer = ReadBufferWithoutRelcache(rnode, forknum, blkno,
499  mode, NULL);
500  }
501  }
502 
503  if (mode == RBM_NORMAL)
504  {
505  /* check that page has been initialized */
506  Page page = (Page) BufferGetPage(buffer);
507 
508  /*
509  * We assume that PageIsNew is safe without a lock. During recovery,
510  * there should be no other backends that could modify the buffer at
511  * the same time.
512  */
513  if (PageIsNew(page))
514  {
515  ReleaseBuffer(buffer);
516  log_invalid_page(rnode, forknum, blkno, true);
517  return InvalidBuffer;
518  }
519  }
520 
521  return buffer;
522 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition: smgr.c:376
bool InRecovery
Definition: xlog.c:190
#define InvalidBuffer
Definition: buf.h:25
Buffer ReadBufferWithoutRelcache(RelFileNode rnode, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:682
uint32 BlockNumber
Definition: block.h:31
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3292
#define P_NEW
Definition: bufmgr.h:82
static void log_invalid_page(RelFileNode node, ForkNumber forkno, BlockNumber blkno, bool present)
Definition: xlogutils.c:77
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
SMgrRelation smgropen(RelFileNode rnode, BackendId backend)
Definition: smgr.c:137
#define InvalidBackendId
Definition: backendid.h:23
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:672
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2588
#define PageIsNew(page)
Definition: bufpage.h:226
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
XLogRedoAction XLogReadBufferForRedoExtended ( XLogReaderState record,
uint8  buffer_id,
ReadBufferMode  mode,
bool  get_cleanup_lock,
Buffer buf 
)

Definition at line 325 of file xlogutils.c.

References Assert, BKPBLOCK_WILL_INIT, BLK_DONE, BLK_NEEDS_REDO, BLK_NOTFOUND, BLK_RESTORED, XLogReaderState::blocks, BUFFER_LOCK_EXCLUSIVE, BufferGetPage, BufferIsValid, elog, XLogReaderState::EndRecPtr, ERROR, DecodedBkpBlock::flags, FlushOneBuffer(), INIT_FORKNUM, LockBuffer(), LockBufferForCleanup(), MarkBufferDirty(), PageGetLSN, PageIsNew, PageSetLSN, PANIC, RBM_ZERO_AND_CLEANUP_LOCK, RBM_ZERO_AND_LOCK, RestoreBlockImage(), XLogReadBufferExtended(), XLogRecBlockImageApply, XLogRecGetBlockTag(), and XLogRecHasBlockImage.

Referenced by btree_xlog_vacuum(), heap_xlog_clean(), heap_xlog_visible(), XLogInitBufferForRedo(), and XLogReadBufferForRedo().

329 {
330  XLogRecPtr lsn = record->EndRecPtr;
331  RelFileNode rnode;
332  ForkNumber forknum;
333  BlockNumber blkno;
334  Page page;
335  bool zeromode;
336  bool willinit;
337 
338  if (!XLogRecGetBlockTag(record, block_id, &rnode, &forknum, &blkno))
339  {
340  /* Caller specified a bogus block_id */
341  elog(PANIC, "failed to locate backup block with ID %d", block_id);
342  }
343 
344  /*
345  * Make sure that if the block is marked with WILL_INIT, the caller is
346  * going to initialize it. And vice versa.
347  */
348  zeromode = (mode == RBM_ZERO_AND_LOCK || mode == RBM_ZERO_AND_CLEANUP_LOCK);
349  willinit = (record->blocks[block_id].flags & BKPBLOCK_WILL_INIT) != 0;
350  if (willinit && !zeromode)
351  elog(PANIC, "block with WILL_INIT flag in WAL record must be zeroed by redo routine");
352  if (!willinit && zeromode)
353  elog(PANIC, "block to be initialized in redo routine must be marked with WILL_INIT flag in the WAL record");
354 
355  /* If it has a full-page image and it should be restored, do it. */
356  if (XLogRecBlockImageApply(record, block_id))
357  {
358  Assert(XLogRecHasBlockImage(record, block_id));
359  *buf = XLogReadBufferExtended(rnode, forknum, blkno,
360  get_cleanup_lock ? RBM_ZERO_AND_CLEANUP_LOCK : RBM_ZERO_AND_LOCK);
361  page = BufferGetPage(*buf);
362  if (!RestoreBlockImage(record, block_id, page))
363  elog(ERROR, "failed to restore block image");
364 
365  /*
366  * The page may be uninitialized. If so, we can't set the LSN because
367  * that would corrupt the page.
368  */
369  if (!PageIsNew(page))
370  {
371  PageSetLSN(page, lsn);
372  }
373 
375 
376  /*
377  * At the end of crash recovery the init forks of unlogged relations
378  * are copied, without going through shared buffers. So we need to
379  * force the on-disk state of init forks to always be in sync with the
380  * state in shared buffers.
381  */
382  if (forknum == INIT_FORKNUM)
384 
385  return BLK_RESTORED;
386  }
387  else
388  {
389  *buf = XLogReadBufferExtended(rnode, forknum, blkno, mode);
390  if (BufferIsValid(*buf))
391  {
392  if (mode != RBM_ZERO_AND_LOCK && mode != RBM_ZERO_AND_CLEANUP_LOCK)
393  {
394  if (get_cleanup_lock)
396  else
398  }
399  if (lsn <= PageGetLSN(BufferGetPage(*buf)))
400  return BLK_DONE;
401  else
402  return BLK_NEEDS_REDO;
403  }
404  else
405  return BLK_NOTFOUND;
406  }
407 }
void LockBufferForCleanup(Buffer buffer)
Definition: bufmgr.c:3586
#define XLogRecHasBlockImage(decoder, block_id)
Definition: xlogreader.h:207
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1445
Buffer XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum, BlockNumber blkno, ReadBufferMode mode)
Definition: xlogutils.c:436
uint32 BlockNumber
Definition: block.h:31
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
#define PANIC
Definition: elog.h:53
XLogRecPtr EndRecPtr
Definition: xlogreader.h:115
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:65
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define BKPBLOCK_WILL_INIT
Definition: xlogrecord.h:182
ForkNumber
Definition: relpath.h:24
bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: xlogreader.c:1307
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:670
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
void FlushOneBuffer(Buffer buffer)
Definition: bufmgr.c:3272
bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
Definition: xlogreader.c:1360
#define PageGetLSN(page)
Definition: bufpage.h:363
#define PageIsNew(page)
Definition: bufpage.h:226
#define elog
Definition: elog.h:219
#define XLogRecBlockImageApply(decoder, block_id)
Definition: xlogreader.h:209
#define PageSetLSN(page, lsn)
Definition: bufpage.h:365
Pointer Page
Definition: bufpage.h:74
DecodedBkpBlock blocks[XLR_MAX_BLOCK_ID+1]
Definition: xlogreader.h:134
void XLogTruncateRelation ( RelFileNode  rnode,
ForkNumber  forkNum,
BlockNumber  nblocks 
)

Definition at line 635 of file xlogutils.c.

References forget_invalid_pages().

Referenced by smgr_redo().

637 {
638  forget_invalid_pages(rnode, forkNum, nblocks);
639 }
static void forget_invalid_pages(RelFileNode node, ForkNumber forkno, BlockNumber minblkno)
Definition: xlogutils.c:141