Header And Logo

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

Defines | Typedefs | Functions

clog.h File Reference

#include "access/xlog.h"
Include dependency graph for clog.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define TRANSACTION_STATUS_IN_PROGRESS   0x00
#define TRANSACTION_STATUS_COMMITTED   0x01
#define TRANSACTION_STATUS_ABORTED   0x02
#define TRANSACTION_STATUS_SUB_COMMITTED   0x03
#define CLOG_ZEROPAGE   0x00
#define CLOG_TRUNCATE   0x10

Typedefs

typedef int XidStatus

Functions

void TransactionIdSetTreeStatus (TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
XidStatus TransactionIdGetStatus (TransactionId xid, XLogRecPtr *lsn)
Size CLOGShmemBuffers (void)
Size CLOGShmemSize (void)
void CLOGShmemInit (void)
void BootStrapCLOG (void)
void StartupCLOG (void)
void TrimCLOG (void)
void ShutdownCLOG (void)
void CheckPointCLOG (void)
void ExtendCLOG (TransactionId newestXact)
void TruncateCLOG (TransactionId oldestXact)
void clog_redo (XLogRecPtr lsn, XLogRecord *record)
void clog_desc (StringInfo buf, uint8 xl_info, char *rec)

Define Documentation

#define CLOG_TRUNCATE   0x10

Definition at line 48 of file clog.h.

Referenced by clog_desc(), clog_redo(), and WriteTruncateXlogRec().

#define CLOG_ZEROPAGE   0x00

Definition at line 47 of file clog.h.

Referenced by clog_desc(), clog_redo(), and WriteZeroPageXlogRec().

#define TRANSACTION_STATUS_ABORTED   0x02
#define TRANSACTION_STATUS_COMMITTED   0x01
#define TRANSACTION_STATUS_IN_PROGRESS   0x00

Definition at line 25 of file clog.h.

Referenced by TransactionIdSetStatusBit(), and TransactionLogFetch().

#define TRANSACTION_STATUS_SUB_COMMITTED   0x03

Typedef Documentation

typedef int XidStatus

Definition at line 23 of file clog.h.


Function Documentation

void BootStrapCLOG ( void   ) 

Definition at line 467 of file clog.c.

References Assert, CLogControlLock, ClogCtl, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), SimpleLruWritePage(), and ZeroCLOGPage().

Referenced by BootStrapXLOG().

{
    int         slotno;

    LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);

    /* Create and zero the first page of the commit log */
    slotno = ZeroCLOGPage(0, false);

    /* Make sure it's written out */
    SimpleLruWritePage(ClogCtl, slotno);
    Assert(!ClogCtl->shared->page_dirty[slotno]);

    LWLockRelease(CLogControlLock);
}

void CheckPointCLOG ( void   ) 

Definition at line 590 of file clog.c.

References ClogCtl, and SimpleLruFlush().

Referenced by CheckPointGuts().

{
    /* Flush dirty CLOG pages to disk */
    TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(true);
    SimpleLruFlush(ClogCtl, true);
    TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(true);
}

void clog_desc ( StringInfo  buf,
uint8  xl_info,
char *  rec 
)

Definition at line 21 of file clogdesc.c.

References appendStringInfo(), CLOG_TRUNCATE, and CLOG_ZEROPAGE.

{
    uint8       info = xl_info & ~XLR_INFO_MASK;

    if (info == CLOG_ZEROPAGE)
    {
        int         pageno;

        memcpy(&pageno, rec, sizeof(int));
        appendStringInfo(buf, "zeropage: %d", pageno);
    }
    else if (info == CLOG_TRUNCATE)
    {
        int         pageno;

        memcpy(&pageno, rec, sizeof(int));
        appendStringInfo(buf, "truncate before: %d", pageno);
    }
    else
        appendStringInfo(buf, "UNKNOWN");
}

void clog_redo ( XLogRecPtr  lsn,
XLogRecord record 
)

Definition at line 732 of file clog.c.

References Assert, CLOG_TRUNCATE, CLOG_ZEROPAGE, CLogControlLock, ClogCtl, elog, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), PANIC, SimpleLruTruncate(), SimpleLruWritePage(), XLogRecord::xl_info, XLogRecGetData, XLR_BKP_BLOCK_MASK, and ZeroCLOGPage().

{
    uint8       info = record->xl_info & ~XLR_INFO_MASK;

    /* Backup blocks are not used in clog records */
    Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));

    if (info == CLOG_ZEROPAGE)
    {
        int         pageno;
        int         slotno;

        memcpy(&pageno, XLogRecGetData(record), sizeof(int));

        LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);

        slotno = ZeroCLOGPage(pageno, false);
        SimpleLruWritePage(ClogCtl, slotno);
        Assert(!ClogCtl->shared->page_dirty[slotno]);

        LWLockRelease(CLogControlLock);
    }
    else if (info == CLOG_TRUNCATE)
    {
        int         pageno;

        memcpy(&pageno, XLogRecGetData(record), sizeof(int));

        /*
         * During XLOG replay, latest_page_number isn't set up yet; insert a
         * suitable value to bypass the sanity test in SimpleLruTruncate.
         */
        ClogCtl->shared->latest_page_number = pageno;

        SimpleLruTruncate(ClogCtl, pageno);
    }
    else
        elog(PANIC, "clog_redo: unknown op code %u", info);
}

