Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

xlogutils.h File Reference

#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.

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)

Function Documentation

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