}
else if (info == COMMIT_TS_TRUNCATE)
{
- int pageno;
+ xl_commit_ts_truncate *trunc = (xl_commit_ts_truncate *) rec;
- memcpy(&pageno, rec, sizeof(int));
- appendStringInfo(buf, "%d", pageno);
+ appendStringInfo(buf, "pageno %d, oldestXid %u",
+ trunc->pageno, trunc->oldestXid);
}
else if (info == COMMIT_TS_SETTS)
{
static void ActivateCommitTs(void);
static void DeactivateCommitTs(void);
static void WriteZeroPageXlogRec(int pageno);
-static void WriteTruncateXlogRec(int pageno);
+static void WriteTruncateXlogRec(int pageno, TransactionId oldestXid);
static void WriteSetTimestampXlogRec(TransactionId mainxid, int nsubxids,
TransactionId *subxids, TimestampTz timestamp,
RepOriginId nodeid);
return; /* nothing to remove */
/* Write XLOG record */
- WriteTruncateXlogRec(cutoffPage);
+ WriteTruncateXlogRec(cutoffPage, oldestXact);
/* Now we can remove the old CommitTs segment(s) */
SimpleLruTruncate(CommitTsCtl, cutoffPage);
* Write a TRUNCATE xlog record
*/
static void
-WriteTruncateXlogRec(int pageno)
+WriteTruncateXlogRec(int pageno, TransactionId oldestXid)
{
+ xl_commit_ts_truncate xlrec;
+
+ xlrec.pageno = pageno;
+ xlrec.oldestXid = oldestXid;
+
XLogBeginInsert();
- XLogRegisterData((char *) (&pageno), sizeof(int));
+ XLogRegisterData((char *) (&xlrec), SizeOfCommitTsTruncate);
(void) XLogInsert(RM_COMMIT_TS_ID, COMMIT_TS_TRUNCATE);
}
}
else if (info == COMMIT_TS_TRUNCATE)
{
- int pageno;
+ xl_commit_ts_truncate *trunc = (xl_commit_ts_truncate *) XLogRecGetData(record);
- memcpy(&pageno, XLogRecGetData(record), sizeof(int));
+ AdvanceOldestCommitTsXid(trunc->oldestXid);
/*
* During XLOG replay, latest_page_number isn't set up yet; insert a
* suitable value to bypass the sanity test in SimpleLruTruncate.
*/
- CommitTsCtl->shared->latest_page_number = pageno;
+ CommitTsCtl->shared->latest_page_number = trunc->pageno;
- SimpleLruTruncate(CommitTsCtl, pageno);
+ SimpleLruTruncate(CommitTsCtl, trunc->pageno);
}
else if (info == COMMIT_TS_SETTS)
{
if (bogus)
return;
+ /*
+ * Advance the oldest value for commit timestamps before truncating, so
+ * that if a user requests a timestamp for a transaction we're truncating
+ * away right after this point, they get NULL instead of an ugly "file not
+ * found" error from slru.c. This doesn't matter for xact/multixact
+ * because they are not subject to arbitrary lookups from users.
+ */
+ AdvanceOldestCommitTsXid(frozenXID);
+
/*
* Truncate CLOG, multixact and CommitTs to the oldest computed value.
*/
*/
SetTransactionIdLimit(frozenXID, oldestxid_datoid);
SetMultiXactIdLimit(minMulti, minmulti_datoid);
- AdvanceOldestCommitTsXid(frozenXID);
}
#define SizeOfCommitTsSet (offsetof(xl_commit_ts_set, mainxid) + \
sizeof(TransactionId))
+typedef struct xl_commit_ts_truncate
+{
+ int pageno;
+ TransactionId oldestXid;
+} xl_commit_ts_truncate;
+
+#define SizeOfCommitTsTruncate (offsetof(xl_commit_ts_truncate, oldestXid) + \
+ sizeof(TransactionId))
extern void commit_ts_redo(XLogReaderState *record);
extern void commit_ts_desc(StringInfo buf, XLogReaderState *record);