Size CLOGShmemBuffers ( void   ) 

Definition at line 438 of file clog.c.

References Max, Min, and NBuffers.

Referenced by CLOGShmemInit(), CLOGShmemSize(), and NumLWLocks().

{
    return Min(32, Max(4, NBuffers / 512));
}

void CLOGShmemInit ( void   ) 

Definition at line 453 of file clog.c.

References CLOG_LSNS_PER_PAGE, CLogControlLock, ClogCtl, CLOGShmemBuffers(), and SimpleLruInit().

Referenced by CreateSharedMemoryAndSemaphores().

{
    ClogCtl->PagePrecedes = CLOGPagePrecedes;
    SimpleLruInit(ClogCtl, "CLOG Ctl", CLOGShmemBuffers(), CLOG_LSNS_PER_PAGE,
                  CLogControlLock, "pg_clog");
}

Size CLOGShmemSize ( void   ) 
void ExtendCLOG ( TransactionId  newestXact  ) 

Definition at line 608 of file clog.c.

References CLogControlLock, FirstNormalTransactionId, InRecovery, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), TransactionIdEquals, TransactionIdToPage, TransactionIdToPgIndex, and ZeroCLOGPage().

Referenced by GetNewTransactionId(), and RecordKnownAssignedTransactionIds().

{
    int         pageno;

    /*
     * No work except at first XID of a page.  But beware: just after
     * wraparound, the first XID of page zero is FirstNormalTransactionId.
     */
    if (TransactionIdToPgIndex(newestXact) != 0 &&
        !TransactionIdEquals(newestXact, FirstNormalTransactionId))
        return;

    pageno = TransactionIdToPage(newestXact);

    LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);

    /* Zero the page and make an XLOG entry about it */
    ZeroCLOGPage(pageno, !InRecovery);

    LWLockRelease(CLogControlLock);
}

void ShutdownCLOG ( void   ) 

Definition at line 578 of file clog.c.

References ClogCtl, and SimpleLruFlush().

Referenced by ShutdownXLOG().

{
    /* Flush dirty CLOG pages to disk */
    TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(false);
    SimpleLruFlush(ClogCtl, false);
    TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(false);
}

void StartupCLOG ( void   ) 

Definition at line 510 of file clog.c.

References CLogControlLock, ClogCtl, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), VariableCacheData::nextXid, ShmemVariableCache, and TransactionIdToPage.

Referenced by StartupXLOG().

{
    TransactionId xid = ShmemVariableCache->nextXid;
    int         pageno = TransactionIdToPage(xid);

    LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);

    /*
     * Initialize our idea of the latest page number.
     */
    ClogCtl->shared->latest_page_number = pageno;

    LWLockRelease(CLogControlLock);
}

XidStatus TransactionIdGetStatus ( TransactionId  xid,
XLogRecPtr lsn 
)

Definition at line 389 of file clog.c.

References CLOG_XACT_BITMASK, CLogControlLock, ClogCtl, GetLSNIndex, LWLockRelease(), SimpleLruReadPage_ReadOnly(), TransactionIdToBIndex, TransactionIdToByte, and TransactionIdToPage.

Referenced by TransactionIdGetCommitLSN(), and TransactionLogFetch().

{
    int         pageno = TransactionIdToPage(xid);
    int         byteno = TransactionIdToByte(xid);
    int         bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
    int         slotno;
    int         lsnindex;
    char       *byteptr;
    XidStatus   status;

    /* lock is acquired by SimpleLruReadPage_ReadOnly */

    slotno = SimpleLruReadPage_ReadOnly(ClogCtl, pageno, xid);
    byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;

    status = (*byteptr >> bshift) & CLOG_XACT_BITMASK;

    lsnindex = GetLSNIndex(slotno, xid);
    *lsn = ClogCtl->shared->group_lsn[lsnindex];

    LWLockRelease(CLogControlLock);

    return status;
}

void TransactionIdSetTreeStatus ( TransactionId  xid,
int  nsubxids,
TransactionId subxids,
XidStatus  status,
XLogRecPtr  lsn 
)

Definition at line 145 of file clog.c.

References Assert, i, set_status_by_pages(), TRANSACTION_STATUS_ABORTED, TRANSACTION_STATUS_COMMITTED, TRANSACTION_STATUS_SUB_COMMITTED, TransactionIdSetPageStatus(), and TransactionIdToPage.

Referenced by TransactionIdAbortTree(), TransactionIdAsyncCommitTree(), and TransactionIdCommitTree().

