mirror of
https://github.com/postgres/postgres.git
synced 2025-11-09 06:21:09 +03:00
Transaction IDs wrap around, per my proposal of 13-Aug-01. More
documentation to come, but the code is all here. initdb forced.
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.2 2001/08/25 23:24:39 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/clog.c,v 1.3 2001/08/26 16:55:59 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -762,8 +762,12 @@ ExtendCLOG(TransactionId newestXact)
|
||||
{
|
||||
int pageno;
|
||||
|
||||
/* No work except at first XID of a page */
|
||||
if (TransactionIdToPgIndex(newestXact) != 0)
|
||||
/*
|
||||
* 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);
|
||||
@@ -818,6 +822,18 @@ TruncateCLOG(TransactionId oldestXact)
|
||||
S_LOCK(&(ClogCtl->control_lck));
|
||||
|
||||
restart:;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (CLOGPagePrecedes(ClogCtl->latest_page_number, cutoffPage))
|
||||
{
|
||||
S_UNLOCK(&(ClogCtl->control_lck));
|
||||
elog(LOG, "unable to truncate commit log: apparent wraparound");
|
||||
return;
|
||||
}
|
||||
|
||||
for (slotno = 0; slotno < NUM_CLOG_BUFFERS; slotno++)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.47 2001/08/25 18:52:41 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.48 2001/08/26 16:55:59 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* This file contains the high level access-method interface to the
|
||||
@@ -236,3 +236,68 @@ TransactionIdAbort(TransactionId transactionId)
|
||||
|
||||
TransactionLogUpdate(transactionId, TRANSACTION_STATUS_ABORTED);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* TransactionIdPrecedes --- is id1 logically < id2?
|
||||
*/
|
||||
bool
|
||||
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.
|
||||
*/
|
||||
int32 diff;
|
||||
|
||||
if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
|
||||
return (id1 < id2);
|
||||
|
||||
diff = (int32) (id1 - id2);
|
||||
return (diff < 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* TransactionIdPrecedesOrEquals --- is id1 logically <= id2?
|
||||
*/
|
||||
bool
|
||||
TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)
|
||||
{
|
||||
int32 diff;
|
||||
|
||||
if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
|
||||
return (id1 <= id2);
|
||||
|
||||
diff = (int32) (id1 - id2);
|
||||
return (diff <= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* TransactionIdFollows --- is id1 logically > id2?
|
||||
*/
|
||||
bool
|
||||
TransactionIdFollows(TransactionId id1, TransactionId id2)
|
||||
{
|
||||
int32 diff;
|
||||
|
||||
if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
|
||||
return (id1 > id2);
|
||||
|
||||
diff = (int32) (id1 - id2);
|
||||
return (diff > 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* TransactionIdFollowsOrEquals --- is id1 logically >= id2?
|
||||
*/
|
||||
bool
|
||||
TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
|
||||
{
|
||||
int32 diff;
|
||||
|
||||
if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
|
||||
return (id1 >= id2);
|
||||
|
||||
diff = (int32) (id1 - id2);
|
||||
return (diff >= 0);
|
||||
}
|
||||
|
||||
@@ -6,23 +6,18 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: xid.c,v 1.32 2001/08/23 23:06:37 tgl Exp $
|
||||
*
|
||||
* OLD COMMENTS
|
||||
* XXX WARNING
|
||||
* Much of this file will change when we change our representation
|
||||
* of transaction ids -cim 3/23/90
|
||||
*
|
||||
* It is time to make the switch from 5 byte to 4 byte transaction ids
|
||||
* This file was totally reworked. -mer 5/22/92
|
||||
* $Id: xid.c,v 1.33 2001/08/26 16:55:59 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "access/xact.h"
|
||||
|
||||
|
||||
#define PG_GETARG_TRANSACTIONID(n) DatumGetTransactionId(PG_GETARG_DATUM(n))
|
||||
#define PG_RETURN_TRANSACTIONID(x) return TransactionIdGetDatum(x)
|
||||
|
||||
@@ -30,9 +25,9 @@
|
||||
Datum
|
||||
xidin(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *representation = PG_GETARG_CSTRING(0);
|
||||
char *str = PG_GETARG_CSTRING(0);
|
||||
|
||||
PG_RETURN_TRANSACTIONID((TransactionId) atol(representation));
|
||||
PG_RETURN_TRANSACTIONID((TransactionId) strtoul(str, NULL, 0));
|
||||
}
|
||||
|
||||
Datum
|
||||
@@ -40,21 +35,15 @@ xidout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
|
||||
/* maximum 32 bit unsigned integer representation takes 10 chars */
|
||||
char *representation = palloc(11);
|
||||
char *str = palloc(11);
|
||||
|
||||
snprintf(representation, 11, "%lu", (unsigned long) transactionId);
|
||||
snprintf(str, 11, "%lu", (unsigned long) transactionId);
|
||||
|
||||
PG_RETURN_CSTRING(representation);
|
||||
PG_RETURN_CSTRING(str);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* xideq
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* xideq - returns 1, iff xid1 == xid2
|
||||
* 0 else;
|
||||
* xideq - are two xids equal?
|
||||
*/
|
||||
Datum
|
||||
xideq(PG_FUNCTION_ARGS)
|
||||
@@ -64,3 +53,19 @@ xideq(PG_FUNCTION_ARGS)
|
||||
|
||||
PG_RETURN_BOOL(TransactionIdEquals(xid1, xid2));
|
||||
}
|
||||
|
||||
/*
|
||||
* xid_age - compute age of an XID (relative to current xact)
|
||||
*/
|
||||
Datum
|
||||
xid_age(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TransactionId xid = PG_GETARG_TRANSACTIONID(0);
|
||||
TransactionId now = GetCurrentTransactionId();
|
||||
|
||||
/* Permanent XIDs are always infinitely old */
|
||||
if (! TransactionIdIsNormal(xid))
|
||||
PG_RETURN_INT32(INT_MAX);
|
||||
|
||||
PG_RETURN_INT32((int32) (now - xid));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user