Skip to content

Port last written lsn cache patch to new main #200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/backend/access/gin/gininsert.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
0, RelationGetNumberOfBlocks(index),
true);
}
SetLastWrittenPageLSN(XactLastRecEnd);
SetLastWrittenPageLSN(XactLastRecEnd, index->rd_smgr->smgr_rnode.node.relNode);

smgr_end_unlogged_build(index->rd_smgr);

Expand Down
4 changes: 2 additions & 2 deletions src/backend/access/gist/gistbuild.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
0, RelationGetNumberOfBlocks(index),
true);
}
SetLastWrittenPageLSN(XactLastRecEnd);
SetLastWrittenPageLSN(XactLastRecEnd, index->rd_smgr->smgr_rnode.node.relNode);

smgr_end_unlogged_build(index->rd_smgr);
}
Expand Down Expand Up @@ -469,7 +469,7 @@ gist_indexsortbuild(GISTBuildState *state)

lsn = log_newpage(&state->indexrel->rd_node, MAIN_FORKNUM, GIST_ROOT_BLKNO,
pagestate->page, true);
SetLastWrittenPageLSN(lsn);
SetLastWrittenPageLSN(lsn, state->indexrel->rd_smgr->smgr_rnode.node.relNode);
}

pfree(pagestate->page);
Expand Down
2 changes: 1 addition & 1 deletion src/backend/access/spgist/spginsert.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ spgbuild(Relation heap, Relation index, IndexInfo *indexInfo)
0, RelationGetNumberOfBlocks(index),
true);
}
SetLastWrittenPageLSN(XactLastRecEnd);
SetLastWrittenPageLSN(XactLastRecEnd, index->rd_smgr->smgr_rnode.node.relNode);

smgr_end_unlogged_build(index->rd_smgr);

Expand Down
93 changes: 83 additions & 10 deletions src/backend/access/transam/xlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ extern uint32 bootstrap_data_checksum_version;
#define RECOVERY_COMMAND_FILE "recovery.conf"
#define RECOVERY_COMMAND_DONE "recovery.done"

/* Size of last written page LSN cache. Should not be large because sequential search is used. */
#define LAST_WRITTEN_CACHE_SIZE 4

/* User-settable parameters */
int max_wal_size_mb = 1024; /* 1 GB */
int min_wal_size_mb = 80; /* 80 MB */
Expand Down Expand Up @@ -749,7 +752,15 @@ typedef struct XLogCtlData
* XLOG_FPW_CHANGE record that instructs full_page_writes is disabled.
*/
XLogRecPtr lastFpwDisableRecPtr;
XLogRecPtr lastWrittenPageLSN;

/*
* Cache of last written page LSN.
* We store this value for up to LAST_WRITTEN_CACHE_SIZE relations + maximum for all other relations.
*/
XLogRecPtr lastWrittenPageNonCacheLsn;
XLogRecPtr lastWrittenPageCacheLsn[LAST_WRITTEN_CACHE_SIZE];
Oid lastWrittenPageCacheOid[LAST_WRITTEN_CACHE_SIZE];
size_t lastWrittenPageCacheClock; /* Pointer of the victim element for clock replacement algorithm */

/* neon: copy of startup's RedoStartLSN for walproposer's use */
XLogRecPtr RedoStartLSN;
Expand All @@ -762,6 +773,7 @@ typedef struct XLogCtlData
slock_t info_lck; /* locks shared variables shown above */
} XLogCtlData;


static XLogCtlData *XLogCtl = NULL;

/* a private copy of XLogCtl->Insert.WALInsertLocks, for convenience */
Expand Down Expand Up @@ -8098,8 +8110,13 @@ StartupXLOG(void)

XLogCtl->LogwrtRqst.Write = EndOfLog;
XLogCtl->LogwrtRqst.Flush = EndOfLog;
XLogCtl->lastWrittenPageLSN = EndOfLog;

XLogCtl->lastWrittenPageLsn = EndOfLog;
for (int i = 0; i < LAST_WRITTEN_CACHE_SIZE; i++)
{
XLogCtl->lastWrittenPageCacheLsn[i] = InvalidXLogRecPtr;
XLogCtl->lastWrittenPageCacheOid[i] = InvalidOid;
}
XLogCtl->lastWrittenPageCacheClock = 0;
LocalSetXLogInsertAllowed();

/* If necessary, write overwrite-contrecord before doing anything else */
Expand Down Expand Up @@ -8870,28 +8887,84 @@ GetInsertRecPtr(void)
}