{
    int         pageno = TransactionIdToPage(xid);      /* get page of parent */
    int         i;

    Assert(status == TRANSACTION_STATUS_COMMITTED ||
           status == TRANSACTION_STATUS_ABORTED);

    /*
     * See how many subxids, if any, are on the same page as the parent, if
     * any.
     */
    for (i = 0; i < nsubxids; i++)
    {
        if (TransactionIdToPage(subxids[i]) != pageno)
            break;
    }

    /*
     * Do all items fit on a single page?
     */
    if (i == nsubxids)
    {
        /*
         * Set the parent and all subtransactions in a single call
         */
        TransactionIdSetPageStatus(xid, nsubxids, subxids, status, lsn,
                                   pageno);
    }
    else
    {
        int         nsubxids_on_first_page = i;

        /*
         * If this is a commit then we care about doing this correctly (i.e.
         * using the subcommitted intermediate status).  By here, we know
         * we're updating more than one page of clog, so we must mark entries
         * that are *not* on the first page so that they show as subcommitted
         * before we then return to update the status to fully committed.
         *
         * To avoid touching the first page twice, skip marking subcommitted
         * for the subxids on that first page.
         */
        if (status == TRANSACTION_STATUS_COMMITTED)
            set_status_by_pages(nsubxids - nsubxids_on_first_page,
                                subxids + nsubxids_on_first_page,
                                TRANSACTION_STATUS_SUB_COMMITTED, lsn);

        /*
         * Now set the parent and subtransactions on same page as the parent,
         * if any
         */
        pageno = TransactionIdToPage(xid);
        TransactionIdSetPageStatus(xid, nsubxids_on_first_page, subxids, status,
                                   lsn, pageno);

        /*
         * Now work through the rest of the subxids one clog page at a time,
         * starting from the second page onwards, like we did above.
         */
        set_status_by_pages(nsubxids - nsubxids_on_first_page,
                            subxids + nsubxids_on_first_page,
                            status, lsn);
    }
}

void TrimCLOG ( void   ) 

Definition at line 529 of file clog.c.

References CLogControlLock, ClogCtl, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MemSet, VariableCacheData::nextXid, ShmemVariableCache, SimpleLruReadPage(), TransactionIdToBIndex, TransactionIdToByte, TransactionIdToPage, and TransactionIdToPgIndex.

Referenced by StartupXLOG().

{
    TransactionId xid = ShmemVariableCache->nextXid;
    int         pageno = TransactionIdToPage(xid);

    LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);

    /*
     * Re-Initialize our idea of the latest page number.
     */
    ClogCtl->shared->latest_page_number = pageno;

    /*
     * Zero out the remainder of the current clog page.  Under normal
     * circumstances it should be zeroes already, but it seems at least
     * theoretically possible that XLOG replay will have settled on a nextXID
     * value that is less than the last XID actually used and marked by the
     * previous database lifecycle (since subtransaction commit writes clog
     * but makes no WAL entry).  Let's just be safe. (We need not worry about
     * pages beyond the current one, since those will be zeroed when first
     * used.  For the same reason, there is no need to do anything when
     * nextXid is exactly at a page boundary; and it's likely that the
     * "current" page doesn't exist yet in that case.)
     */
    if (TransactionIdToPgIndex(xid) != 0)
    {
        int         byteno = TransactionIdToByte(xid);
        int         bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
        int         slotno;
        char       *byteptr;

        slotno = SimpleLruReadPage(ClogCtl, pageno, false, xid);
        byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;

        /* Zero so-far-unused positions in the current byte */
        *byteptr &= (1 << bshift) - 1;
        /* Zero the rest of the page */
        MemSet(byteptr + 1, 0, BLCKSZ - byteno - 1);

        ClogCtl->shared->page_dirty[slotno] = true;
    }

    LWLockRelease(CLogControlLock);
}

void TruncateCLOG ( TransactionId  oldestXact  ) 

Definition at line 647 of file clog.c.

References ClogCtl, SimpleLruTruncate(), SlruScanDirCbReportPresence(), SlruScanDirectory(), TransactionIdToPage, and WriteTruncateXlogRec().

Referenced by vac_truncate_clog().

{
    int         cutoffPage;

    /*
     * The cutoff point is the start of the segment containing oldestXact. We
     * pass the *page* containing oldestXact to SimpleLruTruncate.
     */
    cutoffPage = TransactionIdToPage(oldestXact);

    /* Check to see if there's any files that could be removed */
    if (!SlruScanDirectory(ClogCtl, SlruScanDirCbReportPresence, &cutoffPage))
        return;                 /* nothing to remove */

    /* Write XLOG record and flush XLOG to disk */
    WriteTruncateXlogRec(cutoffPage);

    /* Now we can remove the old CLOG segment(s) */
    SimpleLruTruncate(ClogCtl, cutoffPage);
}