1
0
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:
Tom Lane
2001-08-26 16:56:03 +00:00
parent d1ee78f296
commit bc7d37a525
29 changed files with 617 additions and 171 deletions

View File

@@ -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++)
{

View File

@@ -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);
}

View File

@@ -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));
}