aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r--src/backend/access/transam/xlog.c121
1 files changed, 107 insertions, 14 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 21e7b47206d..d78f1c30744 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.247 2006/08/07 16:57:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.248 2006/08/17 23:04:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,6 +23,7 @@
#include <sys/time.h>
#include "access/clog.h"
+#include "access/heapam.h"
#include "access/multixact.h"
#include "access/subtrans.h"
#include "access/transam.h"
@@ -32,6 +33,8 @@
#include "access/xlogutils.h"
#include "catalog/catversion.h"
#include "catalog/pg_control.h"
+#include "catalog/pg_type.h"
+#include "funcapi.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/bgwriter.h"
@@ -128,6 +131,7 @@
/* User-settable parameters */
int CheckPointSegments = 3;
int XLOGbuffers = 8;
+int XLogArchiveTimeout = 0;
char *XLogArchiveCommand = NULL;
char *XLOG_sync_method = NULL;
const char XLOG_sync_method_default[] = DEFAULT_SYNC_METHOD_STR;
@@ -347,8 +351,9 @@ typedef struct XLogCtlInsert
*/
typedef struct XLogCtlWrite
{
- XLogwrtResult LogwrtResult; /* current value of LogwrtResult */
- int curridx; /* cache index of next block to write */
+ XLogwrtResult LogwrtResult; /* current value of LogwrtResult */
+ int curridx; /* cache index of next block to write */
+ time_t lastSegSwitchTime; /* time of last xlog segment switch */
} XLogCtlWrite;
/*
@@ -1660,7 +1665,8 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch)
* switch.
*
* This is also the right place to notify the Archiver that the
- * segment is ready to copy to archival storage.
+ * segment is ready to copy to archival storage, and to update
+ * the timer for archive_timeout.
*/
if (finishing_seg || (xlog_switch && last_iteration))
{
@@ -1669,6 +1675,8 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch)
if (XLogArchivingActive())
XLogArchiveNotifySeg(openLogId, openLogSeg);
+
+ Write->lastSegSwitchTime = time(NULL);
}
}
@@ -5124,6 +5132,9 @@ StartupXLOG(void)
ControlFile->time = time(NULL);
UpdateControlFile();
+ /* start the archive_timeout timer running */
+ XLogCtl->Write.lastSegSwitchTime = ControlFile->time;
+
/* Start up the commit log and related stuff, too */
StartupCLOG();
StartupSUBTRANS(oldestActiveXID);
@@ -5308,6 +5319,22 @@ GetRedoRecPtr(void)
}
/*
+ * Get the time of the last xlog segment switch
+ */
+time_t
+GetLastSegSwitchTime(void)
+{
+ time_t result;
+
+ /* Need WALWriteLock, but shared lock is sufficient */
+ LWLockAcquire(WALWriteLock, LW_SHARED);
+ result = XLogCtl->Write.lastSegSwitchTime;
+ LWLockRelease(WALWriteLock);
+
+ return result;
+}
+
+/*
* GetRecentNextXid - get the nextXid value saved by the most recent checkpoint
*
* This is currently used only by the autovacuum daemon. To check for
@@ -5728,7 +5755,7 @@ XLogPutNextOid(Oid nextOid)
* or the end+1 address of the prior segment if we did not need to
* write a switch record because we are already at segment start.
*/
-static XLogRecPtr
+XLogRecPtr
RequestXLogSwitch(void)
{
XLogRecPtr RecPtr;
@@ -6335,12 +6362,45 @@ pg_switch_xlog(PG_FUNCTION_ARGS)
}
/*
- * Report the current WAL location (same format as pg_start_backup etc)
+ * Report the current WAL write location (same format as pg_start_backup etc)
+ *
+ * This is useful for determining how much of WAL is visible to an external
+ * archiving process. Note that the data before this point is written out
+ * to the kernel, but is not necessarily synced to disk.
*/
Datum
pg_current_xlog_location(PG_FUNCTION_ARGS)
{
text *result;
+ char location[MAXFNAMELEN];
+
+ /* Make sure we have an up-to-date local LogwrtResult */
+ {
+ /* use volatile pointer to prevent code rearrangement */
+ volatile XLogCtlData *xlogctl = XLogCtl;
+
+ SpinLockAcquire(&xlogctl->info_lck);
+ LogwrtResult = xlogctl->LogwrtResult;
+ SpinLockRelease(&xlogctl->info_lck);
+ }
+
+ snprintf(location, sizeof(location), "%X/%X",
+ LogwrtResult.Write.xlogid, LogwrtResult.Write.xrecoff);
+
+ result = DatumGetTextP(DirectFunctionCall1(textin,
+ CStringGetDatum(location)));
+ PG_RETURN_TEXT_P(result);
+}
+
+/*
+ * Report the current WAL insert location (same format as pg_start_backup etc)
+ *
+ * This function is mostly for debugging purposes.
+ */
+Datum
+pg_current_xlog_insert_location(PG_FUNCTION_ARGS)
+{
+ text *result;
XLogCtlInsert *Insert = &XLogCtl->Insert;
XLogRecPtr current_recptr;
char location[MAXFNAMELEN];
@@ -6372,7 +6432,6 @@ Datum
pg_xlogfile_name_offset(PG_FUNCTION_ARGS)
{
text *location = PG_GETARG_TEXT_P(0);
- text *result;
char *locationstr;
unsigned int uxlogid;
unsigned int uxrecoff;
@@ -6381,7 +6440,15 @@ pg_xlogfile_name_offset(PG_FUNCTION_ARGS)
uint32 xrecoff;
XLogRecPtr locationpoint;
char xlogfilename[MAXFNAMELEN];
+ Datum values[2];
+ bool isnull[2];
+ TupleDesc resultTupleDesc;
+ HeapTuple resultHeapTuple;
+ Datum result;
+ /*
+ * Read input and parse
+ */
locationstr = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(location)));
@@ -6394,18 +6461,44 @@ pg_xlogfile_name_offset(PG_FUNCTION_ARGS)
locationpoint.xlogid = uxlogid;
locationpoint.xrecoff = uxrecoff;
+ /*
+ * Construct a tuple descriptor for the result row. This must match
+ * this function's pg_proc entry!
+ */
+ resultTupleDesc = CreateTemplateTupleDesc(2, false);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "file_name",
+ TEXTOID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "file_offset",
+ INT4OID, -1, 0);
+
+ resultTupleDesc = BlessTupleDesc(resultTupleDesc);
+
+ /*
+ * xlogfilename
+ */
XLByteToPrevSeg(locationpoint, xlogid, xlogseg);
XLogFileName(xlogfilename, ThisTimeLineID, xlogid, xlogseg);
+ values[0] = DirectFunctionCall1(textin,
+ CStringGetDatum(xlogfilename));
+ isnull[0] = false;
+
+ /*
+ * offset
+ */
xrecoff = locationpoint.xrecoff - xlogseg * XLogSegSize;
- snprintf(xlogfilename + strlen(xlogfilename),
- sizeof(xlogfilename) - strlen(xlogfilename),
- " %u",
- (unsigned int) xrecoff);
- result = DatumGetTextP(DirectFunctionCall1(textin,
- CStringGetDatum(xlogfilename)));
- PG_RETURN_TEXT_P(result);
+ values[1] = UInt32GetDatum(xrecoff);
+ isnull[1] = false;
+
+ /*
+ * Tuple jam: Having first prepared your Datums, then squash together
+ */
+ resultHeapTuple = heap_form_tuple(resultTupleDesc, values, isnull);
+
+ result = HeapTupleGetDatum(resultHeapTuple);
+
+ PG_RETURN_DATUM(result);
}
/*