#include "storage/bufmgr.h"
Go to the source code of this file.
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) |
Buffer | XLogReadBuffer (RelFileNode rnode, BlockNumber blkno, bool init) |
Buffer | XLogReadBufferExtended (RelFileNode rnode, ForkNumber forknum, BlockNumber blkno, ReadBufferMode mode) |
Relation | CreateFakeRelcacheEntry (RelFileNode rnode) |
void | FreeFakeRelcacheEntry (Relation fakerel) |
Relation CreateFakeRelcacheEntry | ( | RelFileNode | rnode | ) |
Definition at line 393 of file xlogutils.c.
References Assert, LockRelId::dbId, RelFileNode::dbNode, InRecovery, LockInfoData::lockRelId, palloc0(), FakeRelCacheEntryData::pgc, RelationData::rd_backend, RelationData::rd_lockInfo, RelationData::rd_node, RelationData::rd_rel, RelationData::rd_smgr, RelationGetRelationName, LockRelId::relId, and RelFileNode::relNode.
Referenced by btree_xlog_cleanup(), ginContinueSplit(), heap_xlog_delete(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), and smgr_redo().
{ FakeRelCacheEntry fakeentry; Relation rel; Assert(InRecovery); /* Allocate the Relation struct and all related space in one block. */ fakeentry = palloc0(sizeof(FakeRelCacheEntryData)); rel = (Relation) fakeentry; rel->rd_rel = &fakeentry->pgc; rel->rd_node = rnode; /* We will never be working with temp rels during recovery */ rel->rd_backend = InvalidBackendId; /* It must be a permanent table if we're in recovery. */ rel->rd_rel->relpersistence = RELPERSISTENCE_PERMANENT; /* We don't know the name of the relation; use relfilenode instead */ sprintf(RelationGetRelationName(rel), "%u", rnode.relNode); /* * We set up the lockRelId in case anything tries to lock the dummy * relation. Note that this is fairly bogus since relNode may be * different from the relation's OID. It shouldn't really matter though, * since we are presumably running by ourselves and can't have any lock * conflicts ... */ rel->rd_lockInfo.lockRelId.dbId = rnode.dbNode; rel->rd_lockInfo.lockRelId.relId = rnode.relNode; rel->rd_smgr = NULL; return rel; }
void FreeFakeRelcacheEntry | ( | Relation | fakerel | ) |
Definition at line 434 of file xlogutils.c.
References pfree().
Referenced by btree_xlog_cleanup(), ginContinueSplit(), heap_xlog_delete(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), and smgr_redo().
{ pfree(fakerel); }
void XLogCheckInvalidPages | ( | void | ) |
Definition at line 217 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(), and WARNING.
Referenced by CheckRecoveryConsistency().
{ HASH_SEQ_STATUS status; xl_invalid_page *hentry; bool foundone = false; if (invalid_page_tab == NULL) return; /* nothing to do */ hash_seq_init(&status, invalid_page_tab); /* * Our strategy is to emit WARNING messages for all remaining entries and * only PANIC after we've dumped all the available info. */ while ((hentry = (xl_invalid_page *) hash_seq_search(&status)) != NULL) { report_invalid_page(WARNING, hentry->key.node, hentry->key.forkno, hentry->key.blkno, hentry->present); foundone = true; } if (foundone) elog(PANIC, "WAL contains references to invalid pages"); hash_destroy(invalid_page_tab); invalid_page_tab = NULL; }
void XLogDropDatabase | ( | Oid | dbid | ) |
Definition at line 457 of file xlogutils.c.
References forget_invalid_pages_db(), and smgrcloseall().
Referenced by dbase_redo().
{ /* * This is unnecessarily heavy-handed, as it will close SMgrRelation * objects for other databases as well. DROP DATABASE occurs seldom enough * that it's not worth introducing a variant of smgrclose for just this * purpose. XXX: Or should we rather leave the smgr entries dangling? */ smgrcloseall(); forget_invalid_pages_db(dbid); }
void XLogDropRelation | ( | RelFileNode | rnode, | |
ForkNumber | forknum | |||
) |
Definition at line 446 of file xlogutils.c.
References forget_invalid_pages().
Referenced by xact_redo_abort(), and xact_redo_commit_internal().
{ forget_invalid_pages(rnode, forknum, 0); }
bool XLogHaveInvalidPages | ( | void | ) |
Definition at line 207 of file xlogutils.c.
References hash_get_num_entries(), and NULL.
Referenced by RecoveryRestartPoint().
{ if (invalid_page_tab != NULL && hash_get_num_entries(invalid_page_tab) > 0) return true; return false; }
Buffer XLogReadBuffer | ( | RelFileNode | rnode, | |
BlockNumber | blkno, | |||
bool | init | |||
) |
Definition at line 264 of file xlogutils.c.
References buf, BUFFER_LOCK_EXCLUSIVE, BufferIsValid, LockBuffer(), MAIN_FORKNUM, RBM_NORMAL, RBM_ZERO, and XLogReadBufferExtended().
Referenced by _bt_restore_meta(), btree_xlog_cleanup(), btree_xlog_delete(), btree_xlog_delete_get_latestRemovedXid(), btree_xlog_delete_page(), btree_xlog_insert(), btree_xlog_newroot(), btree_xlog_split(), ginContinueSplit(), ginRedoCreateIndex(), ginRedoCreatePTree(), ginRedoDeleteListPages(), ginRedoDeletePage(), ginRedoInsert(), ginRedoInsertListPage(), ginRedoSplit(), ginRedoUpdateMetapage(), ginRedoVacuumPage(), gistRedoClearFollowRight(), gistRedoCreateIndex(), gistRedoPageSplitRecord(), gistRedoPageUpdateRecord(), heap_xlog_delete(), heap_xlog_freeze(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), seq_redo(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoCreateIndex(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoSplitTuple(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), and spgRedoVacuumRoot().
{ Buffer buf; buf = XLogReadBufferExtended(rnode, MAIN_FORKNUM, blkno, init ? RBM_ZERO : RBM_NORMAL); if (BufferIsValid(buf)) LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); return buf; }
Buffer XLogReadBufferExtended | ( | RelFileNode | rnode, | |
ForkNumber | forknum, | |||
BlockNumber | blkno, | |||
ReadBufferMode | mode | |||
) |
Definition at line 293 of file xlogutils.c.
References Assert, BufferGetBlockNumber(), BufferGetPage, InRecovery, InvalidBackendId, InvalidBuffer, log_invalid_page(), NULL, P_NEW, PageIsNew, RBM_NORMAL, ReadBufferWithoutRelcache(), ReleaseBuffer(), smgrcreate(), smgrnblocks(), and smgropen().
Referenced by btree_xlog_vacuum(), heap_xlog_clean(), heap_xlog_newpage(), heap_xlog_visible(), RestoreBackupBlockContents(), XLogReadBuffer(), and XLogRecordPageWithFreeSpace().
{ BlockNumber lastblock; Buffer buffer; SMgrRelation smgr; Assert(blkno != P_NEW); /* Open the relation at smgr level */ smgr = smgropen(rnode, InvalidBackendId); /* * Create the target file if it doesn't already exist. This lets us cope * if the replay sequence contains writes to a relation that is later * deleted. (The original coding of this routine would instead suppress * the writes, but that seems like it risks losing valuable data if the * filesystem loses an inode during a crash. Better to write the data * until we are actually told to delete the file.) */ smgrcreate(smgr, forknum, true); lastblock = smgrnblocks(smgr, forknum); if (blkno < lastblock) { /* page exists in file */ buffer = ReadBufferWithoutRelcache(rnode, forknum, blkno, mode, NULL); } else { /* hm, page doesn't exist in file */ if (mode == RBM_NORMAL) { log_invalid_page(rnode, forknum, blkno, false); return InvalidBuffer; } /* OK to extend the file */ /* we do this in recovery only - no rel-extension lock needed */ Assert(InRecovery); buffer = InvalidBuffer; while (blkno >= lastblock) { if (buffer != InvalidBuffer) ReleaseBuffer(buffer); buffer = ReadBufferWithoutRelcache(rnode, forknum, P_NEW, mode, NULL); lastblock++; } Assert(BufferGetBlockNumber(buffer) == blkno); } if (mode == RBM_NORMAL) { /* check that page has been initialized */ Page page = (Page) BufferGetPage(buffer); /* * We assume that PageIsNew is safe without a lock. During recovery, * there should be no other backends that could modify the buffer at * the same time. */ if (PageIsNew(page)) { ReleaseBuffer(buffer); log_invalid_page(rnode, forknum, blkno, true); return InvalidBuffer; } } return buffer; }
void XLogTruncateRelation | ( | RelFileNode | rnode, | |
ForkNumber | forkNum, | |||
BlockNumber | nblocks | |||
) |
Definition at line 476 of file xlogutils.c.
References forget_invalid_pages().
Referenced by smgr_redo().
{ forget_invalid_pages(rnode, forkNum, nblocks); }