Commit f0e37a85 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

New CHECKPOINT command.

Auto removing of offline log files and creating new file
at checkpoint time.
parent 7267fdd7
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.79 2000/10/29 18:33:41 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.80 2000/11/05 22:50:19 vadim Exp $
* *
* NOTES * NOTES
* Transaction aborts can now occur two ways: * Transaction aborts can now occur two ways:
...@@ -678,7 +678,7 @@ RecordTransactionCommit() ...@@ -678,7 +678,7 @@ RecordTransactionCommit()
leak = BufferPoolCheckLeak(); leak = BufferPoolCheckLeak();
#ifdef XLOG #ifdef XLOG
if (MyLastRecPtr.xlogid != 0 || MyLastRecPtr.xrecoff != 0) if (MyLastRecPtr.xrecoff != 0)
{ {
xl_xact_commit xlrec; xl_xact_commit xlrec;
struct timeval delay; struct timeval delay;
...@@ -701,7 +701,6 @@ RecordTransactionCommit() ...@@ -701,7 +701,6 @@ RecordTransactionCommit()
delay.tv_usec = CommitDelay; delay.tv_usec = CommitDelay;
(void) select(0, NULL, NULL, NULL, &delay); (void) select(0, NULL, NULL, NULL, &delay);
XLogFlush(recptr); XLogFlush(recptr);
MyLastRecPtr.xlogid = 0;
MyLastRecPtr.xrecoff = 0; MyLastRecPtr.xrecoff = 0;
TransactionIdCommit(xid); TransactionIdCommit(xid);
...@@ -836,7 +835,7 @@ RecordTransactionAbort(void) ...@@ -836,7 +835,7 @@ RecordTransactionAbort(void)
TransactionIdAbort(xid); TransactionIdAbort(xid);
#ifdef XLOG #ifdef XLOG
if (MyLastRecPtr.xlogid != 0 || MyLastRecPtr.xrecoff != 0) if (MyLastRecPtr.xrecoff != 0)
{ {
xl_xact_abort xlrec; xl_xact_abort xlrec;
XLogRecPtr recptr; XLogRecPtr recptr;
...@@ -844,6 +843,8 @@ RecordTransactionAbort(void) ...@@ -844,6 +843,8 @@ RecordTransactionAbort(void)
xlrec.xtime = time(NULL); xlrec.xtime = time(NULL);
recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT,
(char*) &xlrec, SizeOfXactAbort, NULL, 0); (char*) &xlrec, SizeOfXactAbort, NULL, 0);
MyProc->logRec.xrecoff = 0;
} }
#endif #endif
...@@ -1189,7 +1190,6 @@ AbortTransaction(void) ...@@ -1189,7 +1190,6 @@ AbortTransaction(void)
AtEOXact_Files(); AtEOXact_Files();
/* Here we'll rollback xaction changes */ /* Here we'll rollback xaction changes */
MyLastRecPtr.xlogid = 0;
MyLastRecPtr.xrecoff = 0; MyLastRecPtr.xrecoff = 0;
AtAbort_Locks(); AtAbort_Locks();
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.23 2000/11/03 11:39:35 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.24 2000/11/05 22:50:19 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <errno.h> #include <errno.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h>
#include <dirent.h>
#include "postgres.h" #include "postgres.h"
...@@ -48,7 +50,10 @@ StartUpID ThisStartUpID = 0; ...@@ -48,7 +50,10 @@ StartUpID ThisStartUpID = 0;
int XLOG_DEBUG = 1; int XLOG_DEBUG = 1;
/* To read/update control file and create new log file */
SPINLOCK ControlFileLockId; SPINLOCK ControlFileLockId;
/* To generate new xid */
SPINLOCK XidGenLockId; SPINLOCK XidGenLockId;
extern VariableCache ShmemVariableCache; extern VariableCache ShmemVariableCache;
...@@ -91,19 +96,20 @@ typedef struct XLogCtlWrite ...@@ -91,19 +96,20 @@ typedef struct XLogCtlWrite
typedef struct XLogCtlData typedef struct XLogCtlData
{ {
XLogCtlInsert Insert; XLogCtlInsert Insert;
XLgwrRqst LgwrRqst; XLgwrRqst LgwrRqst;
XLgwrResult LgwrResult; XLgwrResult LgwrResult;
XLogCtlWrite Write; XLogCtlWrite Write;
char *pages; char *pages;
XLogRecPtr *xlblocks; /* 1st byte ptr-s + BLCKSZ */ XLogRecPtr *xlblocks; /* 1st byte ptr-s + BLCKSZ */
uint32 XLogCacheByte; uint32 XLogCacheByte;
uint32 XLogCacheBlck; uint32 XLogCacheBlck;
StartUpID ThisStartUpID; StartUpID ThisStartUpID;
#ifdef HAS_TEST_AND_SET #ifdef HAS_TEST_AND_SET
slock_t insert_lck; slock_t insert_lck;
slock_t info_lck; slock_t info_lck;
slock_t lgwr_lck; slock_t lgwr_lck;
slock_t chkp_lck; /* checkpoint lock */
#endif #endif
} XLogCtlData; } XLogCtlData;
...@@ -133,6 +139,7 @@ typedef struct ControlFileData ...@@ -133,6 +139,7 @@ typedef struct ControlFileData
uint32 blcksz; /* block size for this DB */ uint32 blcksz; /* block size for this DB */
uint32 relseg_size; /* blocks per segment of large relation */ uint32 relseg_size; /* blocks per segment of large relation */
uint32 catalog_version_no; /* internal version number */ uint32 catalog_version_no; /* internal version number */
char archdir[MAXPGPATH]; /* where to move offline log files */
/* /*
* MORE DATA FOLLOWS AT THE END OF THIS STRUCTURE - locations of data * MORE DATA FOLLOWS AT THE END OF THIS STRUCTURE - locations of data
...@@ -170,6 +177,10 @@ typedef struct CheckPoint ...@@ -170,6 +177,10 @@ typedef struct CheckPoint
snprintf(path, MAXPGPATH, "%s%c%08X%08X", \ snprintf(path, MAXPGPATH, "%s%c%08X%08X", \
XLogDir, SEP_CHAR, log, seg) XLogDir, SEP_CHAR, log, seg)
#define XLogTempFileName(path, log, seg) \
snprintf(path, MAXPGPATH, "%s%cT%08X%08X", \
XLogDir, SEP_CHAR, log, seg)
#define PrevBufIdx(curridx) \ #define PrevBufIdx(curridx) \
((curridx == 0) ? XLogCtl->XLogCacheBlck : (curridx - 1)) ((curridx == 0) ? XLogCtl->XLogCacheBlck : (curridx - 1))
...@@ -198,7 +209,7 @@ typedef struct CheckPoint ...@@ -198,7 +209,7 @@ typedef struct CheckPoint
static void GetFreeXLBuffer(void); static void GetFreeXLBuffer(void);
static void XLogWrite(char *buffer); static void XLogWrite(char *buffer);
static int XLogFileInit(uint32 log, uint32 seg); static int XLogFileInit(uint32 log, uint32 seg, bool *usexistent);
static int XLogFileOpen(uint32 log, uint32 seg, bool econt); static int XLogFileOpen(uint32 log, uint32 seg, bool econt);
static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, char *buffer); static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, char *buffer);
static char *str_time(time_t tnow); static char *str_time(time_t tnow);
...@@ -672,6 +683,7 @@ XLogWrite(char *buffer) ...@@ -672,6 +683,7 @@ XLogWrite(char *buffer)
char *from; char *from;
uint32 wcnt = 0; uint32 wcnt = 0;
int i = 0; int i = 0;
bool usexistent;
for (; XLByteLT(LgwrResult.Write, LgwrRqst.Write);) for (; XLByteLT(LgwrResult.Write, LgwrRqst.Write);)
{ {
...@@ -710,13 +722,18 @@ XLogWrite(char *buffer) ...@@ -710,13 +722,18 @@ XLogWrite(char *buffer)
logId = LgwrResult.Write.xlogid; logId = LgwrResult.Write.xlogid;
logSeg = (LgwrResult.Write.xrecoff - 1) / XLogSegSize; logSeg = (LgwrResult.Write.xrecoff - 1) / XLogSegSize;
logOff = 0; logOff = 0;
logFile = XLogFileInit(logId, logSeg);
SpinAcquire(ControlFileLockId); SpinAcquire(ControlFileLockId);
/* create/use new log file */
usexistent = true;
logFile = XLogFileInit(logId, logSeg, &usexistent);
ControlFile->logId = logId; ControlFile->logId = logId;
ControlFile->logSeg = logSeg + 1; ControlFile->logSeg = logSeg + 1;
ControlFile->time = time(NULL); ControlFile->time = time(NULL);
UpdateControlFile(); UpdateControlFile();
SpinRelease(ControlFileLockId); SpinRelease(ControlFileLockId);
if (!usexistent) /* there was no file */
elog(LOG, "XLogWrite: had to create new log file - "
"you probably should do checkpoints more often");
} }
if (logFile < 0) if (logFile < 0)
...@@ -780,17 +797,39 @@ XLogWrite(char *buffer) ...@@ -780,17 +797,39 @@ XLogWrite(char *buffer)
} }
static int static int
XLogFileInit(uint32 log, uint32 seg) XLogFileInit(uint32 log, uint32 seg, bool *usexistent)
{ {
char path[MAXPGPATH]; char path[MAXPGPATH];
char tpath[MAXPGPATH];
int fd; int fd;
XLogFileName(path, log, seg); XLogFileName(path, log, seg);
/*
* Try to use existent file (checkpoint maker
* creates it sometime).
*/
if (*usexistent)
{
fd = BasicOpenFile(path, O_RDWR | PG_BINARY, S_IRUSR | S_IWUSR);
if (fd < 0)
{
if (errno != ENOENT)
elog(STOP, "InitOpen(logfile %u seg %u) failed: %d",
logId, logSeg, errno);
}
else
return(fd);
*usexistent = false;
}
XLogTempFileName(tpath, log, seg);
unlink(tpath);
unlink(path); unlink(path);
fd = BasicOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, S_IRUSR | S_IWUSR); fd = BasicOpenFile(tpath, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, S_IRUSR | S_IWUSR);
if (fd < 0) if (fd < 0)
elog(STOP, "Init(logfile %u seg %u) failed: %d", elog(STOP, "InitCreate(logfile %u seg %u) failed: %d",
logId, logSeg, errno); logId, logSeg, errno);
if (lseek(fd, XLogSegSize - 1, SEEK_SET) != (off_t) (XLogSegSize - 1)) if (lseek(fd, XLogSegSize - 1, SEEK_SET) != (off_t) (XLogSegSize - 1))
...@@ -809,6 +848,15 @@ XLogFileInit(uint32 log, uint32 seg) ...@@ -809,6 +848,15 @@ XLogFileInit(uint32 log, uint32 seg)
elog(STOP, "Lseek(logfile %u seg %u off %u) failed: %d", elog(STOP, "Lseek(logfile %u seg %u off %u) failed: %d",
log, seg, 0, errno); log, seg, 0, errno);
close(fd);
link(tpath, path);
unlink(tpath);
fd = BasicOpenFile(path, O_RDWR | PG_BINARY, S_IRUSR | S_IWUSR);
if (fd < 0)
elog(STOP, "InitReopen(logfile %u seg %u) failed: %d",
logId, logSeg, errno);
return (fd); return (fd);
} }
...@@ -837,6 +885,49 @@ XLogFileOpen(uint32 log, uint32 seg, bool econt) ...@@ -837,6 +885,49 @@ XLogFileOpen(uint32 log, uint32 seg, bool econt)
return (fd); return (fd);
} }
/*
* (Re)move offline log files older or equal to passwd one
*/
static void
MoveOfflineLogs(char *archdir, uint32 _logId, uint32 _logSeg)
{
DIR *xldir;
struct dirent *xlde;
char lastoff[32];
char path[MAXPGPATH];
Assert(archdir[0] == 0); /* ! implemented yet */
xldir = opendir(XLogDir);
if (xldir == NULL)
elog(STOP, "MoveOfflineLogs: cannot open xlog dir: %d", errno);
sprintf(lastoff, "%08X%08X", _logId, _logSeg);
errno = 0;
while ((xlde = readdir(xldir)) != NULL)
{
if (strlen(xlde->d_name) != 16 ||
strspn(xlde->d_name, "0123456789ABCDEF") != 16)
continue;
if (strcmp(xlde->d_name, lastoff) > 0)
{
elog(LOG, "MoveOfflineLogs: skip %s", xlde->d_name);
errno = 0;
continue;
}
elog(LOG, "MoveOfflineLogs: %s %s", (archdir[0]) ?
"archive" : "remove", xlde->d_name);
sprintf(path, "%s%c%s", XLogDir, SEP_CHAR, xlde->d_name);
if (archdir[0] != 0)
unlink(path);
errno = 0;
}
if (errno)
elog(STOP, "MoveOfflineLogs: cannot read xlog dir: %d", errno);
closedir(xldir);
}
static XLogRecord * static XLogRecord *
ReadRecord(XLogRecPtr *RecPtr, char *buffer) ReadRecord(XLogRecPtr *RecPtr, char *buffer)
{ {
...@@ -1183,6 +1274,7 @@ BootStrapXLOG() ...@@ -1183,6 +1274,7 @@ BootStrapXLOG()
int fd; int fd;
char buffer[BLCKSZ]; char buffer[BLCKSZ];
CheckPoint checkPoint; CheckPoint checkPoint;
bool usexistent = false;
#ifdef XLOG #ifdef XLOG
XLogPageHeader page = (XLogPageHeader) buffer; XLogPageHeader page = (XLogPageHeader) buffer;
...@@ -1217,7 +1309,7 @@ BootStrapXLOG() ...@@ -1217,7 +1309,7 @@ BootStrapXLOG()
record->xl_rmid = RM_XLOG_ID; record->xl_rmid = RM_XLOG_ID;
memcpy((char *) record + SizeOfXLogRecord, &checkPoint, sizeof(checkPoint)); memcpy((char *) record + SizeOfXLogRecord, &checkPoint, sizeof(checkPoint));
logFile = XLogFileInit(0, 0); logFile = XLogFileInit(0, 0, &usexistent);
if (write(logFile, buffer, BLCKSZ) != BLCKSZ) if (write(logFile, buffer, BLCKSZ) != BLCKSZ)
elog(STOP, "BootStrapXLOG failed to write logfile: %d", errno); elog(STOP, "BootStrapXLOG failed to write logfile: %d", errno);
...@@ -1297,6 +1389,7 @@ StartupXLOG() ...@@ -1297,6 +1389,7 @@ StartupXLOG()
S_INIT_LOCK(&(XLogCtl->insert_lck)); S_INIT_LOCK(&(XLogCtl->insert_lck));
S_INIT_LOCK(&(XLogCtl->info_lck)); S_INIT_LOCK(&(XLogCtl->info_lck));
S_INIT_LOCK(&(XLogCtl->lgwr_lck)); S_INIT_LOCK(&(XLogCtl->lgwr_lck));
S_INIT_LOCK(&(XLogCtl->chkp_lck));
/* /*
* Open/read Control file * Open/read Control file
...@@ -1556,6 +1649,8 @@ ShutdownXLOG() ...@@ -1556,6 +1649,8 @@ ShutdownXLOG()
elog(LOG, "Data Base System shut down at %s", str_time(time(NULL))); elog(LOG, "Data Base System shut down at %s", str_time(time(NULL)));
} }
extern XLogRecPtr GetUndoRecPtr(void);
void void
CreateCheckPoint(bool shutdown) CreateCheckPoint(bool shutdown)
{ {
...@@ -1565,6 +1660,21 @@ CreateCheckPoint(bool shutdown) ...@@ -1565,6 +1660,21 @@ CreateCheckPoint(bool shutdown)
XLogCtlInsert *Insert = &XLogCtl->Insert; XLogCtlInsert *Insert = &XLogCtl->Insert;
uint32 freespace; uint32 freespace;
uint16 curridx; uint16 curridx;
uint32 _logId;
uint32 _logSeg;
char archdir[MAXPGPATH];
if (MyLastRecPtr.xrecoff != 0)
elog(ERROR, "CreateCheckPoint: cannot be called inside transaction block");
while (TAS(&(XLogCtl->chkp_lck)))
{
struct timeval delay = {2, 0};
if (shutdown)
elog(STOP, "Checkpoint lock is busy while data base is shutting down");
(void) select(0, NULL, NULL, NULL, &delay);
}
memset(&checkPoint, 0, sizeof(checkPoint)); memset(&checkPoint, 0, sizeof(checkPoint));
if (shutdown) if (shutdown)
...@@ -1579,7 +1689,7 @@ CreateCheckPoint(bool shutdown) ...@@ -1579,7 +1689,7 @@ CreateCheckPoint(bool shutdown)
/* Get REDO record ptr */ /* Get REDO record ptr */
while (TAS(&(XLogCtl->insert_lck))) while (TAS(&(XLogCtl->insert_lck)))
{ {
struct timeval delay = {0, 5000}; struct timeval delay = {1, 0};
if (shutdown) if (shutdown)
elog(STOP, "XLog insert lock is busy while data base is shutting down"); elog(STOP, "XLog insert lock is busy while data base is shutting down");
...@@ -1615,7 +1725,7 @@ CreateCheckPoint(bool shutdown) ...@@ -1615,7 +1725,7 @@ CreateCheckPoint(bool shutdown)
FlushBufferPool(); FlushBufferPool();
/* Get UNDO record ptr - should use oldest of PROC->logRec */ /* Get UNDO record ptr - should use oldest of PROC->logRec */
checkPoint.undo.xrecoff = 0; checkPoint.undo = GetUndoRecPtr();
if (shutdown && checkPoint.undo.xrecoff != 0) if (shutdown && checkPoint.undo.xrecoff != 0)
elog(STOP, "Active transaction while data base is shutting down"); elog(STOP, "Active transaction while data base is shutting down");
...@@ -1633,9 +1743,35 @@ CreateCheckPoint(bool shutdown) ...@@ -1633,9 +1743,35 @@ CreateCheckPoint(bool shutdown)
SpinAcquire(ControlFileLockId); SpinAcquire(ControlFileLockId);
if (shutdown) if (shutdown)
ControlFile->state = DB_SHUTDOWNED; ControlFile->state = DB_SHUTDOWNED;
#ifdef XLOG #ifdef XLOG
else /* create new log file */
{
if (recptr.xrecoff % XLogSegSize >=
(uint32) (0.75 * XLogSegSize))
{
int lf;
bool usexistent = true;
_logId = recptr.xlogid;
_logSeg = recptr.xrecoff / XLogSegSize;
if (_logSeg >= XLogLastSeg)
{
_logId++;
_logSeg = 0;
}
else
_logSeg++;
lf = XLogFileInit(_logId, _logSeg, &usexistent);
close(lf);
}
}
ControlFile->checkPoint = MyLastRecPtr; ControlFile->checkPoint = MyLastRecPtr;
_logId = ControlFile->logId;
_logSeg = ControlFile->logSeg - 1;
strcpy(archdir, ControlFile->archdir);
#else #else
ControlFile->checkPoint.xlogid = 0; ControlFile->checkPoint.xlogid = 0;
ControlFile->checkPoint.xrecoff = SizeOfXLogPHD; ControlFile->checkPoint.xrecoff = SizeOfXLogPHD;
...@@ -1645,6 +1781,33 @@ CreateCheckPoint(bool shutdown) ...@@ -1645,6 +1781,33 @@ CreateCheckPoint(bool shutdown)
UpdateControlFile(); UpdateControlFile();
SpinRelease(ControlFileLockId); SpinRelease(ControlFileLockId);
#ifdef XLOG
/*
* Delete offline log files. Get oldest online
* log file from undo rec if it's valid.
*/
if (checkPoint.undo.xrecoff != 0)
{
_logId = checkPoint.undo.xlogid;
_logSeg = checkPoint.undo.xrecoff / XLogSegSize;
}
if (_logId || _logSeg)
{
if (_logSeg)
_logSeg--;
else
{
_logId--;
_logSeg = 0;
}
MoveOfflineLogs(archdir, _logId, _logSeg);
}
S_UNLOCK(&(XLogCtl->chkp_lck));
MyLastRecPtr.xrecoff = 0; /* to avoid commit record */
#endif
return; return;
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.129 2000/11/05 00:15:52 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.130 2000/11/05 22:50:19 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2895,6 +2895,9 @@ copyObject(void *from) ...@@ -2895,6 +2895,9 @@ copyObject(void *from)
case T_SetSessionStmt: case T_SetSessionStmt:
retval = _copySetSessionStmt(from); retval = _copySetSessionStmt(from);
break; break;
case T_CheckPointStmt:
retval = (void*)makeNode(CheckPointStmt);
break;
case T_A_Expr: case T_A_Expr:
retval = _copyAExpr(from); retval = _copyAExpr(from);
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.79 2000/11/05 00:15:52 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.80 2000/11/05 22:50:19 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2049,6 +2049,9 @@ equal(void *a, void *b) ...@@ -2049,6 +2049,9 @@ equal(void *a, void *b)
case T_SetSessionStmt: case T_SetSessionStmt:
retval = _equalSetSessionStmt(a, b); retval = _equalSetSessionStmt(a, b);
break; break;
case T_CheckPointStmt:
retval = true;
break;
case T_A_Expr: case T_A_Expr:
retval = _equalAExpr(a, b); retval = _equalAExpr(a, b);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.204 2000/11/05 00:15:54 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.205 2000/11/05 22:50:20 vadim Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -136,7 +136,7 @@ static void doNegateFloat(Value *v); ...@@ -136,7 +136,7 @@ static void doNegateFloat(Value *v);
RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty, RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty,
RuleStmt, SelectStmt, SetSessionStmt, TransactionStmt, TruncateStmt, RuleStmt, SelectStmt, SetSessionStmt, TransactionStmt, TruncateStmt,
UnlistenStmt, UpdateStmt, VacuumStmt, VariableResetStmt, UnlistenStmt, UpdateStmt, VacuumStmt, VariableResetStmt,
VariableSetStmt, VariableShowStmt, ViewStmt VariableSetStmt, VariableShowStmt, ViewStmt, CheckPointStmt
%type <node> select_no_parens, select_clause, simple_select %type <node> select_no_parens, select_clause, simple_select
...@@ -291,7 +291,7 @@ static void doNegateFloat(Value *v); ...@@ -291,7 +291,7 @@ static void doNegateFloat(Value *v);
/* Keywords (in SQL92 reserved words) */ /* Keywords (in SQL92 reserved words) */
%token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC, %token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
BEGIN_TRANS, BETWEEN, BOTH, BY, BEGIN_TRANS, BETWEEN, BOTH, BY,
CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE, CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
COALESCE, COLLATE, COLUMN, COMMIT, COALESCE, COLLATE, COLUMN, COMMIT,
CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT_DATE, CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT_DATE,
CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR, CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
...@@ -336,7 +336,7 @@ static void doNegateFloat(Value *v); ...@@ -336,7 +336,7 @@ static void doNegateFloat(Value *v);
*/ */
%token ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYZE, %token ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYZE,
BACKWARD, BEFORE, BINARY, BIT, BACKWARD, BEFORE, BINARY, BIT,
CACHE, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE, CACHE, CHECKPOINT, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE,
DATABASE, DELIMITERS, DO, DATABASE, DELIMITERS, DO,
EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND, EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
FORCE, FORWARD, FUNCTION, HANDLER, FORCE, FORWARD, FUNCTION, HANDLER,
...@@ -470,6 +470,7 @@ stmt : AlterSchemaStmt ...@@ -470,6 +470,7 @@ stmt : AlterSchemaStmt
| VariableShowStmt | VariableShowStmt
| VariableResetStmt | VariableResetStmt
| ConstraintsSetStmt | ConstraintsSetStmt
| CheckPointStmt
| /*EMPTY*/ | /*EMPTY*/
{ $$ = (Node *)NULL; } { $$ = (Node *)NULL; }
; ;
...@@ -957,6 +958,16 @@ constraints_set_mode: DEFERRED ...@@ -957,6 +958,16 @@ constraints_set_mode: DEFERRED
; ;
/*
* Checkpoint statement
*/
CheckPointStmt: CHECKPOINT
{
CheckPointStmt *n = makeNode(CheckPointStmt);
$$ = (Node *)n;
}
;
/***************************************************************************** /*****************************************************************************
* *
* ALTER TABLE variations * ALTER TABLE variations
...@@ -5389,6 +5400,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; } ...@@ -5389,6 +5400,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; }
| CACHE { $$ = "cache"; } | CACHE { $$ = "cache"; }
| CASCADE { $$ = "cascade"; } | CASCADE { $$ = "cascade"; }
| CHAIN { $$ = "chain"; } | CHAIN { $$ = "chain"; }
| CHECKPOINT { $$ = "checkpoint"; }
| CLOSE { $$ = "close"; } | CLOSE { $$ = "close"; }
| COMMENT { $$ = "comment"; } | COMMENT { $$ = "comment"; }
| COMMIT { $$ = "commit"; } | COMMIT { $$ = "commit"; }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.81 2000/09/12 05:09:44 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.82 2000/11/05 22:50:20 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -60,6 +60,7 @@ static ScanKeyword ScanKeywords[] = { ...@@ -60,6 +60,7 @@ static ScanKeyword ScanKeywords[] = {
{"character", CHARACTER}, {"character", CHARACTER},
{"characteristics", CHARACTERISTICS}, {"characteristics", CHARACTERISTICS},
{"check", CHECK}, {"check", CHECK},
{"checkpoint", CHECKPOINT},
{"close", CLOSE}, {"close", CLOSE},
{"cluster", CLUSTER}, {"cluster", CLUSTER},
{"coalesce", COALESCE}, {"coalesce", COALESCE},
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.21 2000/04/12 17:15:37 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.22 2000/11/05 22:50:20 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -369,3 +369,40 @@ GetSnapshotData(bool serializable) ...@@ -369,3 +369,40 @@ GetSnapshotData(bool serializable)
snapshot->xcnt = count; snapshot->xcnt = count;
return snapshot; return snapshot;
} }
/*
* GetUndoRecPtr -- returns oldest PROC->logRec.
*/
XLogRecPtr GetUndoRecPtr(void);
XLogRecPtr
GetUndoRecPtr(void)
{
SISeg *segP = shmInvalBuffer;
ProcState *stateP = segP->procState;
XLogRecPtr urec = {0, 0};
XLogRecPtr tempr;
int index;
SpinAcquire(SInvalLock);
for (index = 0; index < segP->maxBackends; index++)
{
SHMEM_OFFSET pOffset = stateP[index].procStruct;
if (pOffset != INVALID_OFFSET)
{
PROC *proc = (PROC *) MAKE_PTR(pOffset);
tempr = proc->logRec;
if (tempr.xrecoff == 0)
continue;
if (urec.xrecoff != 0 && XLByteLT(urec, tempr))
continue;
urec = tempr;
}
}
SpinRelease(SInvalLock);
return(urec);
}
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.98 2000/10/22 23:32:41 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.99 2000/11/05 22:50:21 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/ps_status.h" #include "utils/ps_status.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#include "access/xlog.h"
/* /*
* Error-checking support for DROP commands * Error-checking support for DROP commands
...@@ -818,6 +818,14 @@ ProcessUtility(Node *parsetree, ...@@ -818,6 +818,14 @@ ProcessUtility(Node *parsetree,
DropGroup((DropGroupStmt *) parsetree); DropGroup((DropGroupStmt *) parsetree);
break; break;
case T_CheckPointStmt:
{
set_ps_display(commandTag = "CHECKPOINT");
CreateCheckPoint(false);
}
break;
case T_ReindexStmt: case T_ReindexStmt:
{ {
ReindexStmt *stmt = (ReindexStmt *) parsetree; ReindexStmt *stmt = (ReindexStmt *) parsetree;
......
...@@ -97,4 +97,6 @@ extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info, ...@@ -97,4 +97,6 @@ extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info,
char *buf, uint32 buflen); char *buf, uint32 buflen);
extern void XLogFlush(XLogRecPtr RecPtr); extern void XLogFlush(XLogRecPtr RecPtr);
extern void CreateCheckPoint(bool shutdown);
#endif /* XLOG_H */ #endif /* XLOG_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: nodes.h,v 1.81 2000/10/31 10:22:12 petere Exp $ * $Id: nodes.h,v 1.82 2000/11/05 22:50:21 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -202,6 +202,7 @@ typedef enum NodeTag ...@@ -202,6 +202,7 @@ typedef enum NodeTag
T_DropGroupStmt, T_DropGroupStmt,
T_ReindexStmt, T_ReindexStmt,
T_SetSessionStmt, T_SetSessionStmt,
T_CheckPointStmt,
T_A_Expr = 700, T_A_Expr = 700,
T_Attr, T_Attr,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: parsenodes.h,v 1.118 2000/11/05 00:15:53 tgl Exp $ * $Id: parsenodes.h,v 1.119 2000/11/05 22:50:21 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -695,6 +695,11 @@ typedef struct SetSessionStmt ...@@ -695,6 +695,11 @@ typedef struct SetSessionStmt
List *args; List *args;
} SetSessionStmt; } SetSessionStmt;
typedef struct CheckPointStmt
{
NodeTag type;
} CheckPointStmt;
/* ---------------------- /* ----------------------
* Set Statement * Set Statement
* ---------------------- * ----------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment