mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
pgindent run on all C files. Java run to follow. initdb/regression
tests pass.
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/clog.c,v 1.4 2001/09/29 04:02:21 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/clog.c,v 1.5 2001/10/25 05:49:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
/*
|
||||
* Defines for CLOG page and segment sizes. A page is the same BLCKSZ
|
||||
* as is used everywhere else in Postgres. The CLOG segment size can be
|
||||
* as is used everywhere else in Postgres. The CLOG segment size can be
|
||||
* chosen somewhat arbitrarily; we make it 1 million transactions by default,
|
||||
* or 256Kb.
|
||||
*
|
||||
@@ -48,15 +48,15 @@
|
||||
|
||||
/* We need two bits per xact, so four xacts fit in a byte */
|
||||
#define CLOG_BITS_PER_XACT 2
|
||||
#define CLOG_XACTS_PER_BYTE 4
|
||||
#define CLOG_XACTS_PER_PAGE (CLOG_BLCKSZ * CLOG_XACTS_PER_BYTE)
|
||||
#define CLOG_XACTS_PER_BYTE 4
|
||||
#define CLOG_XACTS_PER_PAGE (CLOG_BLCKSZ * CLOG_XACTS_PER_BYTE)
|
||||
#define CLOG_XACT_BITMASK ((1 << CLOG_BITS_PER_XACT) - 1)
|
||||
|
||||
#define CLOG_XACTS_PER_SEGMENT 0x100000
|
||||
#define CLOG_PAGES_PER_SEGMENT (CLOG_XACTS_PER_SEGMENT / CLOG_XACTS_PER_PAGE)
|
||||
|
||||
#define TransactionIdToPage(xid) ((xid) / (TransactionId) CLOG_XACTS_PER_PAGE)
|
||||
#define TransactionIdToPgIndex(xid) ((xid) % (TransactionId) CLOG_XACTS_PER_PAGE)
|
||||
#define TransactionIdToPgIndex(xid) ((xid) % (TransactionId) CLOG_XACTS_PER_PAGE)
|
||||
#define TransactionIdToByte(xid) (TransactionIdToPgIndex(xid) / CLOG_XACTS_PER_BYTE)
|
||||
#define TransactionIdToBIndex(xid) ((xid) % (TransactionId) CLOG_XACTS_PER_BYTE)
|
||||
|
||||
@@ -101,15 +101,15 @@
|
||||
* the control lock.
|
||||
*
|
||||
* As with the regular buffer manager, it is possible for another process
|
||||
* to re-dirty a page that is currently being written out. This is handled
|
||||
* to re-dirty a page that is currently being written out. This is handled
|
||||
* by setting the page's state from WRITE_IN_PROGRESS to DIRTY. The writing
|
||||
* process must notice this and not mark the page CLEAN when it's done.
|
||||
*
|
||||
* XLOG interactions: this module generates an XLOG record whenever a new
|
||||
* CLOG page is initialized to zeroes. Other writes of CLOG come from
|
||||
* 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
|
||||
* 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,
|
||||
@@ -120,11 +120,13 @@
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLOG_PAGE_EMPTY, /* CLOG buffer is not in use */
|
||||
CLOG_PAGE_READ_IN_PROGRESS, /* CLOG page is being read in */
|
||||
CLOG_PAGE_CLEAN, /* CLOG page is valid and not dirty */
|
||||
CLOG_PAGE_DIRTY, /* CLOG page is valid but needs write */
|
||||
CLOG_PAGE_WRITE_IN_PROGRESS /* CLOG page is being written out in */
|
||||
CLOG_PAGE_EMPTY,/* CLOG buffer is not in use */
|
||||
CLOG_PAGE_READ_IN_PROGRESS, /* CLOG page is being read
|
||||
* in */
|
||||
CLOG_PAGE_CLEAN,/* CLOG page is valid and not dirty */
|
||||
CLOG_PAGE_DIRTY,/* CLOG page is valid but needs write */
|
||||
CLOG_PAGE_WRITE_IN_PROGRESS /* CLOG page is being
|
||||
* written out in */
|
||||
} ClogPageStatus;
|
||||
|
||||
/*
|
||||
@@ -134,14 +136,15 @@ typedef struct ClogCtlData
|
||||
{
|
||||
/*
|
||||
* Info for each buffer slot. Page number is undefined when status is
|
||||
* EMPTY. lru_count is essentially the number of operations since last
|
||||
* use of this page; the page with highest lru_count is the best candidate
|
||||
* to replace.
|
||||
* EMPTY. lru_count is essentially the number of operations since
|
||||
* last use of this page; the page with highest lru_count is the best
|
||||
* candidate to replace.
|
||||
*/
|
||||
char *page_buffer[NUM_CLOG_BUFFERS];
|
||||
ClogPageStatus page_status[NUM_CLOG_BUFFERS];
|
||||
ClogPageStatus page_status[NUM_CLOG_BUFFERS];
|
||||
int page_number[NUM_CLOG_BUFFERS];
|
||||
unsigned int page_lru_count[NUM_CLOG_BUFFERS];
|
||||
unsigned int page_lru_count[NUM_CLOG_BUFFERS];
|
||||
|
||||
/*
|
||||
* latest_page_number is the page number of the current end of the
|
||||
* CLOG; this is not critical data, since we use it only to avoid
|
||||
@@ -157,7 +160,7 @@ static ClogCtlData *ClogCtl = NULL;
|
||||
* The value is automatically inherited by backends via fork, and
|
||||
* doesn't need to be in shared memory.
|
||||
*/
|
||||
static LWLockId ClogBufferLocks[NUM_CLOG_BUFFERS]; /* Per-buffer I/O locks */
|
||||
static LWLockId ClogBufferLocks[NUM_CLOG_BUFFERS]; /* Per-buffer I/O locks */
|
||||
|
||||
/*
|
||||
* ClogDir is set during CLOGShmemInit and does not change thereafter.
|
||||
@@ -166,7 +169,7 @@ static LWLockId ClogBufferLocks[NUM_CLOG_BUFFERS]; /* Per-buffer I/O locks */
|
||||
*/
|
||||
static char ClogDir[MAXPGPATH];
|
||||
|
||||
#define ClogFileName(path, seg) \
|
||||
#define ClogFileName(path, seg) \
|
||||
snprintf(path, MAXPGPATH, "%s/%04X", ClogDir, seg)
|
||||
|
||||
/*
|
||||
@@ -430,7 +433,7 @@ ReadCLOGPage(int pageno)
|
||||
LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
|
||||
|
||||
Assert(ClogCtl->page_number[slotno] == pageno &&
|
||||
ClogCtl->page_status[slotno] == CLOG_PAGE_READ_IN_PROGRESS);
|
||||
ClogCtl->page_status[slotno] == CLOG_PAGE_READ_IN_PROGRESS);
|
||||
|
||||
ClogCtl->page_status[slotno] = CLOG_PAGE_CLEAN;
|
||||
|
||||
@@ -447,7 +450,7 @@ ReadCLOGPage(int pageno)
|
||||
*
|
||||
* NOTE: only one write attempt is made here. Hence, it is possible that
|
||||
* the page is still dirty at exit (if someone else re-dirtied it during
|
||||
* the write). However, we *do* attempt a fresh write even if the page
|
||||
* the write). However, we *do* attempt a fresh write even if the page
|
||||
* is already being written; this is for checkpoints.
|
||||
*
|
||||
* Control lock must be held at entry, and will be held at exit.
|
||||
@@ -455,7 +458,7 @@ ReadCLOGPage(int pageno)
|
||||
static void
|
||||
WriteCLOGPage(int slotno)
|
||||
{
|
||||
int pageno;
|
||||
int pageno;
|
||||
|
||||
/* Do nothing if page does not need writing */
|
||||
if (ClogCtl->page_status[slotno] != CLOG_PAGE_DIRTY &&
|
||||
@@ -489,11 +492,12 @@ WriteCLOGPage(int slotno)
|
||||
* update on this page will mark it dirty again. NB: we are assuming
|
||||
* that read/write of the page status field is atomic, since we change
|
||||
* the state while not holding control lock. However, we cannot set
|
||||
* this state any sooner, or we'd possibly fool a previous writer
|
||||
* into thinking he's successfully dumped the page when he hasn't.
|
||||
* (Scenario: other writer starts, page is redirtied, we come along and
|
||||
* set WRITE_IN_PROGRESS again, other writer completes and sets CLEAN
|
||||
* because redirty info has been lost, then we think it's clean too.)
|
||||
* this state any sooner, or we'd possibly fool a previous writer into
|
||||
* thinking he's successfully dumped the page when he hasn't.
|
||||
* (Scenario: other writer starts, page is redirtied, we come along
|
||||
* and set WRITE_IN_PROGRESS again, other writer completes and sets
|
||||
* CLEAN because redirty info has been lost, then we think it's clean
|
||||
* too.)
|
||||
*/
|
||||
ClogCtl->page_status[slotno] = CLOG_PAGE_WRITE_IN_PROGRESS;
|
||||
|
||||
@@ -523,7 +527,7 @@ WriteCLOGPage(int slotno)
|
||||
static void
|
||||
CLOGPhysicalReadPage(int pageno, int slotno)
|
||||
{
|
||||
int segno = pageno / CLOG_PAGES_PER_SEGMENT;
|
||||
int segno = pageno / CLOG_PAGES_PER_SEGMENT;
|
||||
int rpageno = pageno % CLOG_PAGES_PER_SEGMENT;
|
||||
int offset = rpageno * CLOG_BLCKSZ;
|
||||
char path[MAXPGPATH];
|
||||
@@ -533,9 +537,9 @@ CLOGPhysicalReadPage(int pageno, int slotno)
|
||||
|
||||
/*
|
||||
* In a crash-and-restart situation, it's possible for us to receive
|
||||
* commands to set the commit status of transactions whose bits are
|
||||
* in already-truncated segments of the commit log (see notes in
|
||||
* CLOGPhysicalWritePage). Hence, if we are InRecovery, allow the
|
||||
* commands to set the commit status of transactions whose bits are in
|
||||
* already-truncated segments of the commit log (see notes in
|
||||
* CLOGPhysicalWritePage). Hence, if we are InRecovery, allow the
|
||||
* case where the file doesn't exist, and return zeroes instead.
|
||||
*/
|
||||
fd = BasicOpenFile(path, O_RDWR | PG_BINARY, S_IRUSR | S_IWUSR);
|
||||
@@ -569,7 +573,7 @@ CLOGPhysicalReadPage(int pageno, int slotno)
|
||||
static void
|
||||
CLOGPhysicalWritePage(int pageno, int slotno)
|
||||
{
|
||||
int segno = pageno / CLOG_PAGES_PER_SEGMENT;
|
||||
int segno = pageno / CLOG_PAGES_PER_SEGMENT;
|
||||
int rpageno = pageno % CLOG_PAGES_PER_SEGMENT;
|
||||
int offset = rpageno * CLOG_BLCKSZ;
|
||||
char path[MAXPGPATH];
|
||||
@@ -578,16 +582,17 @@ CLOGPhysicalWritePage(int pageno, int slotno)
|
||||
ClogFileName(path, segno);
|
||||
|
||||
/*
|
||||
* If the file doesn't already exist, we should create it. It is possible
|
||||
* for this to need to happen when writing a page that's not first in
|
||||
* its segment; we assume the OS can cope with that. (Note: it might seem
|
||||
* that it'd be okay to create files only when ZeroCLOGPage is called for
|
||||
* the first page of a segment. However, if after a crash and restart
|
||||
* the REDO logic elects to replay the log from a checkpoint before the
|
||||
* latest one, then it's possible that we will get commands to set
|
||||
* transaction status of transactions that have already been truncated
|
||||
* from the commit log. Easiest way to deal with that is to accept
|
||||
* references to nonexistent files here and in CLOGPhysicalReadPage.)
|
||||
* If the file doesn't already exist, we should create it. It is
|
||||
* possible for this to need to happen when writing a page that's not
|
||||
* first in its segment; we assume the OS can cope with that. (Note:
|
||||
* it might seem that it'd be okay to create files only when
|
||||
* ZeroCLOGPage is called for the first page of a segment. However,
|
||||
* if after a crash and restart the REDO logic elects to replay the
|
||||
* log from a checkpoint before the latest one, then it's possible
|
||||
* that we will get commands to set transaction status of transactions
|
||||
* that have already been truncated from the commit log. Easiest way
|
||||
* to deal with that is to accept references to nonexistent files here
|
||||
* and in CLOGPhysicalReadPage.)
|
||||
*/
|
||||
fd = BasicOpenFile(path, O_RDWR | PG_BINARY, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0)
|
||||
@@ -649,16 +654,15 @@ SelectLRUCLOGPage(int pageno)
|
||||
}
|
||||
|
||||
/*
|
||||
* If we find any EMPTY slot, just select that one.
|
||||
* Else locate the least-recently-used slot that isn't the
|
||||
* latest CLOG page.
|
||||
* If we find any EMPTY slot, just select that one. Else locate
|
||||
* the least-recently-used slot that isn't the latest CLOG page.
|
||||
*/
|
||||
for (slotno = 0; slotno < NUM_CLOG_BUFFERS; slotno++)
|
||||
{
|
||||
if (ClogCtl->page_status[slotno] == CLOG_PAGE_EMPTY)
|
||||
return slotno;
|
||||
if (ClogCtl->page_lru_count[slotno] > bestcount &&
|
||||
ClogCtl->page_number[slotno] != ClogCtl->latest_page_number)
|
||||
ClogCtl->page_number[slotno] != ClogCtl->latest_page_number)
|
||||
{
|
||||
bestslot = slotno;
|
||||
bestcount = ClogCtl->page_lru_count[slotno];
|
||||
@@ -672,10 +676,10 @@ SelectLRUCLOGPage(int pageno)
|
||||
return bestslot;
|
||||
|
||||
/*
|
||||
* We need to do I/O. Normal case is that we have to write it out,
|
||||
* but it's possible in the worst case to have selected a read-busy
|
||||
* page. In that case we use ReadCLOGPage to wait for the read to
|
||||
* complete.
|
||||
* We need to do I/O. Normal case is that we have to write it
|
||||
* out, but it's possible in the worst case to have selected a
|
||||
* read-busy page. In that case we use ReadCLOGPage to wait for
|
||||
* the read to complete.
|
||||
*/
|
||||
if (ClogCtl->page_status[bestslot] == CLOG_PAGE_READ_IN_PROGRESS)
|
||||
(void) ReadCLOGPage(ClogCtl->page_number[bestslot]);
|
||||
@@ -683,9 +687,9 @@ SelectLRUCLOGPage(int pageno)
|
||||
WriteCLOGPage(bestslot);
|
||||
|
||||
/*
|
||||
* Now loop back and try again. This is the easiest way of dealing
|
||||
* with corner cases such as the victim page being re-dirtied while
|
||||
* we wrote it.
|
||||
* Now loop back and try again. This is the easiest way of
|
||||
* dealing with corner cases such as the victim page being
|
||||
* re-dirtied while we wrote it.
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -736,6 +740,7 @@ CheckPointCLOG(void)
|
||||
for (slotno = 0; slotno < NUM_CLOG_BUFFERS; slotno++)
|
||||
{
|
||||
WriteCLOGPage(slotno);
|
||||
|
||||
/*
|
||||
* We cannot assert that the slot is clean now, since another
|
||||
* process might have re-dirtied it already. That's okay.
|
||||
@@ -782,13 +787,13 @@ ExtendCLOG(TransactionId newestXact)
|
||||
* Remove all CLOG segments before the one holding the passed transaction ID
|
||||
*
|
||||
* When this is called, we know that the database logically contains no
|
||||
* reference to transaction IDs older than oldestXact. However, we must
|
||||
* reference to transaction IDs older than oldestXact. However, we must
|
||||
* not truncate the CLOG until we have performed a checkpoint, to ensure
|
||||
* that no such references remain on disk either; else a crash just after
|
||||
* the truncation might leave us with a problem. Since CLOG segments hold
|
||||
* a large number of transactions, the opportunity to actually remove a
|
||||
* segment is fairly rare, and so it seems best not to do the checkpoint
|
||||
* unless we have confirmed that there is a removable segment. Therefore
|
||||
* unless we have confirmed that there is a removable segment. Therefore
|
||||
* we issue the checkpoint command here, not in higher-level code as might
|
||||
* seem cleaner.
|
||||
*/
|
||||
@@ -813,15 +818,16 @@ TruncateCLOG(TransactionId oldestXact)
|
||||
/*
|
||||
* Scan CLOG shared memory and remove any pages preceding the cutoff
|
||||
* page, to ensure we won't rewrite them later. (Any dirty pages
|
||||
* should have been flushed already during the checkpoint, we're
|
||||
* just being extra careful here.)
|
||||
* should have been flushed already during the checkpoint, we're just
|
||||
* being extra careful here.)
|
||||
*/
|
||||
LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
|
||||
|
||||
restart:;
|
||||
|
||||
/*
|
||||
* While we are holding the lock, make an important safety check:
|
||||
* the planned cutoff point must be <= the current CLOG endpoint page.
|
||||
* While we are holding the lock, make an important safety check: the
|
||||
* planned cutoff point must be <= the current CLOG endpoint page.
|
||||
* Otherwise we have already wrapped around, and proceeding with the
|
||||
* truncation would risk removing the current CLOG segment.
|
||||
*/
|
||||
@@ -838,6 +844,7 @@ restart:;
|
||||
continue;
|
||||
if (!CLOGPagePrecedes(ClogCtl->page_number[slotno], cutoffPage))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If page is CLEAN, just change state to EMPTY (expected case).
|
||||
*/
|
||||
@@ -846,6 +853,7 @@ restart:;
|
||||
ClogCtl->page_status[slotno] = CLOG_PAGE_EMPTY;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hmm, we have (or may have) I/O operations acting on the page,
|
||||
* so we've got to wait for them to finish and then start again.
|
||||
@@ -928,9 +936,11 @@ CLOGPagePrecedes(int page1, int page2)
|
||||
TransactionId xid1;
|
||||
TransactionId xid2;
|
||||
|
||||
xid1 = (TransactionId) page1 * CLOG_XACTS_PER_PAGE;
|
||||
xid1 = (TransactionId) page1 *CLOG_XACTS_PER_PAGE;
|
||||
|
||||
xid1 += FirstNormalTransactionId;
|
||||
xid2 = (TransactionId) page2 * CLOG_XACTS_PER_PAGE;
|
||||
xid2 = (TransactionId) page2 *CLOG_XACTS_PER_PAGE;
|
||||
|
||||
xid2 += FirstNormalTransactionId;
|
||||
|
||||
return TransactionIdPrecedes(xid1, xid2);
|
||||
@@ -966,8 +976,8 @@ clog_redo(XLogRecPtr lsn, XLogRecord *record)
|
||||
|
||||
if (info == CLOG_ZEROPAGE)
|
||||
{
|
||||
int pageno;
|
||||
int slotno;
|
||||
int pageno;
|
||||
int slotno;
|
||||
|
||||
memcpy(&pageno, XLogRecGetData(record), sizeof(int));
|
||||
|
||||
@@ -993,7 +1003,7 @@ clog_desc(char *buf, uint8 xl_info, char *rec)
|
||||
|
||||
if (info == CLOG_ZEROPAGE)
|
||||
{
|
||||
int pageno;
|
||||
int pageno;
|
||||
|
||||
memcpy(&pageno, rec, sizeof(int));
|
||||
sprintf(buf + strlen(buf), "zeropage: %d", pageno);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.48 2001/08/26 16:55:59 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.49 2001/10/25 05:49:22 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* This file contains the high level access-method interface to the
|
||||
@@ -32,7 +32,7 @@ static void TransactionLogUpdate(TransactionId transactionId,
|
||||
* ----------------
|
||||
*/
|
||||
static TransactionId cachedTestXid = InvalidTransactionId;
|
||||
static XidStatus cachedTestXidStatus;
|
||||
static XidStatus cachedTestXidStatus;
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
@@ -56,8 +56,8 @@ TransactionLogTest(TransactionId transactionId, /* transaction id to test */
|
||||
XidStatus xidstatus; /* recorded status of xid */
|
||||
|
||||
/*
|
||||
* Before going to the commit log manager, check our single item cache to
|
||||
* see if we didn't just check the transaction status a moment ago.
|
||||
* Before going to the commit log manager, check our single item cache
|
||||
* to see if we didn't just check the transaction status a moment ago.
|
||||
*/
|
||||
if (TransactionIdEquals(transactionId, cachedTestXid))
|
||||
return (status == cachedTestXidStatus);
|
||||
@@ -65,7 +65,7 @@ TransactionLogTest(TransactionId transactionId, /* transaction id to test */
|
||||
/*
|
||||
* Also, check to see if the transaction ID is a permanent one.
|
||||
*/
|
||||
if (! TransactionIdIsNormal(transactionId))
|
||||
if (!TransactionIdIsNormal(transactionId))
|
||||
{
|
||||
if (TransactionIdEquals(transactionId, BootstrapTransactionId))
|
||||
return (status == TRANSACTION_STATUS_COMMITTED);
|
||||
@@ -77,18 +77,18 @@ TransactionLogTest(TransactionId transactionId, /* transaction id to test */
|
||||
/*
|
||||
* Get the status.
|
||||
*/
|
||||
xidstatus = TransactionIdGetStatus(transactionId);
|
||||
xidstatus = TransactionIdGetStatus(transactionId);
|
||||
|
||||
/*
|
||||
* DO NOT cache status for unfinished transactions!
|
||||
*/
|
||||
if (xidstatus != TRANSACTION_STATUS_IN_PROGRESS)
|
||||
{
|
||||
TransactionIdStore(transactionId, &cachedTestXid);
|
||||
cachedTestXidStatus = xidstatus;
|
||||
}
|
||||
/*
|
||||
* DO NOT cache status for unfinished transactions!
|
||||
*/
|
||||
if (xidstatus != TRANSACTION_STATUS_IN_PROGRESS)
|
||||
{
|
||||
TransactionIdStore(transactionId, &cachedTestXid);
|
||||
cachedTestXidStatus = xidstatus;
|
||||
}
|
||||
|
||||
return (status == xidstatus);
|
||||
return (status == xidstatus);
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
@@ -197,7 +197,7 @@ TransactionIdIsInProgress(TransactionId transactionId)
|
||||
|
||||
return TransactionLogTest(transactionId, TRANSACTION_STATUS_IN_PROGRESS);
|
||||
}
|
||||
#endif /* NOT_USED */
|
||||
#endif /* NOT_USED */
|
||||
|
||||
/* --------------------------------
|
||||
* TransactionId Commit
|
||||
@@ -246,7 +246,7 @@ TransactionIdPrecedes(TransactionId id1, TransactionId id2)
|
||||
{
|
||||
/*
|
||||
* If either ID is a permanent XID then we can just do unsigned
|
||||
* comparison. If both are normal, do a modulo-2^31 comparison.
|
||||
* comparison. If both are normal, do a modulo-2^31 comparison.
|
||||
*/
|
||||
int32 diff;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* Copyright (c) 2000, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.46 2001/09/29 04:02:21 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.47 2001/10/25 05:49:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ VariableCache ShmemVariableCache = NULL;
|
||||
TransactionId
|
||||
GetNewTransactionId(void)
|
||||
{
|
||||
TransactionId xid;
|
||||
TransactionId xid;
|
||||
|
||||
/*
|
||||
* During bootstrap initialization, we return the special bootstrap
|
||||
@@ -48,32 +48,32 @@ GetNewTransactionId(void)
|
||||
TransactionIdAdvance(ShmemVariableCache->nextXid);
|
||||
|
||||
/*
|
||||
* If we have just allocated the first XID of a new page of the
|
||||
* commit log, zero out that commit-log page before returning.
|
||||
* We must do this while holding XidGenLock, else another xact could
|
||||
* acquire and commit a later XID before we zero the page. Fortunately,
|
||||
* a page of the commit log holds 32K or more transactions, so we don't
|
||||
* have to do this very often.
|
||||
* If we have just allocated the first XID of a new page of the commit
|
||||
* log, zero out that commit-log page before returning. We must do
|
||||
* this while holding XidGenLock, else another xact could acquire and
|
||||
* commit a later XID before we zero the page. Fortunately, a page of
|
||||
* the commit log holds 32K or more transactions, so we don't have to
|
||||
* do this very often.
|
||||
*/
|
||||
ExtendCLOG(xid);
|
||||
|
||||
/*
|
||||
* Must set MyProc->xid before releasing XidGenLock. This ensures that
|
||||
* when GetSnapshotData calls ReadNewTransactionId, all active XIDs
|
||||
* before the returned value of nextXid are already present in the shared
|
||||
* PROC array. Else we have a race condition.
|
||||
* Must set MyProc->xid before releasing XidGenLock. This ensures
|
||||
* that when GetSnapshotData calls ReadNewTransactionId, all active
|
||||
* XIDs before the returned value of nextXid are already present in
|
||||
* the shared PROC array. Else we have a race condition.
|
||||
*
|
||||
* XXX by storing xid into MyProc without acquiring SInvalLock, we are
|
||||
* relying on fetch/store of an xid to be atomic, else other backends
|
||||
* might see a partially-set xid here. But holding both locks at once
|
||||
* would be a nasty concurrency hit (and in fact could cause a deadlock
|
||||
* against GetSnapshotData). So for now, assume atomicity. Note that
|
||||
* readers of PROC xid field should be careful to fetch the value only
|
||||
* once, rather than assume they can read it multiple times and get the
|
||||
* same answer each time.
|
||||
* might see a partially-set xid here. But holding both locks at once
|
||||
* would be a nasty concurrency hit (and in fact could cause a
|
||||
* deadlock against GetSnapshotData). So for now, assume atomicity.
|
||||
* Note that readers of PROC xid field should be careful to fetch the
|
||||
* value only once, rather than assume they can read it multiple times
|
||||
* and get the same answer each time.
|
||||
*
|
||||
* A solution to the atomic-store problem would be to give each PROC
|
||||
* its own spinlock used only for fetching/storing that PROC's xid.
|
||||
* A solution to the atomic-store problem would be to give each PROC its
|
||||
* own spinlock used only for fetching/storing that PROC's xid.
|
||||
* (SInvalLock would then mean primarily that PROCs couldn't be added/
|
||||
* removed while holding the lock.)
|
||||
*/
|
||||
@@ -91,7 +91,7 @@ GetNewTransactionId(void)
|
||||
TransactionId
|
||||
ReadNewTransactionId(void)
|
||||
{
|
||||
TransactionId xid;
|
||||
TransactionId xid;
|
||||
|
||||
/*
|
||||
* During bootstrap initialization, we return the special bootstrap
|
||||
@@ -117,16 +117,16 @@ static Oid lastSeenOid = InvalidOid;
|
||||
Oid
|
||||
GetNewObjectId(void)
|
||||
{
|
||||
Oid result;
|
||||
Oid result;
|
||||
|
||||
LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
|
||||
|
||||
/*
|
||||
* Check for wraparound of the OID counter. We *must* not return 0
|
||||
* (InvalidOid); and as long as we have to check that, it seems a good
|
||||
* idea to skip over everything below BootstrapObjectIdData too. (This
|
||||
* basically just reduces the odds of OID collision right after a wrap
|
||||
* occurs.) Note we are relying on unsigned comparison here.
|
||||
* idea to skip over everything below BootstrapObjectIdData too.
|
||||
* (This basically just reduces the odds of OID collision right after
|
||||
* a wrap occurs.) Note we are relying on unsigned comparison here.
|
||||
*/
|
||||
if (ShmemVariableCache->nextOid < ((Oid) BootstrapObjectIdData))
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.112 2001/10/18 17:30:03 thomas Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.113 2001/10/25 05:49:22 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Transaction aborts can now occur two ways:
|
||||
@@ -300,7 +300,6 @@ IsTransactionState(void)
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* --------------------------------
|
||||
@@ -476,7 +475,6 @@ AtStart_Cache(void)
|
||||
static void
|
||||
AtStart_Locks(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* at present, it is unknown to me what belongs here -cim 3/18/90
|
||||
*
|
||||
@@ -492,7 +490,6 @@ AtStart_Locks(void)
|
||||
static void
|
||||
AtStart_Memory(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* We shouldn't have any transaction contexts already.
|
||||
*/
|
||||
@@ -717,8 +714,8 @@ RecordTransactionAbort(void)
|
||||
recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, &rdata);
|
||||
|
||||
/*
|
||||
* There's no need for XLogFlush here, since the default assumption
|
||||
* would be that we aborted, anyway.
|
||||
* There's no need for XLogFlush here, since the default
|
||||
* assumption would be that we aborted, anyway.
|
||||
*/
|
||||
|
||||
/* Mark the transaction aborted in clog */
|
||||
@@ -756,7 +753,6 @@ AtAbort_Cache(void)
|
||||
static void
|
||||
AtAbort_Locks(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* XXX What if ProcReleaseLocks() fails? (race condition?)
|
||||
*
|
||||
@@ -773,7 +769,6 @@ AtAbort_Locks(void)
|
||||
static void
|
||||
AtAbort_Memory(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* Make sure we are in a valid context (not a child of
|
||||
* TransactionCommandContext...). Note that it is possible for this
|
||||
@@ -807,7 +802,6 @@ AtAbort_Memory(void)
|
||||
static void
|
||||
AtCleanup_Memory(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* Now that we're "out" of a transaction, have the system allocate
|
||||
* things in the top memory context instead of per-transaction
|
||||
@@ -909,7 +903,6 @@ CurrentXactInProgress(void)
|
||||
{
|
||||
return CurrentTransactionState->state == TRANS_INPROGRESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* --------------------------------
|
||||
@@ -965,12 +958,11 @@ CommitTransaction(void)
|
||||
* this must be done _before_ releasing locks we hold and _after_
|
||||
* RecordTransactionCommit.
|
||||
*
|
||||
* LWLockAcquire(SInvalLock) is required: UPDATE with xid 0 is blocked
|
||||
* by xid 1' UPDATE, xid 1 is doing commit while xid 2 gets snapshot -
|
||||
* if xid 2' GetSnapshotData sees xid 1 as running then it must see
|
||||
* xid 0 as running as well or it will see two tuple versions - one
|
||||
* deleted by xid 1 and one inserted by xid 0. See notes in
|
||||
* GetSnapshotData.
|
||||
* LWLockAcquire(SInvalLock) is required: UPDATE with xid 0 is blocked by
|
||||
* xid 1' UPDATE, xid 1 is doing commit while xid 2 gets snapshot - if
|
||||
* xid 2' GetSnapshotData sees xid 1 as running then it must see xid 0
|
||||
* as running as well or it will see two tuple versions - one deleted
|
||||
* by xid 1 and one inserted by xid 0. See notes in GetSnapshotData.
|
||||
*/
|
||||
if (MyProc != (PROC *) NULL)
|
||||
{
|
||||
@@ -1002,7 +994,7 @@ CommitTransaction(void)
|
||||
AtCommit_Memory();
|
||||
AtEOXact_Files();
|
||||
|
||||
SharedBufferChanged = false;/* safest place to do it */
|
||||
SharedBufferChanged = false; /* safest place to do it */
|
||||
|
||||
/* Count transaction commit in statistics collector */
|
||||
pgstat_count_xact_commit();
|
||||
@@ -1032,8 +1024,8 @@ AbortTransaction(void)
|
||||
/*
|
||||
* Release any LW locks we might be holding as quickly as possible.
|
||||
* (Regular locks, however, must be held till we finish aborting.)
|
||||
* Releasing LW locks is critical since we might try to grab them again
|
||||
* while cleaning up!
|
||||
* Releasing LW locks is critical since we might try to grab them
|
||||
* again while cleaning up!
|
||||
*/
|
||||
LWLockReleaseAll();
|
||||
|
||||
@@ -1105,7 +1097,7 @@ AbortTransaction(void)
|
||||
AtEOXact_Files();
|
||||
AtAbort_Locks();
|
||||
|
||||
SharedBufferChanged = false;/* safest place to do it */
|
||||
SharedBufferChanged = false; /* safest place to do it */
|
||||
|
||||
/* Count transaction abort in statistics collector */
|
||||
pgstat_count_xact_rollback();
|
||||
@@ -1155,7 +1147,6 @@ StartTransactionCommand(void)
|
||||
|
||||
switch (s->blockState)
|
||||
{
|
||||
|
||||
/*
|
||||
* if we aren't in a transaction block, we just do our usual
|
||||
* start transaction.
|
||||
@@ -1238,7 +1229,6 @@ CommitTransactionCommand(void)
|
||||
|
||||
switch (s->blockState)
|
||||
{
|
||||
|
||||
/*
|
||||
* if we aren't in a transaction block, we just do our usual
|
||||
* transaction commit
|
||||
@@ -1313,7 +1303,6 @@ AbortCurrentTransaction(void)
|
||||
|
||||
switch (s->blockState)
|
||||
{
|
||||
|
||||
/*
|
||||
* if we aren't in a transaction block, we just do the basic
|
||||
* abort & cleanup transaction.
|
||||
@@ -1429,7 +1418,6 @@ EndTransactionBlock(void)
|
||||
*/
|
||||
if (s->blockState == TBLOCK_INPROGRESS)
|
||||
{
|
||||
|
||||
/*
|
||||
* here we are in a transaction block which should commit when we
|
||||
* get to the upcoming CommitTransactionCommand() so we set the
|
||||
@@ -1442,7 +1430,6 @@ EndTransactionBlock(void)
|
||||
|
||||
if (s->blockState == TBLOCK_ABORT)
|
||||
{
|
||||
|
||||
/*
|
||||
* here, we are in a transaction block which aborted and since the
|
||||
* AbortTransaction() was already done, we do whatever is needed
|
||||
@@ -1480,7 +1467,6 @@ AbortTransactionBlock(void)
|
||||
*/
|
||||
if (s->blockState == TBLOCK_INPROGRESS)
|
||||
{
|
||||
|
||||
/*
|
||||
* here we were inside a transaction block something screwed up
|
||||
* inside the system so we enter the abort state, do the abort
|
||||
@@ -1502,7 +1488,6 @@ AbortTransactionBlock(void)
|
||||
AbortTransaction();
|
||||
s->blockState = TBLOCK_ENDABORT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* --------------------------------
|
||||
@@ -1527,7 +1512,6 @@ UserAbortTransactionBlock(void)
|
||||
|
||||
if (s->blockState == TBLOCK_INPROGRESS)
|
||||
{
|
||||
|
||||
/*
|
||||
* here we were inside a transaction block and we got an abort
|
||||
* command from the user, so we move to the abort state, do the
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: xid.c,v 1.33 2001/08/26 16:55:59 tgl Exp $
|
||||
* $Id: xid.c,v 1.34 2001/10/25 05:49:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -34,6 +34,7 @@ Datum
|
||||
xidout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
|
||||
|
||||
/* maximum 32 bit unsigned integer representation takes 10 chars */
|
||||
char *str = palloc(11);
|
||||
|
||||
@@ -64,7 +65,7 @@ xid_age(PG_FUNCTION_ARGS)
|
||||
TransactionId now = GetCurrentTransactionId();
|
||||
|
||||
/* Permanent XIDs are always infinitely old */
|
||||
if (! TransactionIdIsNormal(xid))
|
||||
if (!TransactionIdIsNormal(xid))
|
||||
PG_RETURN_INT32(INT_MAX);
|
||||
|
||||
PG_RETURN_INT32((int32) (now - xid));
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.78 2001/09/29 04:02:21 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.79 2001/10/25 05:49:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -97,7 +97,7 @@ char XLOG_archive_dir[MAXPGPATH]; /* null string means
|
||||
* delete 'em */
|
||||
|
||||
/*
|
||||
* XLOGfileslop is used in the code as the allowed "fuzz" in the number of
|
||||
* XLOGfileslop is used in the code as the allowed "fuzz" in the number of
|
||||
* preallocated XLOG segments --- we try to have at least XLOGfiles advance
|
||||
* segments but no more than XLOGfiles+XLOGfileslop segments. This could
|
||||
* be made a separate GUC variable, but at present I think it's sufficient
|
||||
@@ -215,13 +215,13 @@ typedef struct XLogwrtRqst
|
||||
{
|
||||
XLogRecPtr Write; /* last byte + 1 to write out */
|
||||
XLogRecPtr Flush; /* last byte + 1 to flush */
|
||||
} XLogwrtRqst;
|
||||
} XLogwrtRqst;
|
||||
|
||||
typedef struct XLogwrtResult
|
||||
{
|
||||
XLogRecPtr Write; /* last byte + 1 written out */
|
||||
XLogRecPtr Flush; /* last byte + 1 flushed */
|
||||
} XLogwrtResult;
|
||||
} XLogwrtResult;
|
||||
|
||||
/*
|
||||
* Shared state data for XLogInsert.
|
||||
@@ -260,8 +260,9 @@ typedef struct XLogCtlData
|
||||
|
||||
/*
|
||||
* These values do not change after startup, although the pointed-to
|
||||
* pages and xlblocks values certainly do. Permission to read/write the
|
||||
* pages and xlblocks values depends on WALInsertLock and WALWriteLock.
|
||||
* pages and xlblocks values certainly do. Permission to read/write
|
||||
* the pages and xlblocks values depends on WALInsertLock and
|
||||
* WALWriteLock.
|
||||
*/
|
||||
char *pages; /* buffers for unwritten XLOG pages */
|
||||
XLogRecPtr *xlblocks; /* 1st byte ptr-s + BLCKSZ */
|
||||
@@ -428,8 +429,8 @@ static void XLogWrite(XLogwrtRqst WriteRqst);
|
||||
static int XLogFileInit(uint32 log, uint32 seg,
|
||||
bool *use_existent, bool use_lock);
|
||||
static bool InstallXLogFileSegment(uint32 log, uint32 seg, char *tmppath,
|
||||
bool find_free, int max_advance,
|
||||
bool use_lock);
|
||||
bool find_free, int max_advance,
|
||||
bool use_lock);
|
||||
static int XLogFileOpen(uint32 log, uint32 seg, bool econt);
|
||||
static void PreallocXlogFiles(XLogRecPtr endptr);
|
||||
static void MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr);
|
||||
@@ -621,8 +622,8 @@ begin:;
|
||||
SpinLockRelease_NoHoldoff(&XLogCtl->info_lck);
|
||||
|
||||
/*
|
||||
* If cache is half filled then try to acquire write lock and
|
||||
* do XLogWrite. Ignore any fractional blocks in performing this check.
|
||||
* If cache is half filled then try to acquire write lock and do
|
||||
* XLogWrite. Ignore any fractional blocks in performing this check.
|
||||
*/
|
||||
LogwrtRqst.Write.xrecoff -= LogwrtRqst.Write.xrecoff % BLCKSZ;
|
||||
if (LogwrtRqst.Write.xlogid != LogwrtResult.Write.xlogid ||
|
||||
@@ -939,9 +940,7 @@ AdvanceXLInsertBuffer(void)
|
||||
NewPageEndPtr.xrecoff = BLCKSZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewPageEndPtr.xrecoff += BLCKSZ;
|
||||
}
|
||||
XLogCtl->xlblocks[nextidx] = NewPageEndPtr;
|
||||
NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * BLCKSZ);
|
||||
Insert->curridx = nextidx;
|
||||
@@ -956,7 +955,7 @@ AdvanceXLInsertBuffer(void)
|
||||
|
||||
/* And fill the new page's header */
|
||||
NewPage->xlp_magic = XLOG_PAGE_MAGIC;
|
||||
/* NewPage->xlp_info = 0; */ /* done by memset */
|
||||
/* NewPage->xlp_info = 0; *//* done by memset */
|
||||
NewPage->xlp_sui = ThisStartUpID;
|
||||
NewPage->xlp_pageaddr.xlogid = NewPageEndPtr.xlogid;
|
||||
NewPage->xlp_pageaddr.xrecoff = NewPageEndPtr.xrecoff - BLCKSZ;
|
||||
@@ -985,7 +984,6 @@ XLogWrite(XLogwrtRqst WriteRqst)
|
||||
|
||||
while (XLByteLT(LogwrtResult.Write, WriteRqst.Write))
|
||||
{
|
||||
|
||||
/*
|
||||
* Make sure we're not ahead of the insert process. This could
|
||||
* happen if we're passed a bogus WriteRqst.Write that is past the
|
||||
@@ -1004,7 +1002,6 @@ XLogWrite(XLogwrtRqst WriteRqst)
|
||||
|
||||
if (!XLByteInPrevSeg(LogwrtResult.Write, openLogId, openLogSeg))
|
||||
{
|
||||
|
||||
/*
|
||||
* Switch to new logfile segment.
|
||||
*/
|
||||
@@ -1114,7 +1111,6 @@ XLogWrite(XLogwrtRqst WriteRqst)
|
||||
if (XLByteLT(LogwrtResult.Flush, WriteRqst.Flush) &&
|
||||
XLByteLT(LogwrtResult.Flush, LogwrtResult.Write))
|
||||
{
|
||||
|
||||
/*
|
||||
* Could get here without iterating above loop, in which case we
|
||||
* might have no open file or the wrong one. However, we do not
|
||||
@@ -1174,11 +1170,11 @@ XLogFlush(XLogRecPtr record)
|
||||
if (XLOG_DEBUG)
|
||||
{
|
||||
elog(DEBUG, "XLogFlush%s%s: request %X/%X; write %X/%X; flush %X/%X\n",
|
||||
(IsBootstrapProcessingMode()) ? "(bootstrap)" : "",
|
||||
(InRedo) ? "(redo)" : "",
|
||||
record.xlogid, record.xrecoff,
|
||||
LogwrtResult.Write.xlogid, LogwrtResult.Write.xrecoff,
|
||||
LogwrtResult.Flush.xlogid, LogwrtResult.Flush.xrecoff);
|
||||
(IsBootstrapProcessingMode()) ? "(bootstrap)" : "",
|
||||
(InRedo) ? "(redo)" : "",
|
||||
record.xlogid, record.xrecoff,
|
||||
LogwrtResult.Write.xlogid, LogwrtResult.Write.xrecoff,
|
||||
LogwrtResult.Flush.xlogid, LogwrtResult.Flush.xrecoff);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
@@ -1240,7 +1236,7 @@ XLogFlush(XLogRecPtr record)
|
||||
if (XLByteLT(LogwrtResult.Flush, record))
|
||||
elog(STOP, "XLogFlush: request %X/%X is not satisfied --- flushed only to %X/%X",
|
||||
record.xlogid, record.xrecoff,
|
||||
LogwrtResult.Flush.xlogid, LogwrtResult.Flush.xrecoff);
|
||||
LogwrtResult.Flush.xlogid, LogwrtResult.Flush.xrecoff);
|
||||
}
|
||||
LWLockRelease(WALWriteLock);
|
||||
}
|
||||
@@ -1565,8 +1561,8 @@ MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr)
|
||||
{
|
||||
/*
|
||||
* Before deleting the file, see if it can be recycled as
|
||||
* a future log segment. We allow recycling segments up to
|
||||
* XLOGfiles + XLOGfileslop segments beyond the current
|
||||
* a future log segment. We allow recycling segments up
|
||||
* to XLOGfiles + XLOGfileslop segments beyond the current
|
||||
* XLOG location.
|
||||
*/
|
||||
if (InstallXLogFileSegment(endlogId, endlogSeg, path,
|
||||
@@ -1719,7 +1715,6 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, char *buffer)
|
||||
|
||||
if (readBuf == NULL)
|
||||
{
|
||||
|
||||
/*
|
||||
* First time through, permanently allocate readBuf. We do it
|
||||
* this way, rather than just making a static array, for two
|
||||
@@ -1767,7 +1762,7 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, char *buffer)
|
||||
readFile = XLogFileOpen(readId, readSeg, (emode == LOG));
|
||||
if (readFile < 0)
|
||||
goto next_record_is_invalid;
|
||||
readOff = (uint32) (-1);/* force read to occur below */
|
||||
readOff = (uint32) (-1); /* force read to occur below */
|
||||
}
|
||||
|
||||
targetPageOff = ((RecPtr->xrecoff % XLogSegSize) / BLCKSZ) * BLCKSZ;
|
||||
@@ -2022,7 +2017,6 @@ WriteControlFile(void)
|
||||
|
||||
#ifdef USE_LOCALE
|
||||
char *localeptr;
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -2054,10 +2048,10 @@ WriteControlFile(void)
|
||||
"\n\tsuch queries, you may wish to set LC_COLLATE to \"C\" and"
|
||||
"\n\tre-initdb. For more information see the Administrator's Guide.",
|
||||
ControlFile->lc_collate);
|
||||
#else /* not USE_LOCALE */
|
||||
#else /* not USE_LOCALE */
|
||||
strcpy(ControlFile->lc_collate, "C");
|
||||
strcpy(ControlFile->lc_ctype, "C");
|
||||
#endif /* not USE_LOCALE */
|
||||
#endif /* not USE_LOCALE */
|
||||
|
||||
/* Contents are protected with a CRC */
|
||||
INIT_CRC64(ControlFile->crc);
|
||||
@@ -2156,7 +2150,7 @@ ReadControlFile(void)
|
||||
if (ControlFile->catalog_version_no != CATALOG_VERSION_NO)
|
||||
elog(STOP,
|
||||
"The database cluster was initialized with CATALOG_VERSION_NO %d,\n"
|
||||
"\tbut the backend was compiled with CATALOG_VERSION_NO %d.\n"
|
||||
"\tbut the backend was compiled with CATALOG_VERSION_NO %d.\n"
|
||||
"\tIt looks like you need to initdb.",
|
||||
ControlFile->catalog_version_no, CATALOG_VERSION_NO);
|
||||
if (ControlFile->blcksz != BLCKSZ)
|
||||
@@ -2174,7 +2168,7 @@ ReadControlFile(void)
|
||||
#ifdef USE_LOCALE
|
||||
if (setlocale(LC_COLLATE, ControlFile->lc_collate) == NULL)
|
||||
elog(STOP,
|
||||
"The database cluster was initialized with LC_COLLATE '%s',\n"
|
||||
"The database cluster was initialized with LC_COLLATE '%s',\n"
|
||||
"\twhich is not recognized by setlocale().\n"
|
||||
"\tIt looks like you need to initdb.",
|
||||
ControlFile->lc_collate);
|
||||
@@ -2184,15 +2178,15 @@ ReadControlFile(void)
|
||||
"\twhich is not recognized by setlocale().\n"
|
||||
"\tIt looks like you need to initdb.",
|
||||
ControlFile->lc_ctype);
|
||||
#else /* not USE_LOCALE */
|
||||
#else /* not USE_LOCALE */
|
||||
if (strcmp(ControlFile->lc_collate, "C") != 0 ||
|
||||
strcmp(ControlFile->lc_ctype, "C") != 0)
|
||||
elog(STOP,
|
||||
"The database cluster was initialized with LC_COLLATE '%s' and\n"
|
||||
"The database cluster was initialized with LC_COLLATE '%s' and\n"
|
||||
"\tLC_CTYPE '%s', but the server was compiled without locale support.\n"
|
||||
"\tIt looks like you need to initdb or recompile.",
|
||||
ControlFile->lc_collate, ControlFile->lc_ctype);
|
||||
#endif /* not USE_LOCALE */
|
||||
#endif /* not USE_LOCALE */
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2536,7 +2530,7 @@ StartupXLOG(void)
|
||||
{
|
||||
/* nextXid must be beyond record's xid */
|
||||
if (TransactionIdFollowsOrEquals(record->xl_xid,
|
||||
ShmemVariableCache->nextXid))
|
||||
ShmemVariableCache->nextXid))
|
||||
{
|
||||
ShmemVariableCache->nextXid = record->xl_xid;
|
||||
TransactionIdAdvance(ShmemVariableCache->nextXid);
|
||||
@@ -2585,8 +2579,8 @@ StartupXLOG(void)
|
||||
Insert->PrevRecord = LastRec;
|
||||
|
||||
/*
|
||||
* If the next record will go to the new page
|
||||
* then initialize for that one.
|
||||
* If the next record will go to the new page then initialize for that
|
||||
* one.
|
||||
*/
|
||||
if ((BLCKSZ - EndOfLog.xrecoff % BLCKSZ) < SizeOfXLogRecord)
|
||||
EndOfLog.xrecoff += (BLCKSZ - EndOfLog.xrecoff % BLCKSZ);
|
||||
@@ -2602,9 +2596,7 @@ StartupXLOG(void)
|
||||
NewPageEndPtr.xrecoff = BLCKSZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewPageEndPtr.xrecoff += BLCKSZ;
|
||||
}
|
||||
XLogCtl->xlblocks[0] = NewPageEndPtr;
|
||||
Insert->currpage->xlp_magic = XLOG_PAGE_MAGIC;
|
||||
if (InRecovery)
|
||||
@@ -2621,9 +2613,10 @@ StartupXLOG(void)
|
||||
XLogCtl->xlblocks[0].xlogid = openLogId;
|
||||
XLogCtl->xlblocks[0].xrecoff =
|
||||
((EndOfLog.xrecoff - 1) / BLCKSZ + 1) * BLCKSZ;
|
||||
|
||||
/*
|
||||
* Tricky point here: readBuf contains the *last* block that the
|
||||
* LastRec record spans, not the one it starts in. The last block
|
||||
* LastRec record spans, not the one it starts in. The last block
|
||||
* is indeed the one we want to use.
|
||||
*/
|
||||
Assert(readOff == (XLogCtl->xlblocks[0].xrecoff - BLCKSZ) % XLogSegSize);
|
||||
@@ -2670,7 +2663,6 @@ StartupXLOG(void)
|
||||
|
||||
if (InRecovery)
|
||||
{
|
||||
|
||||
/*
|
||||
* In case we had to use the secondary checkpoint, make sure that
|
||||
* it will still be shown as the secondary checkpoint after this
|
||||
@@ -2748,8 +2740,8 @@ ReadCheckpointRecord(XLogRecPtr RecPtr,
|
||||
if (record->xl_rmid != RM_XLOG_ID)
|
||||
{
|
||||
elog(LOG, (whichChkpt == 1 ?
|
||||
"invalid resource manager id in primary checkpoint record" :
|
||||
"invalid resource manager id in secondary checkpoint record"));
|
||||
"invalid resource manager id in primary checkpoint record" :
|
||||
"invalid resource manager id in secondary checkpoint record"));
|
||||
return NULL;
|
||||
}
|
||||
if (record->xl_info != XLOG_CHECKPOINT_SHUTDOWN &&
|
||||
@@ -2845,11 +2837,11 @@ CreateCheckPoint(bool shutdown)
|
||||
|
||||
/*
|
||||
* The CheckpointLock can be held for quite a while, which is not good
|
||||
* because we won't respond to a cancel/die request while waiting for an
|
||||
* LWLock. (But the alternative of using a regular lock won't work for
|
||||
* background checkpoint processes, which are not regular backends.)
|
||||
* So, rather than use a plain LWLockAcquire, use this kluge to allow
|
||||
* an interrupt to be accepted while we are waiting:
|
||||
* because we won't respond to a cancel/die request while waiting for
|
||||
* an LWLock. (But the alternative of using a regular lock won't work
|
||||
* for background checkpoint processes, which are not regular
|
||||
* backends.) So, rather than use a plain LWLockAcquire, use this
|
||||
* kluge to allow an interrupt to be accepted while we are waiting:
|
||||
*/
|
||||
while (!LWLockConditionalAcquire(CheckpointLock, LW_EXCLUSIVE))
|
||||
{
|
||||
@@ -2996,7 +2988,8 @@ CreateCheckPoint(bool shutdown)
|
||||
* but watch out for case that undo = 0.
|
||||
*
|
||||
* Without UNDO support: just use the redo pointer. This allows xlog
|
||||
* space to be freed much faster when there are long-running transactions.
|
||||
* space to be freed much faster when there are long-running
|
||||
* transactions.
|
||||
*/
|
||||
#ifdef NOT_USED
|
||||
if (ControlFile->checkPointCopy.undo.xrecoff != 0 &&
|
||||
@@ -3230,7 +3223,6 @@ assign_xlog_sync_method(const char *method)
|
||||
|
||||
if (sync_method != new_sync_method || open_sync_bit != new_sync_bit)
|
||||
{
|
||||
|
||||
/*
|
||||
* To ensure that no blocks escape unsynced, force an fsync on the
|
||||
* currently open log segment (if any). Also, if the open flag is
|
||||
@@ -3264,7 +3256,7 @@ issue_xlog_fsync(void)
|
||||
{
|
||||
switch (sync_method)
|
||||
{
|
||||
case SYNC_METHOD_FSYNC:
|
||||
case SYNC_METHOD_FSYNC:
|
||||
if (pg_fsync(openLogFile) != 0)
|
||||
elog(STOP, "fsync of log file %u, segment %u failed: %m",
|
||||
openLogId, openLogSeg);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlogutils.c,v 1.20 2001/10/05 17:28:11 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlogutils.c,v 1.21 2001/10/25 05:49:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -247,7 +247,7 @@ _xl_remove_hash_entry(XLogRelDesc *rdesc)
|
||||
rdesc->moreRecently->lessRecently = rdesc->lessRecently;
|
||||
|
||||
hentry = (XLogRelCacheEntry *) hash_search(_xlrelcache,
|
||||
(void *) &(rdesc->reldata.rd_node), HASH_REMOVE, NULL);
|
||||
(void *) &(rdesc->reldata.rd_node), HASH_REMOVE, NULL);
|
||||
if (hentry == NULL)
|
||||
elog(STOP, "_xl_remove_hash_entry: file was not found in cache");
|
||||
|
||||
@@ -304,9 +304,7 @@ XLogCloseRelationCache(void)
|
||||
hash_seq_init(&status, _xlrelcache);
|
||||
|
||||
while ((hentry = (XLogRelCacheEntry *) hash_seq_search(&status)) != NULL)
|
||||
{
|
||||
_xl_remove_hash_entry(hentry->rdesc);
|
||||
}
|
||||
|
||||
hash_destroy(_xlrelcache);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user