#include "access/xlog.h"
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 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 |
Definition at line 27 of file clog.h.
Referenced by TransactionIdAbortTree(), TransactionIdDidAbort(), TransactionIdSetPageStatus(), and TransactionIdSetTreeStatus().
#define TRANSACTION_STATUS_COMMITTED 0x01 |
Definition at line 26 of file clog.h.
Referenced by TransactionIdAsyncCommitTree(), TransactionIdCommitTree(), TransactionIdDidCommit(), TransactionIdSetPageStatus(), TransactionIdSetStatusBit(), and TransactionIdSetTreeStatus().
#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 |
Definition at line 28 of file clog.h.
Referenced by TransactionIdDidAbort(), TransactionIdDidCommit(), TransactionIdSetPageStatus(), TransactionIdSetStatusBit(), TransactionIdSetTreeStatus(), and TransactionLogFetch().
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().
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 | ) |
Definition at line 447 of file clog.c.
References CLOG_LSNS_PER_PAGE, CLOGShmemBuffers(), and SimpleLruShmemSize().
Referenced by CreateSharedMemoryAndSemaphores().
{ return SimpleLruShmemSize(CLOGShmemBuffers(), CLOG_LSNS_PER_PAGE); }
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); }