From 385d85b87e4f0a7c3a3e551a1575466e8d348d93 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 25 Jun 2021 16:57:05 -0400 Subject: [PATCH 11/12] cfe-11-gist_over_cfe-10-hint squash commit --- src/backend/access/gist/README | 10 ++++++++++ src/backend/access/gist/gist.c | 21 +++++++++++++++------ src/backend/access/gist/gistbuild.c | 12 +++++++++--- src/backend/access/gist/gistvacuum.c | 20 ++++++++++++++------ 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/backend/access/gist/README b/src/backend/access/gist/README index efb2730e18..c4d908fcb2 100644 --- a/src/backend/access/gist/README +++ b/src/backend/access/gist/README @@ -477,6 +477,16 @@ value. The page is not recycled, until that XID is no longer visible to anyone. That's much more conservative than necessary, but let's keep it simple. +GiST and Encryption +------------------- + +GiST uses LSNs and NSNs for concurrency. This means that unlogged and +temporary relations also need LSNs. GiST has a mechanism to assign LSNs +to such relations, but sometimes uses fixed LSNs and or calls +gistGetFakeLSN(), which can cause duplicate LSNs to be used. Therefore, +when encryption is enabled and fake LSNs are needed, the GiST code calls +LSNForEncryption(). See src/backend/crypto/README for more details. + Authors: Teodor Sigaev diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 30069f139c..74e7e485e6 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -501,13 +501,16 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, * we don't need to be able to detect concurrent splits yet.) */ if (is_build) - recptr = GistBuildLSN; + recptr = !FileEncryptionEnabled ? GistBuildLSN : + LSNForEncryption(RelationIsPermanent(rel)); else { if (RelationNeedsWAL(rel)) recptr = gistXLogSplit(is_leaf, dist, oldrlink, oldnsn, leftchildbuf, markfollowright); + else if (FileEncryptionEnabled) + recptr = LSNForEncryption(RelationIsPermanent(rel)); else recptr = gistGetFakeLSN(rel); } @@ -568,7 +571,8 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, MarkBufferDirty(leftchildbuf); if (is_build) - recptr = GistBuildLSN; + recptr = !FileEncryptionEnabled ? GistBuildLSN : + LSNForEncryption(RelationIsPermanent(rel)); else { if (RelationNeedsWAL(rel)) @@ -586,6 +590,8 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, deloffs, ndeloffs, itup, ntup, leftchildbuf); } + else if (FileEncryptionEnabled) + recptr = LSNForEncryption(RelationIsPermanent(rel)); else recptr = gistGetFakeLSN(rel); } @@ -1665,6 +1671,8 @@ gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel) if (ndeletable > 0) { + XLogRecPtr recptr; + TransactionId latestRemovedXid = InvalidTransactionId; if (XLogStandbyInfoActive() && RelationNeedsWAL(rel)) @@ -1690,16 +1698,17 @@ gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel) /* XLOG stuff */ if (RelationNeedsWAL(rel)) { - XLogRecPtr recptr; - recptr = gistXLogDelete(buffer, deletable, ndeletable, latestRemovedXid); - PageSetLSN(page, recptr); } + else if (FileEncryptionEnabled) + recptr = LSNForEncryption(RelationIsPermanent(rel)); else - PageSetLSN(page, gistGetFakeLSN(rel)); + recptr = gistGetFakeLSN(rel); + + PageSetLSN(page, recptr); END_CRIT_SECTION(); } diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c index fb0f466708..bf5162b410 100644 --- a/src/backend/access/gist/gistbuild.c +++ b/src/backend/access/gist/gistbuild.c @@ -48,6 +48,8 @@ #include "utils/rel.h" #include "utils/tuplesort.h" +extern XLogRecPtr LSNForEncryption(bool use_wal_lsn); + /* Step of index tuples for check whether to switch to buffering build mode */ #define BUFFERING_MODE_SWITCH_CHECK_STEP 256 @@ -307,7 +309,8 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) GISTInitBuffer(buffer, F_LEAF); MarkBufferDirty(buffer); - PageSetLSN(page, GistBuildLSN); + PageSetLSN(page, !FileEncryptionEnabled ? GistBuildLSN : + LSNForEncryption(RelationIsPermanent(index))); UnlockReleaseBuffer(buffer); @@ -458,7 +461,9 @@ gist_indexsortbuild(GISTBuildState *state) gist_indexsortbuild_flush_ready_pages(state); /* Write out the root */ - PageSetLSN(levelstate->pages[0], GistBuildLSN); + RelationGetSmgr(state->indexrel); + PageSetLSN(levelstate->pages[0], !FileEncryptionEnabled ? GistBuildLSN : + LSNForEncryption(RelationIsPermanent(state->indexrel))); PageSetChecksumInplace(levelstate->pages[0], GIST_ROOT_BLKNO); smgrwrite(RelationGetSmgr(state->indexrel), MAIN_FORKNUM, GIST_ROOT_BLKNO, levelstate->pages[0], true); @@ -655,7 +660,8 @@ gist_indexsortbuild_flush_ready_pages(GISTBuildState *state) if (blkno != state->pages_written) elog(ERROR, "unexpected block number to flush GiST sorting build"); - PageSetLSN(page, GistBuildLSN); + PageSetLSN(page, !FileEncryptionEnabled ? GistBuildLSN : + LSNForEncryption(RelationIsPermanent(state->indexrel))); PageSetChecksumInplace(page, blkno); smgrextend(RelationGetSmgr(state->indexrel), MAIN_FORKNUM, blkno, page, true); diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index 0aa6e58a62..35265ae0e7 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -24,6 +24,8 @@ #include "storage/lmgr.h" #include "utils/memutils.h" +extern XLogRecPtr LSNForEncryption(bool use_wal_lsn); + /* Working state needed by gistbulkdelete */ typedef struct { @@ -180,6 +182,8 @@ gistvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, vstate.callback_state = callback_state; if (RelationNeedsWAL(rel)) vstate.startNSN = GetInsertRecPtr(); + else if (FileEncryptionEnabled) + vstate.startNSN = LSNForEncryption(RelationIsPermanent(rel)); else vstate.startNSN = gistGetFakeLSN(rel); @@ -359,6 +363,8 @@ restart: */ if (ntodelete > 0) { + XLogRecPtr recptr; + START_CRIT_SECTION(); MarkBufferDirty(buffer); @@ -367,16 +373,15 @@ restart: GistMarkTuplesDeleted(page); if (RelationNeedsWAL(rel)) - { - XLogRecPtr recptr; - recptr = gistXLogUpdate(buffer, todelete, ntodelete, NULL, 0, InvalidBuffer); - PageSetLSN(page, recptr); - } + else if (FileEncryptionEnabled) + recptr = LSNForEncryption(RelationIsPermanent(rel)); else - PageSetLSN(page, gistGetFakeLSN(rel)); + recptr = gistGetFakeLSN(rel); + + PageSetLSN(page, recptr); END_CRIT_SECTION(); @@ -663,8 +668,11 @@ gistdeletepage(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, if (RelationNeedsWAL(info->index)) recptr = gistXLogPageDelete(leafBuffer, txid, parentBuffer, downlink); + else if (FileEncryptionEnabled) + recptr = LSNForEncryption(RelationIsPermanent(info->index)); else recptr = gistGetFakeLSN(info->index); + PageSetLSN(parentPage, recptr); PageSetLSN(leafPage, recptr); -- 2.37.0 (Apple Git-136)