Skip to content

Commit ba2dde5

Browse files
knizhnikMMeent
authored andcommitted
Large last written lsn cache (#177)
Maintain cache of last written LSN for each relation segment (8 Mb).
1 parent c0c8388 commit ba2dde5

File tree

10 files changed

+221
-36
lines changed

10 files changed

+221
-36
lines changed

contrib/neon/pagestore_smgr.c

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ static char *hexdump_page(char *page);
8484

8585
const int SmgrTrace = DEBUG5;
8686

87+
/*
88+
* Pseudo block number used to associate LSN with relation metadata (relation size)
89+
*/
90+
#define REL_METADATA_PSEUDO_BLOCKNO InvalidBlockNumber
91+
8792
page_server_api *page_server;
8893

8994
/* GUCs */
@@ -558,7 +563,7 @@ zenith_wallog_page(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
558563
* Remember the LSN on this page. When we read the page again, we must
559564
* read the same or newer version of it.
560565
*/
561-
SetLastWrittenPageLSN(lsn);
566+
SetLastWrittenLSN(lsn, reln->smgr_rnode.node.relNode, blocknum, blocknum);
562567
}
563568

564569

@@ -603,7 +608,7 @@ zm_adjust_lsn(XLogRecPtr lsn)
603608
* Return LSN for requesting pages and number of blocks from page server
604609
*/
605610
static XLogRecPtr
606-
zenith_get_request_lsn(bool *latest)
611+
zenith_get_request_lsn(bool *latest, Oid rnode, BlockNumber blkno)
607612
{
608613
XLogRecPtr lsn;
609614

@@ -630,9 +635,9 @@ zenith_get_request_lsn(bool *latest)
630635
* so our request cannot concern those.
631636
*/
632637
*latest = true;
633-
lsn = GetLastWrittenPageLSN();
638+
lsn = GetLastWrittenLSN(rnode, blkno);
634639
Assert(lsn != InvalidXLogRecPtr);
635-
elog(DEBUG1, "zenith_get_request_lsn GetLastWrittenPageLSN lsn %X/%X ",
640+
elog(DEBUG1, "zenith_get_request_lsn GetLastWrittenLSN lsn %X/%X ",
636641
(uint32) ((lsn) >> 32), (uint32) (lsn));
637642

638643
lsn = zm_adjust_lsn(lsn);
@@ -716,7 +721,7 @@ zenith_exists(SMgrRelation reln, ForkNumber forkNum)
716721
return false;
717722
}
718723

719-
request_lsn = zenith_get_request_lsn(&latest);
724+
request_lsn = zenith_get_request_lsn(&latest, reln->smgr_rnode.node.relNode, REL_METADATA_PSEUDO_BLOCKNO);
720725
{
721726
ZenithExistsRequest request = {
722727
.req.tag = T_ZenithExistsRequest,
@@ -791,7 +796,7 @@ zenith_create(SMgrRelation reln, ForkNumber forkNum, bool isRedo)
791796
*
792797
* FIXME: This is currently not just an optimization, but required for
793798
* correctness. Postgres can call smgrnblocks() on the newly-created
794-
* relation. Currently, we don't call SetLastWrittenPageLSN() when a new
799+
* relation. Currently, we don't call SetLastWrittenLSN() when a new
795800
* relation created, so if we didn't remember the size in the relsize
796801
* cache, we might call smgrnblocks() on the newly-created relation before
797802
* the creation WAL record hass been received by the page server.
@@ -904,6 +909,8 @@ zenith_extend(SMgrRelation reln, ForkNumber forkNum, BlockNumber blkno,
904909
if (IS_LOCAL_REL(reln))
905910
mdextend(reln, forkNum, blkno, buffer, skipFsync);
906911
#endif
912+
913+
SetLastWrittenLSN(lsn, reln->smgr_rnode.node.relNode, REL_METADATA_PSEUDO_BLOCKNO, REL_METADATA_PSEUDO_BLOCKNO);
907914
}
908915

909916
/*
@@ -1079,7 +1086,7 @@ zenith_read(SMgrRelation reln, ForkNumber forkNum, BlockNumber blkno,
10791086
elog(ERROR, "unknown relpersistence '%c'", reln->smgr_relpersistence);
10801087
}
10811088

1082-
request_lsn = zenith_get_request_lsn(&latest);
1089+
request_lsn = zenith_get_request_lsn(&latest, reln->smgr_rnode.node.relNode, blkno);
10831090
zenith_read_at_lsn(reln->smgr_rnode.node, forkNum, blkno, request_lsn, latest, buffer);
10841091

10851092
#ifdef DEBUG_COMPARE_LOCAL
@@ -1284,7 +1291,7 @@ zenith_nblocks(SMgrRelation reln, ForkNumber forknum)
12841291
return n_blocks;
12851292
}
12861293

1287-
request_lsn = zenith_get_request_lsn(&latest);
1294+
request_lsn = zenith_get_request_lsn(&latest, reln->smgr_rnode.node.relNode, REL_METADATA_PSEUDO_BLOCKNO);
12881295
{
12891296
ZenithNblocksRequest request = {
12901297
.req.tag = T_ZenithNblocksRequest,
@@ -1344,7 +1351,7 @@ zenith_dbsize(Oid dbNode)
13441351
XLogRecPtr request_lsn;
13451352
bool latest;
13461353

1347-
request_lsn = zenith_get_request_lsn(&latest);
1354+
request_lsn = zenith_get_request_lsn(&latest, InvalidOid, REL_METADATA_PSEUDO_BLOCKNO);
13481355
{
13491356
ZenithDbSizeRequest request = {
13501357
.req.tag = T_ZenithDbSizeRequest,
@@ -1431,7 +1438,11 @@ zenith_truncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks)
14311438
*/
14321439
XLogFlush(lsn);
14331440

1434-
SetLastWrittenPageLSN(lsn);
1441+
/*
1442+
* Truncate may affect several chunks of relations. So we should either update last written LSN for all of them,
1443+
* either update LSN for "dummy" metadata block. Second approach seems to be more efficient.
1444+
*/
1445+
SetLastWrittenLSN(lsn, reln->smgr_rnode.node.relNode, REL_METADATA_PSEUDO_BLOCKNO, REL_METADATA_PSEUDO_BLOCKNO);
14351446

14361447
#ifdef DEBUG_COMPARE_LOCAL
14371448
if (IS_LOCAL_REL(reln))

src/backend/access/gin/gininsert.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,8 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
421421
log_newpage_range(index, MAIN_FORKNUM,
422422
0, RelationGetNumberOfBlocks(index),
423423
true);
424+
SetLastWrittenLSN(XactLastRecEnd, index->rd_smgr->smgr_rnode.node.relNode, 0, RelationGetNumberOfBlocks(index));
424425
}
425-
SetLastWrittenPageLSN(XactLastRecEnd);
426426

427427
smgr_end_unlogged_build(index->rd_smgr);
428428

src/backend/access/gist/gistbuild.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,10 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
335335
log_newpage_range(index, MAIN_FORKNUM,
336336
0, RelationGetNumberOfBlocks(index),
337337
true);
338+
SetLastWrittenLSN(XactLastRecEnd,
339+
index->rd_smgr->smgr_rnode.node.relNode,
340+
0, RelationGetNumberOfBlocks(index));
338341
}
339-
SetLastWrittenPageLSN(XactLastRecEnd);
340-
341342
smgr_end_unlogged_build(index->rd_smgr);
342343
}
343344

@@ -467,7 +468,8 @@ gist_indexsortbuild(GISTBuildState *state)
467468

468469
lsn = log_newpage(&state->indexrel->rd_node, MAIN_FORKNUM, GIST_ROOT_BLKNO,
469470
pagestate->page, true);
470-
SetLastWrittenPageLSN(lsn);
471+
SetLastWrittenLSN(lsn, state->indexrel->rd_smgr->smgr_rnode.node.relNode,
472+
GIST_ROOT_BLKNO, GIST_ROOT_BLKNO);
471473
}
472474

473475
pfree(pagestate->page);

src/backend/access/spgist/spginsert.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,9 @@ spgbuild(Relation heap, Relation index, IndexInfo *indexInfo)
143143
log_newpage_range(index, MAIN_FORKNUM,
144144
0, RelationGetNumberOfBlocks(index),
145145
true);
146+
SetLastWrittenLSN(XactLastRecEnd, index->rd_smgr->smgr_rnode.node.relNode,
147+
0, RelationGetNumberOfBlocks(index));
146148
}
147-
SetLastWrittenPageLSN(XactLastRecEnd);
148149

149150
smgr_end_unlogged_build(index->rd_smgr);
150151

0 commit comments

Comments
 (0)