/*
* GetLastWrittenPageLSN -- Returns maximal LSN of written page
* GetLastWrittenPageLSN -- Returns maximal LSN of written page.
* It returns either cached last written LSN of particular relation,
* either global maximum of last written LSNs among all relations.
*/
XLogRecPtr
GetLastWrittenPageLSN(void)
GetLastWrittenPageLSN(Oid rnode)
{
XLogRecPtr lsn;
SpinLockAcquire(&XLogCtl->info_lck);
lsn = XLogCtl->lastWrittenPageLSN;
lsn = XLogCtl->lastWrittenPageLsn;
if (rnode != InvalidOid)
{
for (int i = 0; i < LAST_WRITTEN_CACHE_SIZE; i++)
{
if (rnode == XLogCtl->lastWrittenPageCacheOid[i])
{
lsn = XLogCtl->lastWrittenPageCacheLsn[i];
break;
}
}
}
else
{
/* Find maximum of all cached LSNs */
for (int i = 0; i < LAST_WRITTEN_CACHE_SIZE; i++)
{
if (XLogCtl->lastWrittenPageCacheLsn[i] > lsn)
lsn = XLogCtl->lastWrittenPageCacheLsn[i];
}
}
SpinLockRelease(&XLogCtl->info_lck);

return lsn;
}

/*
* SetLastWrittenPageLSN -- Set maximal LSN of written page
* SetLastWrittenPageLSN -- Set maximal LSN of written page.
* We maintain small shared cache for last written LSN of least recently updated
* pages. This cache allows to keep global lastWrittenPageLsn unchanged and
* so avoid long wait for LSN for read requests to other relations.
*/
void
SetLastWrittenPageLSN(XLogRecPtr lsn)
SetLastWrittenPageLSN(XLogRecPtr lsn, Oid rnode)
{
if (lsn == InvalidXLogRecPtr)
return;

SpinLockAcquire(&XLogCtl->info_lck);
if (lsn > XLogCtl->lastWrittenPageLSN)
XLogCtl->lastWrittenPageLSN = lsn;
if (rnode == InvalidOid)
{
if (lsn > XLogCtl->lastWrittenPageLsn)
XLogCtl->lastWrittenPageLsn = lsn;
}
else
{
int i = LAST_WRITTEN_CACHE_SIZE;
while (--i >= 0)
{
if (rnode == XLogCtl->lastWrittenPageCacheOid[i])
{
if (lsn > XLogCtl->lastWrittenPageCacheLsn[i])
{
XLogCtl->lastWrittenPageCacheLsn[i] = lsn;
}
break;
}
}
if (i < 0)
{
int victim = ++XLogCtl->lastWrittenPageCacheClock % LAST_WRITTEN_CACHE_SIZE;
if (XLogCtl->lastWrittenPageCacheLsn[victim] > XLogCtl->lastWrittenPageLsn)
{
XLogCtl->lastWrittenPageLsn = XLogCtl->lastWrittenPageCacheLsn[victim];
}
XLogCtl->lastWrittenPageCacheOid[victim] = rnode;
XLogCtl->lastWrittenPageCacheLsn[victim] = lsn;
}
}
SpinLockRelease(&XLogCtl->info_lck);
}

Expand Down
4 changes: 2 additions & 2 deletions src/backend/commands/dbcommands.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)

lsn = XLogInsert(RM_DBASE_ID,
XLOG_DBASE_CREATE | XLR_SPECIAL_REL_UPDATE);
SetLastWrittenPageLSN(lsn);
SetLastWrittenPageLSN(lsn, InvalidOid);
}
}
table_endscan(scan);
Expand Down Expand Up @@ -2294,7 +2294,7 @@ dbase_redo(XLogReaderState *record)
{
XLogRecPtr lsn = record->EndRecPtr;

SetLastWrittenPageLSN(lsn);
SetLastWrittenPageLSN(lsn, InvalidOid);
}
}
else if (info == XLOG_DBASE_DROP)
Expand Down
4 changes: 2 additions & 2 deletions src/include/access/xlog.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ extern XLogRecPtr GetFlushRecPtr(void);
extern XLogRecPtr GetLastImportantRecPtr(void);
extern void RemovePromoteSignalFiles(void);

extern void SetLastWrittenPageLSN(XLogRecPtr lsn);
extern XLogRecPtr GetLastWrittenPageLSN(void);
extern void SetLastWrittenPageLSN(XLogRecPtr lsn, Oid relfilenode);
extern XLogRecPtr GetLastWrittenPageLSN(Oid relfilenode);

extern XLogRecPtr GetRedoStartLsn(void);

Expand Down