1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-10 17:42:29 +03:00
This commit is contained in:
Vadim B. Mikheev
2000-10-21 15:43:36 +00:00
parent 7c177a4908
commit a7fcadd10a
21 changed files with 1167 additions and 682 deletions

View File

@@ -1,4 +1,59 @@
#include "postgres.h"
#include "access/rmgr.h"
#include "access/xlog.h"
RmgrData *RmgrTable = NULL;
#ifdef XLOG
extern void xlog_redo(XLogRecPtr lsn, XLogRecord *rptr);
extern void xlog_undo(XLogRecPtr lsn, XLogRecord *rptr);
extern void xlog_desc(char *buf, uint8 xl_info, char* rec);
extern void xact_redo(XLogRecPtr lsn, XLogRecord *rptr);
extern void xact_undo(XLogRecPtr lsn, XLogRecord *rptr);
extern void xact_desc(char *buf, uint8 xl_info, char* rec);
extern void smgr_redo(XLogRecPtr lsn, XLogRecord *rptr);
extern void smgr_undo(XLogRecPtr lsn, XLogRecord *rptr);
extern void smgr_desc(char *buf, uint8 xl_info, char* rec);
extern void heap_redo(XLogRecPtr lsn, XLogRecord *rptr);
extern void heap_undo(XLogRecPtr lsn, XLogRecord *rptr);
extern void heap_desc(char *buf, uint8 xl_info, char* rec);
extern void btree_redo(XLogRecPtr lsn, XLogRecord *rptr);
extern void btree_undo(XLogRecPtr lsn, XLogRecord *rptr);
extern void btree_desc(char *buf, uint8 xl_info, char* rec);
extern void hash_redo(XLogRecPtr lsn, XLogRecord *rptr);
extern void hash_undo(XLogRecPtr lsn, XLogRecord *rptr);
extern void hash_desc(char *buf, uint8 xl_info, char* rec);
extern void rtree_redo(XLogRecPtr lsn, XLogRecord *rptr);
extern void rtree_undo(XLogRecPtr lsn, XLogRecord *rptr);
extern void rtree_desc(char *buf, uint8 xl_info, char* rec);
extern void gist_redo(XLogRecPtr lsn, XLogRecord *rptr);
extern void gist_undo(XLogRecPtr lsn, XLogRecord *rptr);
extern void gist_desc(char *buf, uint8 xl_info, char* rec);
RmgrData RmgrTable[] = {
{"XLOG", xlog_redo, xlog_undo, xlog_desc},
{"Transaction", xact_redo, xact_undo, xact_desc},
{"Storage", smgr_redo, smgr_undo, smgr_desc},
{"Reserved 3", NULL, NULL, NULL},
{"Reserved 4", NULL, NULL, NULL},
{"Reserved 5", NULL, NULL, NULL},
{"Reserved 6", NULL, NULL, NULL},
{"Reserved 7", NULL, NULL, NULL},
{"Reserved 8", NULL, NULL, NULL},
{"Reserved 9", NULL, NULL, NULL},
{"Heap", heap_redo, heap_undo, heap_desc},
{"Btree", btree_redo, btree_undo, btree_desc},
{"Hash", hash_redo, hash_undo, hash_desc},
{"Rtree", rtree_redo, rtree_undo, rtree_desc},
{"Gist", gist_redo, gist_undo, gist_desc}
};
#else
RmgrData RmgrTable[] = {};
#endif

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.73 2000/10/20 11:01:04 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.74 2000/10/21 15:43:22 vadim Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
@@ -224,6 +224,7 @@ int CommitDelay;
void xact_redo(XLogRecPtr lsn, XLogRecord *record);
void xact_undo(XLogRecPtr lsn, XLogRecord *record);
void xact_desc(char *buf, uint8 xl_info, char* rec);
static void (*_RollbackFunc)(void*) = NULL;
static void *_RollbackData = NULL;
@@ -692,6 +693,7 @@ RecordTransactionCommit()
TransactionIdCommit(xid);
#ifdef XLOG
if (MyLastRecPtr.xlogid != 0 || MyLastRecPtr.xrecoff != 0)
{
xl_xact_commit xlrec;
struct timeval delay;
@@ -711,6 +713,9 @@ RecordTransactionCommit()
delay.tv_sec = 0;
delay.tv_usec = CommitDelay;
(void) select(0, NULL, NULL, NULL, &delay);
XLogFlush(recptr);
MyLastRecPtr.xlogid = 0;
MyLastRecPtr.xrecoff = 0;
}
#endif
/*
@@ -823,7 +828,7 @@ RecordTransactionAbort()
TransactionIdAbort(xid);
#ifdef XLOG
if (SharedBufferChanged)
if (MyLastRecPtr.xlogid != 0 || MyLastRecPtr.xrecoff != 0)
{
xl_xact_abort xlrec;
XLogRecPtr recptr;
@@ -1176,6 +1181,8 @@ AbortTransaction()
AtEOXact_Files();
/* Here we'll rollback xaction changes */
MyLastRecPtr.xlogid = 0;
MyLastRecPtr.xrecoff = 0;
AtAbort_Locks();
@@ -1748,6 +1755,33 @@ xact_undo(XLogRecPtr lsn, XLogRecord *record)
else if (info != XLOG_XACT_ABORT)
elog(STOP, "xact_redo: unknown op code %u", info);
}
void
xact_desc(char *buf, uint8 xl_info, char* rec)
{
uint8 info = xl_info & ~XLR_INFO_MASK;
if (info == XLOG_XACT_COMMIT)
{
xl_xact_commit *xlrec = (xl_xact_commit*) rec;
struct tm *tm = localtime(&xlrec->xtime);
sprintf(buf + strlen(buf), "commit: %04u-%02u-%02u %02u:%02u:%02u",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
else if (info == XLOG_XACT_ABORT)
{
xl_xact_abort *xlrec = (xl_xact_abort*) rec;
struct tm *tm = localtime(&xlrec->xtime);
sprintf(buf + strlen(buf), "abort: %04u-%02u-%02u %02u:%02u:%02u",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
else
strcat(buf, "UNKNOWN");
}
void
XactPushRollback(void (*func) (void *), void* data)

View File

@@ -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.18 2000/10/20 11:01:04 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.19 2000/10/21 15:43:22 vadim Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,6 +27,8 @@
#include "storage/spin.h"
#include "storage/s_lock.h"
#include "miscadmin.h"
void UpdateControlFile(void);
int XLOGShmemSize(void);
void XLOGShmemInit(void);
@@ -41,6 +43,9 @@ uint32 XLOGbuffers = 0;
XLogRecPtr MyLastRecPtr = {0, 0};
bool StopIfError = false;
bool InRecovery = false;
StartUpID ThisStartUpID = 0;
int XLOG_DEBUG = 1;
SPINLOCK ControlFileLockId;
SPINLOCK XidGenLockId;
@@ -93,6 +98,7 @@ typedef struct XLogCtlData
XLogRecPtr *xlblocks; /* 1st byte ptr-s + BLCKSZ */
uint32 XLogCacheByte;
uint32 XLogCacheBlck;
StartUpID ThisStartUpID;
#ifdef HAS_TEST_AND_SET
slock_t insert_lck;
slock_t info_lck;
@@ -137,16 +143,20 @@ static ControlFileData *ControlFile = NULL;
typedef struct CheckPoint
{
XLogRecPtr redo; /* next RecPtr available when we */
/* began to create CheckPoint */
/* (i.e. REDO start point) */
XLogRecPtr undo; /* first record of oldest in-progress */
/* transaction when we started */
/* (i.e. UNDO end point) */
TransactionId nextXid;
Oid nextOid;
XLogRecPtr redo; /* next RecPtr available when we */
/* began to create CheckPoint */
/* (i.e. REDO start point) */
XLogRecPtr undo; /* first record of oldest in-progress */
/* transaction when we started */
/* (i.e. UNDO end point) */
StartUpID ThisStartUpID;
TransactionId nextXid;
Oid nextOid;
bool Shutdown;
} CheckPoint;
#define XLOG_CHECKPOINT 0x00
/*
* We break each log file in 16Mb segments
*/
@@ -190,6 +200,7 @@ static int XLogFileInit(uint32 log, uint32 seg);
static int XLogFileOpen(uint32 log, uint32 seg, bool econt);
static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, char *buffer);
static char *str_time(time_t tnow);
static void xlog_outrec(char *buf, XLogRecord *record);
static XLgwrResult LgwrResult = {{0, 0}, {0, 0}};
static XLgwrRqst LgwrRqst = {{0, 0}, {0, 0}};
@@ -225,6 +236,13 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32
if (len == 0 || len > MAXLOGRECSZ)
elog(STOP, "XLogInsert: invalid record len %u", len);
if (IsBootstrapProcessingMode())
{
RecPtr.xlogid = 0;
RecPtr.xrecoff = SizeOfXLogPHD; /* start of 1st checkpoint record */
return (RecPtr);
}
/* obtain xlog insert lock */
if (TAS(&(XLogCtl->insert_lck))) /* busy */
{
@@ -310,6 +328,23 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32
MyProc->logRec = RecPtr;
SpinRelease(SInvalLock);
}
Insert->PrevRecord = RecPtr;
if (XLOG_DEBUG)
{
char buf[8192];
sprintf(buf, "INSERT @ %u/%u: ", RecPtr.xlogid, RecPtr.xrecoff);
xlog_outrec(buf, record);
if (hdr != NULL)
{
strcat(buf, " - ");
RmgrTable[record->xl_rmid].rm_desc(buf, record->xl_info, hdr);
}
strcat(buf, "\n");
write(2, buf, strlen(buf));
}
MyLastRecPtr = RecPtr; /* begin of record */
Insert->currpos += SizeOfXLogRecord;
if (freespace > 0)
@@ -330,7 +365,7 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32
Insert->currpos += wlen;
}
Insert->currpos = ((char *) Insert->currpage) +
DOUBLEALIGN(Insert->currpos - ((char *) Insert->currpage));
MAXALIGN(Insert->currpos - ((char *) Insert->currpage));
len = hdrlen + buflen;
}
@@ -391,7 +426,7 @@ nbuf:
/* we don't store info in subrecord' xl_info */
subrecord->xl_info = 0;
Insert->currpos = ((char *) Insert->currpage) +
DOUBLEALIGN(Insert->currpos - ((char *) Insert->currpage));
MAXALIGN(Insert->currpos - ((char *) Insert->currpage));
}
freespace = ((char *) Insert->currpage) + BLCKSZ - Insert->currpos;
@@ -738,7 +773,7 @@ XLogFileInit(uint32 log, uint32 seg)
fd = BasicOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, S_IRUSR | S_IWUSR);
if (fd < 0)
elog(STOP, "Open(logfile %u seg %u) failed: %d",
elog(STOP, "Init(logfile %u seg %u) failed: %d",
logId, logSeg, errno);
if (lseek(fd, XLogSegSize - 1, SEEK_SET) != (off_t) (XLogSegSize - 1))
@@ -777,6 +812,7 @@ XLogFileOpen(uint32 log, uint32 seg, bool econt)
logId, logSeg);
return (fd);
}
abort();
elog(STOP, "Open(logfile %u seg %u) failed: %d",
logId, logSeg, errno);
}
@@ -876,7 +912,7 @@ got_record:;
XLogSubRecord *subrecord;
uint32 len = record->xl_len;
if (DOUBLEALIGN(record->xl_len) + RecPtr->xrecoff % BLCKSZ +
if (MAXALIGN(record->xl_len) + RecPtr->xrecoff % BLCKSZ +
SizeOfXLogRecord != BLCKSZ)
{
elog(emode, "ReadRecord: invalid fragmented record len %u in (%u, %u)",
@@ -938,7 +974,7 @@ got_record:;
buffer += subrecord->xl_len;
if (subrecord->xl_info & XLR_TO_BE_CONTINUED)
{
if (DOUBLEALIGN(subrecord->xl_len) +
if (MAXALIGN(subrecord->xl_len) +
SizeOfXLogPHD + SizeOfXLogSubRecord != BLCKSZ)
{
elog(emode, "ReadRecord: invalid fragmented subrecord len %u in logfile %u seg %u off %u",
@@ -949,26 +985,26 @@ got_record:;
}
break;
}
if (BLCKSZ - SizeOfXLogRecord >= DOUBLEALIGN(subrecord->xl_len) +
if (BLCKSZ - SizeOfXLogRecord >= MAXALIGN(subrecord->xl_len) +
SizeOfXLogPHD + SizeOfXLogSubRecord)
{
nextRecord = (XLogRecord *) ((char *) subrecord +
DOUBLEALIGN(subrecord->xl_len) + SizeOfXLogSubRecord);
MAXALIGN(subrecord->xl_len) + SizeOfXLogSubRecord);
}
EndRecPtr.xlogid = readId;
EndRecPtr.xrecoff = readSeg * XLogSegSize + readOff * BLCKSZ +
SizeOfXLogPHD + SizeOfXLogSubRecord +
DOUBLEALIGN(subrecord->xl_len);
MAXALIGN(subrecord->xl_len);
ReadRecPtr = *RecPtr;
return (record);
}
if (BLCKSZ - SizeOfXLogRecord >= DOUBLEALIGN(record->xl_len) +
if (BLCKSZ - SizeOfXLogRecord >= MAXALIGN(record->xl_len) +
RecPtr->xrecoff % BLCKSZ + SizeOfXLogRecord)
nextRecord = (XLogRecord *) ((char *) record +
DOUBLEALIGN(record->xl_len) + SizeOfXLogRecord);
MAXALIGN(record->xl_len) + SizeOfXLogRecord);
EndRecPtr.xlogid = RecPtr->xlogid;
EndRecPtr.xrecoff = RecPtr->xrecoff +
DOUBLEALIGN(record->xl_len) + SizeOfXLogRecord;
MAXALIGN(record->xl_len) + SizeOfXLogRecord;
ReadRecPtr = *RecPtr;
return (record);
@@ -1130,7 +1166,7 @@ BootStrapXLOG()
char buffer[BLCKSZ];
CheckPoint checkPoint;
#ifdef NOT_USED
#ifdef XLOG
XLogPageHeader page = (XLogPageHeader) buffer;
XLogRecord *record;
@@ -1146,8 +1182,9 @@ BootStrapXLOG()
checkPoint.undo = checkPoint.redo;
checkPoint.nextXid = FirstTransactionId;
checkPoint.nextOid = BootstrapObjectIdData;
checkPoint.ThisStartUpID = 0;
#ifdef NOT_USED
#ifdef XLOG
memset(buffer, 0, BLCKSZ);
page->xlp_magic = XLOG_PAGE_MAGIC;
@@ -1213,7 +1250,7 @@ str_time(time_t tnow)
void
StartupXLOG()
{
#ifdef NOT_USED
#ifdef XLOG
XLogCtlInsert *Insert;
CheckPoint checkPoint;
XLogRecPtr RecPtr,
@@ -1291,7 +1328,7 @@ StartupXLOG()
elog(LOG, "Data Base System was interrupted being in production at %s",
str_time(ControlFile->time));
#ifdef NOT_USED
#ifdef XLOG
LastRec = RecPtr = ControlFile->checkPoint;
if (!XRecOffIsValid(RecPtr.xrecoff))
@@ -1312,17 +1349,20 @@ StartupXLOG()
checkPoint.nextXid, checkPoint.nextOid);
if (checkPoint.nextXid < FirstTransactionId ||
checkPoint.nextOid < BootstrapObjectIdData)
#ifdef XLOG
#ifdef XLOG_2
elog(STOP, "Invalid NextTransactionId/NextOid");
#else
elog(LOG, "Invalid NextTransactionId/NextOid");
#endif
#ifdef XLOG
#ifdef XLOG_2
ShmemVariableCache->nextXid = checkPoint.nextXid;
ShmemVariableCache->nextOid = checkPoint.nextOid;
#endif
ThisStartUpID = checkPoint.ThisStartUpID;
if (XLByteLT(RecPtr, checkPoint.redo))
elog(STOP, "Invalid redo in checkPoint record");
if (checkPoint.undo.xrecoff == 0)
@@ -1364,10 +1404,23 @@ StartupXLOG()
ReadRecPtr.xlogid, ReadRecPtr.xrecoff);
do
{
#ifdef XLOG
#ifdef XLOG_2
if (record->xl_xid >= ShmemVariableCache->nextXid)
ShmemVariableCache->nextXid = record->xl_xid + 1;
#endif
if (XLOG_DEBUG)
{
char buf[8192];
sprintf(buf, "REDO @ %u/%u: ", ReadRecPtr.xlogid, ReadRecPtr.xrecoff);
xlog_outrec(buf, record);
strcat(buf, " - ");
RmgrTable[record->xl_rmid].rm_desc(buf,
record->xl_info, XLogRecGetData(record));
strcat(buf, "\n");
write(2, buf, strlen(buf));
}
RmgrTable[record->xl_rmid].rm_redo(EndRecPtr, record);
record = ReadRecord(NULL, buffer);
} while (record->xl_len != 0);
@@ -1422,6 +1475,7 @@ StartupXLOG()
if (recovery > 0)
{
#ifdef NOT_USED
int i;
/*
@@ -1429,21 +1483,37 @@ StartupXLOG()
*/
for (i = 0; i <= RM_MAX_ID; i++)
RmgrTable[record->xl_rmid].rm_redo(ReadRecPtr, NULL);
#endif
CreateCheckPoint(true);
StopIfError = sie_saved;
}
#endif /* NOT_USED */
#endif /* XLOG */
ControlFile->state = DB_IN_PRODUCTION;
ControlFile->time = time(NULL);
UpdateControlFile();
ThisStartUpID++;
XLogCtl->ThisStartUpID = ThisStartUpID;
elog(LOG, "Data Base System is in production state at %s", str_time(time(NULL)));
return;
}
/*
* Postmaster uses it to set ThisStartUpID from XLogCtlData
* located in shmem after successful startup.
*/
void SetThisStartUpID(void);
void
SetThisStartUpID(void)
{
ThisStartUpID = XLogCtl->ThisStartUpID;
}
/*
* This func must be called ONCE on system shutdown
*/
@@ -1461,7 +1531,7 @@ ShutdownXLOG()
void
CreateCheckPoint(bool shutdown)
{
#ifdef NOT_USED
#ifdef XLOG
CheckPoint checkPoint;
XLogRecPtr recptr;
XLogCtlInsert *Insert = &XLogCtl->Insert;
@@ -1475,6 +1545,8 @@ CreateCheckPoint(bool shutdown)
ControlFile->time = time(NULL);
UpdateControlFile();
}
checkPoint.ThisStartUpID = ThisStartUpID;
checkPoint.Shutdown = shutdown;
/* Get REDO record ptr */
while (TAS(&(XLogCtl->insert_lck)))
@@ -1517,20 +1589,21 @@ CreateCheckPoint(bool shutdown)
if (shutdown && checkPoint.undo.xrecoff != 0)
elog(STOP, "Active transaction while data base is shutting down");
recptr = XLogInsert(RM_XLOG_ID, (char *) &checkPoint, sizeof(checkPoint), NULL, 0);
recptr = XLogInsert(RM_XLOG_ID, XLOG_CHECKPOINT, (char *) &checkPoint,
sizeof(checkPoint), NULL, 0);
if (shutdown && !XLByteEQ(checkPoint.redo, MyLastRecPtr))
elog(STOP, "XLog concurrent activity while data base is shutting down");
XLogFlush(recptr);
#endif /* NOT_USED */
#endif /* XLOG */
SpinAcquire(ControlFileLockId);
if (shutdown)
ControlFile->state = DB_SHUTDOWNED;
#ifdef NOT_USED
#ifdef XLOG
ControlFile->checkPoint = MyLastRecPtr;
#else
ControlFile->checkPoint.xlogid = 0;
@@ -1543,3 +1616,47 @@ CreateCheckPoint(bool shutdown)
return;
}
void xlog_redo(XLogRecPtr lsn, XLogRecord *record);
void xlog_undo(XLogRecPtr lsn, XLogRecord *record);
void xlog_desc(char *buf, uint8 xl_info, char* rec);
void
xlog_redo(XLogRecPtr lsn, XLogRecord *record)
{
}
void
xlog_undo(XLogRecPtr lsn, XLogRecord *record)
{
}
void
xlog_desc(char *buf, uint8 xl_info, char* rec)
{
uint8 info = xl_info & ~XLR_INFO_MASK;
if (info == XLOG_CHECKPOINT)
{
CheckPoint *checkpoint = (CheckPoint*) rec;
sprintf(buf + strlen(buf), "checkpoint: redo %u/%u; undo %u/%u; "
"sui %u; xid %u; oid %u; %s",
checkpoint->redo.xlogid, checkpoint->redo.xrecoff,
checkpoint->undo.xlogid, checkpoint->undo.xrecoff,
checkpoint->ThisStartUpID, checkpoint->nextXid,
checkpoint->nextOid,
(checkpoint->Shutdown) ? "shutdown" : "online");
}
else
strcat(buf, "UNKNOWN");
}
static void
xlog_outrec(char *buf, XLogRecord *record)
{
sprintf(buf + strlen(buf), "prev %u/%u; xprev %u/%u; xid %u: %s",
record->xl_prev.xlogid, record->xl_prev.xrecoff,
record->xl_xact_prev.xlogid, record->xl_xact_prev.xrecoff,
record->xl_xid,
RmgrTable[record->xl_rmid].rm_name);
}

View File

@@ -276,6 +276,9 @@ _xl_init_rel_cache(void)
_xlpgcarr = (Form_pg_class) malloc(sizeof(FormData_pg_class) * _xlcnt);
memset(_xlpgcarr, 0, sizeof(XLogRelDesc) * _xlcnt);
_xlrelarr[0].moreRecently = &(_xlrelarr[0]);
_xlrelarr[0].lessRecently = &(_xlrelarr[0]);
memset(&ctl, 0, (int) sizeof(ctl));
ctl.keysize = sizeof(RelFileNode);
ctl.datasize = sizeof(XLogRelDesc*);
@@ -383,6 +386,7 @@ XLogOpenRelation(bool redo, RmgrId rmid, RelFileNode rnode)
hentry->rdesc = res;
res->reldata.rd_unlinked = true; /* look smgropen */
res->reldata.rd_fd = -1;
res->reldata.rd_fd = smgropen(DEFAULT_SMGR, &(res->reldata));
}