Commit 4dbb880d authored by Tom Lane's avatar Tom Lane

Rearrange pg_subtrans handling as per recent discussion. pg_subtrans

updates are no longer WAL-logged nor even fsync'd; we do not need to,
since after a crash no old pg_subtrans data is needed again.  We truncate
pg_subtrans to RecentGlobalXmin at each checkpoint.  slru.c's API is
refactored a little bit to separate out the necessary decisions.
parent 059912ce
...@@ -10,29 +10,34 @@ ...@@ -10,29 +10,34 @@
* looked up again. Now we use specialized access code so that the commit * looked up again. Now we use specialized access code so that the commit
* log can be broken into relatively small, independent segments. * log can be broken into relatively small, independent segments.
* *
* XLOG interactions: this module generates an XLOG record whenever a new
* CLOG page is initialized to zeroes. Other writes of CLOG come from
* recording of transaction commit or abort in xact.c, which generates its
* own XLOG records for these events and will re-perform the status update
* on redo; so we need make no additional XLOG entry here. Also, the XLOG
* is guaranteed flushed through the XLOG commit record before we are called
* to log a commit, so the WAL rule "write xlog before data" is satisfied
* automatically for commits, and we don't really care for aborts. Therefore,
* we don't need to mark CLOG pages with LSN information; we have enough
* synchronization already.
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.22 2004/07/03 02:55:56 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.23 2004/08/23 23:22:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include "access/clog.h" #include "access/clog.h"
#include "access/slru.h" #include "access/slru.h"
#include "miscadmin.h" #include "postmaster/bgwriter.h"
#include "storage/lwlock.h"
/* /*
* Defines for CLOG page and segment sizes. A page is the same BLCKSZ * Defines for CLOG page sizes. A page is the same BLCKSZ as is used
* as is used everywhere else in Postgres. * everywhere else in Postgres.
* *
* Note: because TransactionIds are 32 bits and wrap around at 0xFFFFFFFF, * Note: because TransactionIds are 32 bits and wrap around at 0xFFFFFFFF,
* CLOG page numbering also wraps around at 0xFFFFFFFF/CLOG_XACTS_PER_PAGE, * CLOG page numbering also wraps around at 0xFFFFFFFF/CLOG_XACTS_PER_PAGE,
...@@ -53,25 +58,11 @@ ...@@ -53,25 +58,11 @@
#define TransactionIdToBIndex(xid) ((xid) % (TransactionId) CLOG_XACTS_PER_BYTE) #define TransactionIdToBIndex(xid) ((xid) % (TransactionId) CLOG_XACTS_PER_BYTE)
/*---------- /*
* Shared-memory data structures for CLOG control * Link to shared-memory data structures for CLOG control
*
* XLOG interactions: this module generates an XLOG record whenever a new
* CLOG page is initialized to zeroes. Other writes of CLOG come from
* recording of transaction commit or abort in xact.c, which generates its
* own XLOG records for these events and will re-perform the status update
* on redo; so we need make no additional XLOG entry here. Also, the XLOG
* is guaranteed flushed through the XLOG commit record before we are called
* to log a commit, so the WAL rule "write xlog before data" is satisfied
* automatically for commits, and we don't really care for aborts. Therefore,
* we don't need to mark CLOG pages with LSN information; we have enough
* synchronization already.
*----------
*/ */
static SlruCtlData ClogCtlData; static SlruCtlData ClogCtlData;
static SlruCtl ClogCtl = &ClogCtlData; #define ClogCtl (&ClogCtlData)
static int ZeroCLOGPage(int pageno, bool writeXlog); static int ZeroCLOGPage(int pageno, bool writeXlog);
...@@ -91,6 +82,7 @@ TransactionIdSetStatus(TransactionId xid, XidStatus status) ...@@ -91,6 +82,7 @@ TransactionIdSetStatus(TransactionId xid, XidStatus status)
int pageno = TransactionIdToPage(xid); int pageno = TransactionIdToPage(xid);
int byteno = TransactionIdToByte(xid); int byteno = TransactionIdToByte(xid);
int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT; int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
int slotno;
char *byteptr; char *byteptr;
char byteval; char byteval;
...@@ -98,10 +90,10 @@ TransactionIdSetStatus(TransactionId xid, XidStatus status) ...@@ -98,10 +90,10 @@ TransactionIdSetStatus(TransactionId xid, XidStatus status)
status == TRANSACTION_STATUS_ABORTED || status == TRANSACTION_STATUS_ABORTED ||
status == TRANSACTION_STATUS_SUB_COMMITTED); status == TRANSACTION_STATUS_SUB_COMMITTED);
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE); LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
byteptr = SimpleLruReadPage(ClogCtl, pageno, xid, true); slotno = SimpleLruReadPage(ClogCtl, pageno, xid);
byteptr += byteno; byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;
/* Current state should be 0, subcommitted or target state */ /* Current state should be 0, subcommitted or target state */
Assert(((*byteptr >> bshift) & CLOG_XACT_BITMASK) == 0 || Assert(((*byteptr >> bshift) & CLOG_XACT_BITMASK) == 0 ||
...@@ -114,9 +106,9 @@ TransactionIdSetStatus(TransactionId xid, XidStatus status) ...@@ -114,9 +106,9 @@ TransactionIdSetStatus(TransactionId xid, XidStatus status)
byteval |= (status << bshift); byteval |= (status << bshift);
*byteptr = byteval; *byteptr = byteval;
/* ...->page_status[slotno] = SLRU_PAGE_DIRTY; already done */ ClogCtl->shared->page_status[slotno] = SLRU_PAGE_DIRTY;
LWLockRelease(ClogCtl->ControlLock); LWLockRelease(CLogControlLock);
} }
/* /*
...@@ -131,17 +123,18 @@ TransactionIdGetStatus(TransactionId xid) ...@@ -131,17 +123,18 @@ TransactionIdGetStatus(TransactionId xid)
int pageno = TransactionIdToPage(xid); int pageno = TransactionIdToPage(xid);
int byteno = TransactionIdToByte(xid); int byteno = TransactionIdToByte(xid);
int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT; int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
int slotno;
char *byteptr; char *byteptr;
XidStatus status; XidStatus status;
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE); LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
byteptr = SimpleLruReadPage(ClogCtl, pageno, xid, false); slotno = SimpleLruReadPage(ClogCtl, pageno, xid);
byteptr += byteno; byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;
status = (*byteptr >> bshift) & CLOG_XACT_BITMASK; status = (*byteptr >> bshift) & CLOG_XACT_BITMASK;
LWLockRelease(ClogCtl->ControlLock); LWLockRelease(CLogControlLock);
return status; return status;
} }
...@@ -160,8 +153,8 @@ CLOGShmemSize(void) ...@@ -160,8 +153,8 @@ CLOGShmemSize(void)
void void
CLOGShmemInit(void) CLOGShmemInit(void)
{ {
SimpleLruInit(ClogCtl, "CLOG Ctl", "pg_clog");
ClogCtl->PagePrecedes = CLOGPagePrecedes; ClogCtl->PagePrecedes = CLOGPagePrecedes;
SimpleLruInit(ClogCtl, "CLOG Ctl", CLogControlLock, "pg_clog");
} }
/* /*
...@@ -175,16 +168,16 @@ BootStrapCLOG(void) ...@@ -175,16 +168,16 @@ BootStrapCLOG(void)
{ {
int slotno; int slotno;
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE); LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
/* Create and zero the first page of the commit log */ /* Create and zero the first page of the commit log */
slotno = ZeroCLOGPage(0, false); slotno = ZeroCLOGPage(0, false);
/* Make sure it's written out */ /* Make sure it's written out */
SimpleLruWritePage(ClogCtl, slotno, NULL); SimpleLruWritePage(ClogCtl, slotno, NULL);
/* Assert(ClogCtl->page_status[slotno] == SLRU_PAGE_CLEAN); */ Assert(ClogCtl->shared->page_status[slotno] == SLRU_PAGE_CLEAN);
LWLockRelease(ClogCtl->ControlLock); LWLockRelease(CLogControlLock);
} }
/* /*
...@@ -199,7 +192,9 @@ BootStrapCLOG(void) ...@@ -199,7 +192,9 @@ BootStrapCLOG(void)
static int static int
ZeroCLOGPage(int pageno, bool writeXlog) ZeroCLOGPage(int pageno, bool writeXlog)
{ {
int slotno = SimpleLruZeroPage(ClogCtl, pageno); int slotno;
slotno = SimpleLruZeroPage(ClogCtl, pageno);
if (writeXlog) if (writeXlog)
WriteZeroPageXlogRec(pageno); WriteZeroPageXlogRec(pageno);
...@@ -217,8 +212,7 @@ StartupCLOG(void) ...@@ -217,8 +212,7 @@ StartupCLOG(void)
/* /*
* Initialize our idea of the latest page number. * Initialize our idea of the latest page number.
*/ */
SimpleLruSetLatestPage(ClogCtl, ClogCtl->shared->latest_page_number = TransactionIdToPage(ShmemVariableCache->nextXid);
TransactionIdToPage(ShmemVariableCache->nextXid));
} }
/* /*
...@@ -227,6 +221,7 @@ StartupCLOG(void) ...@@ -227,6 +221,7 @@ StartupCLOG(void)
void void
ShutdownCLOG(void) ShutdownCLOG(void)
{ {
/* Flush dirty CLOG pages to disk */
SimpleLruFlush(ClogCtl, false); SimpleLruFlush(ClogCtl, false);
} }
...@@ -236,6 +231,7 @@ ShutdownCLOG(void) ...@@ -236,6 +231,7 @@ ShutdownCLOG(void)
void void
CheckPointCLOG(void) CheckPointCLOG(void)
{ {
/* Flush dirty CLOG pages to disk */
SimpleLruFlush(ClogCtl, true); SimpleLruFlush(ClogCtl, true);
} }
...@@ -263,12 +259,12 @@ ExtendCLOG(TransactionId newestXact) ...@@ -263,12 +259,12 @@ ExtendCLOG(TransactionId newestXact)
pageno = TransactionIdToPage(newestXact); pageno = TransactionIdToPage(newestXact);
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE); LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
/* Zero the page and make an XLOG entry about it */ /* Zero the page and make an XLOG entry about it */
ZeroCLOGPage(pageno, true); ZeroCLOGPage(pageno, true);
LWLockRelease(ClogCtl->ControlLock); LWLockRelease(CLogControlLock);
} }
...@@ -296,6 +292,15 @@ TruncateCLOG(TransactionId oldestXact) ...@@ -296,6 +292,15 @@ TruncateCLOG(TransactionId oldestXact)
* We pass the *page* containing oldestXact to SimpleLruTruncate. * We pass the *page* containing oldestXact to SimpleLruTruncate.
*/ */
cutoffPage = TransactionIdToPage(oldestXact); cutoffPage = TransactionIdToPage(oldestXact);
/* Check to see if there's any files that could be removed */
if (!SlruScanDirectory(ClogCtl, cutoffPage, false))
return; /* nothing to remove */
/* Perform a CHECKPOINT */
RequestCheckpoint(true);
/* Now we can remove the old CLOG segment(s) */
SimpleLruTruncate(ClogCtl, cutoffPage); SimpleLruTruncate(ClogCtl, cutoffPage);
} }
...@@ -340,20 +345,51 @@ WriteZeroPageXlogRec(int pageno) ...@@ -340,20 +345,51 @@ WriteZeroPageXlogRec(int pageno)
rdata.data = (char *) (&pageno); rdata.data = (char *) (&pageno);
rdata.len = sizeof(int); rdata.len = sizeof(int);
rdata.next = NULL; rdata.next = NULL;
(void) XLogInsert(RM_SLRU_ID, CLOG_ZEROPAGE | XLOG_NO_TRAN, &rdata); (void) XLogInsert(RM_CLOG_ID, CLOG_ZEROPAGE | XLOG_NO_TRAN, &rdata);
} }
/* Redo a ZEROPAGE action during WAL replay */ /*
* CLOG resource manager's routines
*/
void void
clog_zeropage_redo(int pageno) clog_redo(XLogRecPtr lsn, XLogRecord *record)
{ {
int slotno; uint8 info = record->xl_info & ~XLR_INFO_MASK;
LWLockAcquire(ClogCtl->ControlLock, LW_EXCLUSIVE); if (info == CLOG_ZEROPAGE)
{
int pageno;
int slotno;
slotno = ZeroCLOGPage(pageno, false); memcpy(&pageno, XLogRecGetData(record), sizeof(int));
SimpleLruWritePage(ClogCtl, slotno, NULL);
/* Assert(ClogCtl->page_status[slotno] == SLRU_PAGE_CLEAN); */ LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
slotno = ZeroCLOGPage(pageno, false);
SimpleLruWritePage(ClogCtl, slotno, NULL);
Assert(ClogCtl->shared->page_status[slotno] == SLRU_PAGE_CLEAN);
LWLockRelease(CLogControlLock);
}
}
void
clog_undo(XLogRecPtr lsn, XLogRecord *record)
{
}
void
clog_desc(char *buf, uint8 xl_info, char *rec)
{
uint8 info = xl_info & ~XLR_INFO_MASK;
if (info == CLOG_ZEROPAGE)
{
int pageno;
LWLockRelease(ClogCtl->ControlLock); memcpy(&pageno, rec, sizeof(int));
sprintf(buf + strlen(buf), "zeropage: %d", pageno);
}
else
strcat(buf, "UNKNOWN");
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Resource managers definition * Resource managers definition
* *
* $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.14 2004/07/21 22:31:20 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.15 2004/08/23 23:22:44 tgl Exp $
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "access/nbtree.h" #include "access/nbtree.h"
#include "access/rtree.h" #include "access/rtree.h"
#include "access/slru.h" #include "access/clog.h"
#include "access/xact.h" #include "access/xact.h"
#include "access/xlog_internal.h" #include "access/xlog_internal.h"
#include "storage/smgr.h" #include "storage/smgr.h"
...@@ -23,7 +23,7 @@ const RmgrData RmgrTable[RM_MAX_ID + 1] = { ...@@ -23,7 +23,7 @@ const RmgrData RmgrTable[RM_MAX_ID + 1] = {
{"XLOG", xlog_redo, xlog_undo, xlog_desc, NULL, NULL}, {"XLOG", xlog_redo, xlog_undo, xlog_desc, NULL, NULL},
{"Transaction", xact_redo, xact_undo, xact_desc, NULL, NULL}, {"Transaction", xact_redo, xact_undo, xact_desc, NULL, NULL},
{"Storage", smgr_redo, smgr_undo, smgr_desc, NULL, NULL}, {"Storage", smgr_redo, smgr_undo, smgr_desc, NULL, NULL},
{"SLRU", slru_redo, slru_undo, slru_desc, NULL, NULL}, {"CLOG", clog_redo, clog_undo, clog_desc, NULL, NULL},
{"Reserved 4", NULL, NULL, NULL, NULL, NULL}, {"Reserved 4", NULL, NULL, NULL, NULL, NULL},
{"Reserved 5", NULL, NULL, NULL, NULL, NULL}, {"Reserved 5", NULL, NULL, NULL, NULL, NULL},
{"Reserved 6", NULL, NULL, NULL, NULL, NULL}, {"Reserved 6", NULL, NULL, NULL, NULL, NULL},
......
This diff is collapsed.
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.162 2004/08/12 19:03:23 momjian Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.163 2004/08/23 23:22:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -4918,6 +4918,14 @@ CreateCheckPoint(bool shutdown, bool force) ...@@ -4918,6 +4918,14 @@ CreateCheckPoint(bool shutdown, bool force)
if (!shutdown) if (!shutdown)
PreallocXlogFiles(recptr); PreallocXlogFiles(recptr);
/*
* Truncate pg_subtrans if possible. We can throw away all data before
* the oldest XMIN of any running transaction. No future transaction will
* attempt to reference any pg_subtrans entry older than that (see Asserts
* in subtrans.c).
*/
TruncateSUBTRANS(GetOldestXmin(true));
LWLockRelease(CheckpointLock); LWLockRelease(CheckpointLock);
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.286 2004/08/06 04:15:07 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.287 2004/08/23 23:22:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -810,9 +810,8 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID) ...@@ -810,9 +810,8 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
return; return;
} }
/* Truncate CLOG and SUBTRANS to the oldest vacuumxid */ /* Truncate CLOG to the oldest vacuumxid */
TruncateCLOG(vacuumXID); TruncateCLOG(vacuumXID);
TruncateSUBTRANS(vacuumXID);
/* Give warning about impending wraparound problems */ /* Give warning about impending wraparound problems */
if (frozenAlreadyWrapped) if (frozenAlreadyWrapped)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.69 2004/08/22 02:41:57 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.70 2004/08/23 23:22:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -661,6 +661,9 @@ result_known: ...@@ -661,6 +661,9 @@ result_known:
* FALSE is sufficient for non-shared relations, since only backends in my * FALSE is sufficient for non-shared relations, since only backends in my
* own database could ever see the tuples in them. * own database could ever see the tuples in them.
* *
* This is also used to determine where to truncate pg_subtrans. allDbs
* must be TRUE for that case.
*
* Note: we include the currently running xids in the set of considered xids. * Note: we include the currently running xids in the set of considered xids.
* This ensures that if a just-started xact has not yet set its snapshot, * This ensures that if a just-started xact has not yet set its snapshot,
* when it does set the snapshot it cannot set xmin less than what we compute. * when it does set the snapshot it cannot set xmin less than what we compute.
...@@ -673,7 +676,17 @@ GetOldestXmin(bool allDbs) ...@@ -673,7 +676,17 @@ GetOldestXmin(bool allDbs)
TransactionId result; TransactionId result;
int index; int index;
result = GetTopTransactionId(); /*
* Normally we start the min() calculation with our own XID. But
* if called by checkpointer, we will not be inside a transaction,
* so use next XID as starting point for min() calculation. (Note
* that if there are no xacts running at all, that will be the subtrans
* truncation point!)
*/
if (IsTransactionState())
result = GetTopTransactionId();
else
result = ReadNewTransactionId();
LWLockAcquire(SInvalLock, LW_SHARED); LWLockAcquire(SInvalLock, LW_SHARED);
......
...@@ -15,14 +15,13 @@ ...@@ -15,14 +15,13 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lwlock.c,v 1.21 2004/07/01 00:50:59 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/lmgr/lwlock.c,v 1.22 2004/08/23 23:22:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "access/clog.h" #include "access/slru.h"
#include "access/subtrans.h"
#include "storage/lwlock.h" #include "storage/lwlock.h"
#include "storage/proc.h" #include "storage/proc.h"
#include "storage/spin.h" #include "storage/spin.h"
...@@ -109,11 +108,11 @@ NumLWLocks(void) ...@@ -109,11 +108,11 @@ NumLWLocks(void)
/* bufmgr.c needs two for each shared buffer */ /* bufmgr.c needs two for each shared buffer */
numLocks += 2 * NBuffers; numLocks += 2 * NBuffers;
/* clog.c needs one per CLOG buffer + one control lock */ /* clog.c needs one per CLOG buffer */
numLocks += NUM_CLOG_BUFFERS + 1; numLocks += NUM_SLRU_BUFFERS;
/* subtrans.c needs one per SubTrans buffer + one control lock */ /* subtrans.c needs one per SubTrans buffer */
numLocks += NUM_SUBTRANS_BUFFERS + 1; numLocks += NUM_SLRU_BUFFERS;
/* Perhaps create a few more for use by user-defined modules? */ /* Perhaps create a few more for use by user-defined modules? */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/clog.h,v 1.9 2004/07/01 00:51:38 tgl Exp $ * $PostgreSQL: pgsql/src/include/access/clog.h,v 1.10 2004/08/23 23:22:45 tgl Exp $
*/ */
#ifndef CLOG_H #ifndef CLOG_H
#define CLOG_H #define CLOG_H
...@@ -27,9 +27,6 @@ typedef int XidStatus; ...@@ -27,9 +27,6 @@ typedef int XidStatus;
#define TRANSACTION_STATUS_ABORTED 0x02 #define TRANSACTION_STATUS_ABORTED 0x02
#define TRANSACTION_STATUS_SUB_COMMITTED 0x03 #define TRANSACTION_STATUS_SUB_COMMITTED 0x03
/* exported because lwlock.c needs it */
#define NUM_CLOG_BUFFERS 8
extern void TransactionIdSetStatus(TransactionId xid, XidStatus status); extern void TransactionIdSetStatus(TransactionId xid, XidStatus status);
extern XidStatus TransactionIdGetStatus(TransactionId xid); extern XidStatus TransactionIdGetStatus(TransactionId xid);
...@@ -42,6 +39,12 @@ extern void ShutdownCLOG(void); ...@@ -42,6 +39,12 @@ extern void ShutdownCLOG(void);
extern void CheckPointCLOG(void); extern void CheckPointCLOG(void);
extern void ExtendCLOG(TransactionId newestXact); extern void ExtendCLOG(TransactionId newestXact);
extern void TruncateCLOG(TransactionId oldestXact); extern void TruncateCLOG(TransactionId oldestXact);
extern void clog_zeropage_redo(int pageno);
/* XLOG stuff */
#define CLOG_ZEROPAGE 0x00
extern void clog_redo(XLogRecPtr lsn, XLogRecord *record);
extern void clog_undo(XLogRecPtr lsn, XLogRecord *record);
extern void clog_desc(char *buf, uint8 xl_info, char *rec);
#endif /* CLOG_H */ #endif /* CLOG_H */
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Resource managers definition * Resource managers definition
* *
* $PostgreSQL: pgsql/src/include/access/rmgr.h,v 1.11 2004/07/01 00:51:38 tgl Exp $ * $PostgreSQL: pgsql/src/include/access/rmgr.h,v 1.12 2004/08/23 23:22:45 tgl Exp $
*/ */
#ifndef RMGR_H #ifndef RMGR_H
#define RMGR_H #define RMGR_H
...@@ -16,7 +16,7 @@ typedef uint8 RmgrId; ...@@ -16,7 +16,7 @@ typedef uint8 RmgrId;
#define RM_XLOG_ID 0 #define RM_XLOG_ID 0
#define RM_XACT_ID 1 #define RM_XACT_ID 1
#define RM_SMGR_ID 2 #define RM_SMGR_ID 2
#define RM_SLRU_ID 3 #define RM_CLOG_ID 3
#define RM_HEAP_ID 10 #define RM_HEAP_ID 10
#define RM_BTREE_ID 11 #define RM_BTREE_ID 11
#define RM_HASH_ID 12 #define RM_HASH_ID 12
......
/* /*-------------------------------------------------------------------------
* slru.h
* *
* Simple LRU * slru.h
* Simple LRU buffering for transaction status logfiles
* *
* Portions Copyright (c) 2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/slru.h,v 1.7 2004/07/01 00:51:38 tgl Exp $ * $PostgreSQL: pgsql/src/include/access/slru.h,v 1.8 2004/08/23 23:22:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/ */
#ifndef SLRU_H #ifndef SLRU_H
#define SLRU_H #define SLRU_H
#include "access/xlog.h"
#include "storage/lwlock.h" #include "storage/lwlock.h"
/* Opaque structs known only in slru.c */ /*
typedef struct SlruSharedData *SlruShared; * Number of page buffers. Ideally this could be different for CLOG and
typedef struct SlruFlushData *SlruFlush; * SUBTRANS, but the benefit doesn't seem to be worth any additional
* notational cruft.
*/
#define NUM_SLRU_BUFFERS 8
/* Page status codes */
typedef enum
{
SLRU_PAGE_EMPTY, /* buffer is not in use */
SLRU_PAGE_READ_IN_PROGRESS, /* page is being read in */
SLRU_PAGE_CLEAN, /* page is valid and not dirty */
SLRU_PAGE_DIRTY, /* page is valid but needs write */
SLRU_PAGE_WRITE_IN_PROGRESS /* page is being written out */
} SlruPageStatus;
/*
* Shared-memory state
*/
typedef struct SlruSharedData
{
LWLockId ControlLock;
/*
* Info for each buffer slot. Page number is undefined when status is
* EMPTY. lru_count is essentially the number of page switches since
* last use of this page; the page with highest lru_count is the best
* candidate to replace.
*/
char *page_buffer[NUM_SLRU_BUFFERS];
SlruPageStatus page_status[NUM_SLRU_BUFFERS];
int page_number[NUM_SLRU_BUFFERS];
unsigned int page_lru_count[NUM_SLRU_BUFFERS];
LWLockId buffer_locks[NUM_SLRU_BUFFERS];
/*
* latest_page_number is the page number of the current end of the
* log; this is not critical data, since we use it only to avoid
* swapping out the latest page.
*/
int latest_page_number;
} SlruSharedData;
typedef SlruSharedData *SlruShared;
/* /*
* SlruCtlData is an unshared structure that points to the active information * SlruCtlData is an unshared structure that points to the active information
...@@ -27,13 +70,11 @@ typedef struct SlruCtlData ...@@ -27,13 +70,11 @@ typedef struct SlruCtlData
{ {
SlruShared shared; SlruShared shared;
LWLockId ControlLock;
/* /*
* Dir is set during SimpleLruInit and does not change thereafter. * This flag tells whether to fsync writes (true for pg_clog,
* Since it's always the same, it doesn't need to be in shared memory. * false for pg_subtrans).
*/ */
char Dir[MAXPGPATH]; bool do_fsync;
/* /*
* Decide which of two page numbers is "older" for truncation purposes. * Decide which of two page numbers is "older" for truncation purposes.
...@@ -42,27 +83,27 @@ typedef struct SlruCtlData ...@@ -42,27 +83,27 @@ typedef struct SlruCtlData
*/ */
bool (*PagePrecedes) (int, int); bool (*PagePrecedes) (int, int);
/*
* Dir is set during SimpleLruInit and does not change thereafter.
* Since it's always the same, it doesn't need to be in shared memory.
*/
char Dir[MAXPGPATH];
} SlruCtlData; } SlruCtlData;
typedef SlruCtlData *SlruCtl; typedef SlruCtlData *SlruCtl;
/* Opaque struct known only in slru.c */
typedef struct SlruFlushData *SlruFlush;
extern int SimpleLruShmemSize(void); extern int SimpleLruShmemSize(void);
extern void SimpleLruInit(SlruCtl ctl, const char *name, const char *subdir); extern void SimpleLruInit(SlruCtl ctl, const char *name,
LWLockId ctllock, const char *subdir);
extern int SimpleLruZeroPage(SlruCtl ctl, int pageno); extern int SimpleLruZeroPage(SlruCtl ctl, int pageno);
extern char *SimpleLruReadPage(SlruCtl ctl, int pageno, extern int SimpleLruReadPage(SlruCtl ctl, int pageno, TransactionId xid);
TransactionId xid, bool forwrite);
extern void SimpleLruWritePage(SlruCtl ctl, int slotno, SlruFlush fdata); extern void SimpleLruWritePage(SlruCtl ctl, int slotno, SlruFlush fdata);
extern void SimpleLruSetLatestPage(SlruCtl ctl, int pageno);
extern void SimpleLruFlush(SlruCtl ctl, bool checkpoint); extern void SimpleLruFlush(SlruCtl ctl, bool checkpoint);
extern void SimpleLruTruncate(SlruCtl ctl, int cutoffPage); extern void SimpleLruTruncate(SlruCtl ctl, int cutoffPage);
extern bool SlruScanDirectory(SlruCtl ctl, int cutoffPage, bool doDeletions);
/* XLOG stuff */
#define CLOG_ZEROPAGE 0x00
#define SUBTRANS_ZEROPAGE 0x10
extern void slru_redo(XLogRecPtr lsn, XLogRecord *record);
extern void slru_undo(XLogRecPtr lsn, XLogRecord *record);
extern void slru_desc(char *buf, uint8 xl_info, char *rec);
#endif /* SLRU_H */ #endif /* SLRU_H */
/* /*
* subtrans.h * subtrans.h
* *
* PostgreSQL subtrans-log manager * PostgreSQL subtransaction-log manager
* *
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/subtrans.h,v 1.2 2004/08/22 02:41:58 tgl Exp $ * $PostgreSQL: pgsql/src/include/access/subtrans.h,v 1.3 2004/08/23 23:22:45 tgl Exp $
*/ */
#ifndef SUBTRANS_H #ifndef SUBTRANS_H
#define SUBTRANS_H #define SUBTRANS_H
#include "access/xlog.h"
/* exported because lwlock.c needs it */
/* cannot be different from NUM_CLOG_BUFFERS without slru.c changes */
#define NUM_SUBTRANS_BUFFERS NUM_CLOG_BUFFERS
extern void SubTransSetParent(TransactionId xid, TransactionId parent); extern void SubTransSetParent(TransactionId xid, TransactionId parent);
extern TransactionId SubTransGetParent(TransactionId xid); extern TransactionId SubTransGetParent(TransactionId xid);
extern TransactionId SubTransGetTopmostTransaction(TransactionId xid); extern TransactionId SubTransGetTopmostTransaction(TransactionId xid);
...@@ -29,6 +23,5 @@ extern void ShutdownSUBTRANS(void); ...@@ -29,6 +23,5 @@ extern void ShutdownSUBTRANS(void);
extern void CheckPointSUBTRANS(void); extern void CheckPointSUBTRANS(void);
extern void ExtendSUBTRANS(TransactionId newestXact); extern void ExtendSUBTRANS(TransactionId newestXact);
extern void TruncateSUBTRANS(TransactionId oldestXact); extern void TruncateSUBTRANS(TransactionId oldestXact);
extern void subtrans_zeropage_redo(int pageno);
#endif /* SUBTRANS_H */ #endif /* SUBTRANS_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/lwlock.h,v 1.13 2004/08/11 04:07:16 tgl Exp $ * $PostgreSQL: pgsql/src/include/storage/lwlock.h,v 1.14 2004/08/23 23:22:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -37,6 +37,8 @@ typedef enum LWLockId ...@@ -37,6 +37,8 @@ typedef enum LWLockId
ControlFileLock, ControlFileLock,
CheckpointLock, CheckpointLock,
CheckpointStartLock, CheckpointStartLock,
CLogControlLock,
SubtransControlLock,
RelCacheInitLock, RelCacheInitLock,
BgWriterCommLock, BgWriterCommLock,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment