diff --git a/src/backend/access/transam/transam.c b/src/backend/access/transam/transam.c index 52a3906ba6..b56dcd0c50 100644 --- a/src/backend/access/transam/transam.c +++ b/src/backend/access/transam/transam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.35 2000/08/03 19:18:55 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.36 2000/11/03 11:39:35 vadim Exp $ * * NOTES * This file contains the high level access-method interface to the @@ -83,6 +83,10 @@ int RecoveryCheckingEnableState = 0; */ extern int OidGenLockId; +#ifdef XLOG +#include "miscadmin.h" +extern VariableCache ShmemVariableCache; +#endif /* ---------------- * recovery checking accessors @@ -438,7 +442,13 @@ InitializeTransactionLog(void) TransactionLogUpdate(AmiTransactionId, XID_COMMIT); TransactionIdStore(AmiTransactionId, &cachedTestXid); cachedTestXidStatus = XID_COMMIT; +#ifdef XLOG + Assert(!IsUnderPostmaster && + ShmemVariableCache->nextXid <= FirstTransactionId); + ShmemVariableCache->nextXid = FirstTransactionId; +#else VariableRelationPutNextXid(FirstTransactionId); +#endif } else if (RecoveryCheckingEnabled()) diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 49c82b5570..f29b41d749 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -8,10 +8,15 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.30 2000/10/28 16:20:53 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.31 2000/11/03 11:39:35 vadim Exp $ * *------------------------------------------------------------------------- */ +#ifdef XLOG + +#include "xlog_varsup.c" + +#else #include "postgres.h" @@ -125,11 +130,7 @@ VariableRelationPutNextXid(TransactionId xid) TransactionIdStore(xid, &(var->nextXidData)); -#ifdef XLOG - WriteBuffer(buf); /* temp */ -#else FlushBuffer(buf, TRUE); -#endif } /* -------------------------------- @@ -520,3 +521,5 @@ CheckMaxObjectId(Oid assigned_oid) prefetched_oid_count = 0; /* force reload */ GetNewObjectId(&temp_oid); /* cause target OID to be allocated */ } + +#endif /* !XLOG */ diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index aa952a42ab..13dba31918 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.22 2000/10/28 16:20:54 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.23 2000/11/03 11:39:35 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -157,6 +157,7 @@ typedef struct CheckPoint } CheckPoint; #define XLOG_CHECKPOINT 0x00 +#define XLOG_NEXTOID 0x10 /* * We break each log file in 16Mb segments @@ -1373,10 +1374,9 @@ StartupXLOG() elog(LOG, "Invalid NextTransactionId/NextOid"); #endif -#ifdef XLOG_2 ShmemVariableCache->nextXid = checkPoint.nextXid; ShmemVariableCache->nextOid = checkPoint.nextOid; -#endif + ShmemVariableCache->oidCount = 0; ThisStartUpID = checkPoint.ThisStartUpID; @@ -1430,10 +1430,8 @@ StartupXLOG() ReadRecPtr.xlogid, ReadRecPtr.xrecoff); do { -#ifdef XLOG_2 if (record->xl_xid >= ShmemVariableCache->nextXid) ShmemVariableCache->nextXid = record->xl_xid + 1; -#endif if (XLOG_DEBUG) { char buf[8192]; @@ -1609,6 +1607,9 @@ CreateCheckPoint(bool shutdown) SpinRelease(XidGenLockId); SpinAcquire(OidGenLockId); checkPoint.nextOid = ShmemVariableCache->nextOid; + if (!shutdown) + checkPoint.nextOid += ShmemVariableCache->oidCount; + SpinRelease(OidGenLockId); FlushBufferPool(); @@ -1647,6 +1648,15 @@ CreateCheckPoint(bool shutdown) return; } +void XLogPutNextOid(Oid nextOid); + +void +XLogPutNextOid(Oid nextOid) +{ + (void) XLogInsert(RM_XLOG_ID, XLOG_NEXTOID, + (char *) &nextOid, sizeof(Oid), NULL, 0); +} + void xlog_redo(XLogRecPtr lsn, XLogRecord *record); void xlog_undo(XLogRecPtr lsn, XLogRecord *record); void xlog_desc(char *buf, uint8 xl_info, char* rec); @@ -1654,6 +1664,16 @@ void xlog_desc(char *buf, uint8 xl_info, char* rec); void xlog_redo(XLogRecPtr lsn, XLogRecord *record) { + uint8 info = record->xl_info & ~XLR_INFO_MASK; + + if (info == XLOG_NEXTOID) + { + Oid nextOid; + + memcpy(&nextOid, XLogRecGetData(record), sizeof(Oid)); + if (ShmemVariableCache->nextOid < nextOid) + ShmemVariableCache->nextOid = nextOid; + } } void @@ -1677,6 +1697,13 @@ xlog_desc(char *buf, uint8 xl_info, char* rec) checkpoint->nextOid, (checkpoint->Shutdown) ? "shutdown" : "online"); } + else if (info == XLOG_NEXTOID) + { + Oid nextOid; + + memcpy(&nextOid, rec, sizeof(Oid)); + sprintf(buf + strlen(buf), "nextOid: %u", nextOid); + } else strcat(buf, "UNKNOWN"); } diff --git a/src/backend/access/transam/xlog_varsup.c b/src/backend/access/transam/xlog_varsup.c new file mode 100644 index 0000000000..fd64085e78 --- /dev/null +++ b/src/backend/access/transam/xlog_varsup.c @@ -0,0 +1,142 @@ +/*------------------------------------------------------------------------- + * + * varsup.c + * postgres OID & XID variables support routines + * + * Copyright (c) 2000, PostgreSQL, Inc + * + * IDENTIFICATION + * $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/xlog_varsup.c,v 1.1 2000/11/03 11:39:35 vadim Exp $ + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/transam.h" +#include "storage/proc.h" + +SPINLOCK OidGenLockId; + +extern SPINLOCK XidGenLockId; +extern void XLogPutNextOid(Oid nextOid); + +/* pointer to "variable cache" in shared memory (set up by shmem.c) */ +VariableCache ShmemVariableCache = NULL; + +void +GetNewTransactionId(TransactionId *xid) +{ + /* + * During bootstrap initialization, we return the special + * bootstrap transaction id. + */ + if (AMI_OVERRIDE) + { + *xid = AmiTransactionId; + return; + } + + SpinAcquire(XidGenLockId); + *xid = ShmemVariableCache->nextXid; + (ShmemVariableCache->nextXid)++; + + if (MyProc != (PROC *) NULL) + MyProc->xid = *xid; + + SpinRelease(XidGenLockId); + +} + +/* + * Like GetNewTransactionId reads nextXid but don't fetch it. + */ +void +ReadNewTransactionId(TransactionId *xid) +{ + + /* + * During bootstrap initialization, we return the special + * bootstrap transaction id. + */ + if (AMI_OVERRIDE) + { + *xid = AmiTransactionId; + return; + } + + SpinAcquire(XidGenLockId); + *xid = ShmemVariableCache->nextXid; + SpinRelease(XidGenLockId); + +} + +/* ---------------------------------------------------------------- + * object id generation support + * ---------------------------------------------------------------- + */ + +#define VAR_OID_PREFETCH 8192 +static Oid lastSeenOid = InvalidOid; + +void +GetNewObjectId(Oid *oid_return) +{ + SpinAcquire(OidGenLockId); + + /* If we run out of logged for use oids then we log more */ + if (ShmemVariableCache->oidCount == 0) + { + XLogPutNextOid(ShmemVariableCache->nextOid + VAR_OID_PREFETCH); + ShmemVariableCache->oidCount = VAR_OID_PREFETCH; + } + + if (PointerIsValid(oid_return)) + lastSeenOid = (*oid_return) = ShmemVariableCache->nextOid; + + (ShmemVariableCache->nextOid)++; + (ShmemVariableCache->oidCount)--; + + SpinRelease(OidGenLockId); +} + +void +CheckMaxObjectId(Oid assigned_oid) +{ + + if (lastSeenOid != InvalidOid && assigned_oid < lastSeenOid) + return; + + SpinAcquire(OidGenLockId); + if (assigned_oid < ShmemVariableCache->nextOid) + { + lastSeenOid = ShmemVariableCache->nextOid - 1; + SpinRelease(OidGenLockId); + return; + } + + /* If we are in the logged oid range, just bump nextOid up */ + if (assigned_oid <= ShmemVariableCache->nextOid + + ShmemVariableCache->oidCount - 1) + { + ShmemVariableCache->oidCount -= + assigned_oid - ShmemVariableCache->nextOid + 1; + ShmemVariableCache->nextOid = assigned_oid + 1; + SpinRelease(OidGenLockId); + return; + } + + /* + * We have exceeded the logged oid range. + * We should lock the database and kill all other backends + * but we are loading oid's that we can not guarantee are unique + * anyway, so we must rely on the user. + */ + + XLogPutNextOid(assigned_oid + VAR_OID_PREFETCH); + ShmemVariableCache->oidCount = VAR_OID_PREFETCH - 1; + ShmemVariableCache->nextOid = assigned_oid + 1; + + SpinRelease(OidGenLockId); + +} diff --git a/src/include/access/transam.h b/src/include/access/transam.h index 415ad56b95..86fed998a4 100644 --- a/src/include/access/transam.h +++ b/src/include/access/transam.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: transam.h,v 1.25 2000/10/28 16:20:59 vadim Exp $ + * $Id: transam.h,v 1.26 2000/11/03 11:39:36 vadim Exp $ * * NOTES * Transaction System Version 101 now support proper oid @@ -136,10 +136,12 @@ typedef VariableRelationContentsData *VariableRelationContents; */ typedef struct VariableCacheData { +#ifndef XLOG uint32 xid_count; +#endif TransactionId nextXid; - uint32 oid_count; /* not implemented, yet */ Oid nextOid; + uint32 oidCount; } VariableCacheData; typedef VariableCacheData *VariableCache;