From fb93145d2a4999f07dc00df9626c72fa15e75989 Mon Sep 17 00:00:00 2001 From: Zsolt Parragi Date: Thu, 7 Sep 2023 22:26:24 +0200 Subject: [PATCH] Fixing page pruning / compaction crash Issue: the heap AM has a function which automatically compacts pages when certain conditions are met. When this happens, it moves the tuples around within the page. As encryption uses the offset of tuples for decrypting them, this results in garbage data and possible crashes. Fix: this commit copies the two compaction functions from the server code, and modifies them to re-encrypt data when moved. This is not optimized at all, if needed, we can improve this by a lot. Also, for now only one execution path is handled from the two, as that's the only one hit by sysbench. We'll have to figure out a testcase for the other and fix that too, for now, it only contains an assert(0). --- src/access/pg_tde_prune.c | 450 ++++++++++++++++++++++++++++- src/access/pg_tde_tdemap.c | 2 - src/access/pg_tdeam.c | 4 +- src/encryption/enc_tuple.c | 13 +- src/include/access/pg_tdeam.h | 2 +- src/include/encryption/enc_tuple.h | 4 + src/include/pg_tde_defines.h | 4 + src/keyring/keyring_api.c | 2 - 8 files changed, 465 insertions(+), 16 deletions(-) diff --git a/src/access/pg_tde_prune.c b/src/access/pg_tde_prune.c index 28f36663..3c279666 100644 --- a/src/access/pg_tde_prune.c +++ b/src/access/pg_tde_prune.c @@ -16,6 +16,8 @@ #include "postgres.h" +#include "encryption/enc_tuple.h" + #include "access/pg_tdeam.h" #include "access/pg_tdeam_xlog.h" @@ -392,7 +394,7 @@ pg_tde_page_prune(Relation relation, Buffer buffer, * Apply the planned item changes, then repair page fragmentation, and * update the page's hint bit about whether it has free line pointers. */ - pg_tde_page_prune_execute(buffer, + pg_tde_page_prune_execute(prstate.rel, buffer, prstate.redirected, prstate.nredirected, prstate.nowdead, prstate.ndead, prstate.nowunused, prstate.nunused); @@ -905,6 +907,7 @@ heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum) prstate->marked[offnum] = true; } +void TdePageRepairFragmentation(Relation rel, Buffer buffer, Page page); /* * Perform the actual page changes needed by pg_tde_page_prune. @@ -912,7 +915,7 @@ heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum) * buffer. */ void -pg_tde_page_prune_execute(Buffer buffer, +pg_tde_page_prune_execute(Relation rel, Buffer buffer, OffsetNumber *redirected, int nredirected, OffsetNumber *nowdead, int ndead, OffsetNumber *nowunused, int nunused) @@ -1039,7 +1042,7 @@ pg_tde_page_prune_execute(Buffer buffer, * Finally, repair any fragmentation, and update the page's hint bit about * whether it has free pointers. */ - PageRepairFragmentation(page); + TdePageRepairFragmentation(rel, buffer, page); /* * Now that the page has been modified, assert that redirect items still @@ -1214,3 +1217,444 @@ pg_tde_get_root_tuples(Page page, OffsetNumber *root_offsets) } } } + +// FROM src/page/bufpage.c + +/* + * Tuple defrag support for PageRepairFragmentation and PageIndexMultiDelete + */ +typedef struct itemIdCompactData +{ + uint16 offsetindex; /* linp array index */ + int16 itemoff; /* page offset of item data */ + uint16 len; + uint16 alignedlen; /* MAXALIGN(item data len) */ +} itemIdCompactData; +typedef itemIdCompactData *itemIdCompact; + +/* + * After removing or marking some line pointers unused, move the tuples to + * remove the gaps caused by the removed items and reorder them back into + * reverse line pointer order in the page. + * + * This function can often be fairly hot, so it pays to take some measures to + * make it as optimal as possible. + * + * Callers may pass 'presorted' as true if the 'itemidbase' array is sorted in + * descending order of itemoff. When this is true we can just memmove() + * tuples towards the end of the page. This is quite a common case as it's + * the order that tuples are initially inserted into pages. When we call this + * function to defragment the tuples in the page then any new line pointers + * added to the page will keep that presorted order, so hitting this case is + * still very common for tables that are commonly updated. + * + * When the 'itemidbase' array is not presorted then we're unable to just + * memmove() tuples around freely. Doing so could cause us to overwrite the + * memory belonging to a tuple we've not moved yet. In this case, we copy all + * the tuples that need to be moved into a temporary buffer. We can then + * simply memcpy() out of that temp buffer back into the page at the correct + * location. Tuples are copied back into the page in the same order as the + * 'itemidbase' array, so we end up reordering the tuples back into reverse + * line pointer order. This will increase the chances of hitting the + * presorted case the next time around. + * + * Callers must ensure that nitems is > 0 + */ +static void // this is where it happens! +pgtde_compactify_tuples(Relation rel, Buffer buffer, itemIdCompact itemidbase, int nitems, Page page, bool presorted) +{ + PageHeader phdr = (PageHeader) page; + Offset upper; + Offset copy_tail; + Offset copy_head; + itemIdCompact itemidptr; + int i; + + /* Code within will not work correctly if nitems == 0 */ + Assert(nitems > 0); + + if (presorted) + { + +#ifdef USE_ASSERT_CHECKING + { + /* + * Verify we've not gotten any new callers that are incorrectly + * passing a true presorted value. + */ + Offset lastoff = phdr->pd_special; + + for (i = 0; i < nitems; i++) + { + itemidptr = &itemidbase[i]; + + Assert(lastoff > itemidptr->itemoff); + + lastoff = itemidptr->itemoff; + } + } +#endif /* USE_ASSERT_CHECKING */ + + /* + * 'itemidbase' is already in the optimal order, i.e, lower item + * pointers have a higher offset. This allows us to memmove() the + * tuples up to the end of the page without having to worry about + * overwriting other tuples that have not been moved yet. + * + * There's a good chance that there are tuples already right at the + * end of the page that we can simply skip over because they're + * already in the correct location within the page. We'll do that + * first... + */ + upper = phdr->pd_special; + i = 0; + do + { + itemidptr = &itemidbase[i]; + if (upper != itemidptr->itemoff + itemidptr->alignedlen) + break; + upper -= itemidptr->alignedlen; + + i++; + } while (i < nitems); + + /* + * Now that we've found the first tuple that needs to be moved, we can + * do the tuple compactification. We try and make the least number of + * memmove() calls and only call memmove() when there's a gap. When + * we see a gap we just move all tuples after the gap up until the + * point of the last move operation. + */ + copy_tail = copy_head = itemidptr->itemoff + itemidptr->alignedlen; + for (; i < nitems; i++) + { + ItemId lp; + + itemidptr = &itemidbase[i]; + + if(copy_head < copy_tail) { // TODO: recheck this condition + // We leave the original loop as-is, and recrypt tuples one by one + // This is definitely not the fastest, but simple + Oid tableOid = RelationGetRelid(rel); + BlockNumber bn = BufferGetBlockNumber(buffer); + unsigned long headerSize = sizeof(HeapTupleHeaderData); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wvla" + char tmpData[itemidptr->alignedlen]; +#pragma GCC diagnostic pop + + +#ifdef ENCRYPTION_DEBUG + fprintf(stderr, " >>>> RELOCATING FROM %u to %u tail %u\n", copy_head, upper, copy_tail); + // Decrypt with old offset + fprintf(stderr, " >>>>> DECRYPTING\n"); +#endif + PGTdeCryptTupInternal(tableOid, bn, copy_head, (char*)(page) + copy_head, tmpData, headerSize, itemidptr->len); + // Reencrypt with new offset +#ifdef ENCRYPTION_DEBUG + fprintf(stderr, " >>>>> ENCRYPTING\n"); +#endif + PGTdeCryptTupInternal(tableOid, bn, upper, tmpData, (char*)page + copy_head, headerSize, itemidptr->len); + + } + + lp = PageGetItemId(page, itemidptr->offsetindex + 1); + + if (copy_head != itemidptr->itemoff + itemidptr->alignedlen && copy_head < copy_tail) + { + memmove((char *) page + upper, + page + copy_head, + copy_tail - copy_head); + + /* + * We've now moved all tuples already seen, but not the + * current tuple, so we set the copy_tail to the end of this + * tuple so it can be moved in another iteration of the loop. + */ + copy_tail = itemidptr->itemoff + itemidptr->alignedlen; + } + /* shift the target offset down by the length of this tuple */ + upper -= itemidptr->alignedlen; + /* point the copy_head to the start of this tuple */ + copy_head = itemidptr->itemoff; + + /* update the line pointer to reference the new offset */ + lp->lp_off = upper; + } + + // TODO: it says remaining, but looks like it's only one? + // TODO: exact same block is duplicated twice + if(copy_head < copy_tail) { // TODO: recheck this condition + // We leave the original loop as-is, and recrypt tuples one by one + // This is definitely not the fastest, but simple + // + Oid tableOid = RelationGetRelid(rel); + BlockNumber bn = BufferGetBlockNumber(buffer); + unsigned long headerSize = sizeof(HeapTupleHeaderData); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wvla" + char tmpData[itemidptr->alignedlen]; +#pragma GCC diagnostic pop + +#ifdef ENCRYPTION_DEBUG + fprintf(stderr, " >>>> RELOCATING FROM %u to %u tail %u\n", copy_head, upper, copy_tail); + + // Decrypt with old offset + fprintf(stderr, " >>>>> DECRYPTING\n"); +#endif + PGTdeCryptTupInternal(tableOid, bn, copy_head, (char*)(page) + copy_head, tmpData, headerSize, itemidptr->len); + // Reencrypt with new offset +#ifdef ENCRYPTION_DEBUG + fprintf(stderr, " >>>>> ENCRYPTING\n"); +#endif + PGTdeCryptTupInternal(tableOid, bn, upper, tmpData, (char*)page + copy_head, headerSize, itemidptr->len); + } + + /* move the remaining tuples. */ + memmove((char *) page + upper, + page + copy_head, + copy_tail - copy_head); + } + else + { + Assert(0); // TODO: to be implemented with encryption + PGAlignedBlock scratch; + char *scratchptr = scratch.data; + + /* + * Non-presorted case: The tuples in the itemidbase array may be in + * any order. So, in order to move these to the end of the page we + * must make a temp copy of each tuple that needs to be moved before + * we copy them back into the page at the new offset. + * + * If a large percentage of tuples have been pruned (>75%) then we'll + * copy these into the temp buffer tuple-by-tuple, otherwise, we'll + * just do a single memcpy() for all tuples that need to be moved. + * When so many tuples have been removed there's likely to be a lot of + * gaps and it's unlikely that many non-movable tuples remain at the + * end of the page. + */ + if (nitems < PageGetMaxOffsetNumber(page) / 4) + { + i = 0; + do + { + itemidptr = &itemidbase[i]; + memcpy(scratchptr + itemidptr->itemoff, page + itemidptr->itemoff, + itemidptr->alignedlen); + i++; + } while (i < nitems); + + /* Set things up for the compactification code below */ + i = 0; + itemidptr = &itemidbase[0]; + upper = phdr->pd_special; + } + else + { + upper = phdr->pd_special; + + /* + * Many tuples are likely to already be in the correct location. + * There's no need to copy these into the temp buffer. Instead + * we'll just skip forward in the itemidbase array to the position + * that we do need to move tuples from so that the code below just + * leaves these ones alone. + */ + i = 0; + do + { + itemidptr = &itemidbase[i]; + if (upper != itemidptr->itemoff + itemidptr->alignedlen) + break; + upper -= itemidptr->alignedlen; + + i++; + } while (i < nitems); + + /* Copy all tuples that need to be moved into the temp buffer */ + memcpy(scratchptr + phdr->pd_upper, + page + phdr->pd_upper, + upper - phdr->pd_upper); + } + + /* + * Do the tuple compactification. itemidptr is already pointing to + * the first tuple that we're going to move. Here we collapse the + * memcpy calls for adjacent tuples into a single call. This is done + * by delaying the memcpy call until we find a gap that needs to be + * closed. + */ + copy_tail = copy_head = itemidptr->itemoff + itemidptr->alignedlen; + for (; i < nitems; i++) + { + ItemId lp; + + itemidptr = &itemidbase[i]; + lp = PageGetItemId(page, itemidptr->offsetindex + 1); + + /* copy pending tuples when we detect a gap */ + if (copy_head != itemidptr->itemoff + itemidptr->alignedlen) + { + memcpy((char *) page + upper, + scratchptr + copy_head, + copy_tail - copy_head); + + /* + * We've now copied all tuples already seen, but not the + * current tuple, so we set the copy_tail to the end of this + * tuple. + */ + copy_tail = itemidptr->itemoff + itemidptr->alignedlen; + } + /* shift the target offset down by the length of this tuple */ + upper -= itemidptr->alignedlen; + /* point the copy_head to the start of this tuple */ + copy_head = itemidptr->itemoff; + + /* update the line pointer to reference the new offset */ + lp->lp_off = upper; + } + + /* Copy the remaining chunk */ + memcpy((char *) page + upper, + scratchptr + copy_head, + copy_tail - copy_head); + } + + phdr->pd_upper = upper; +} + +/* + * PageRepairFragmentation + * + * Frees fragmented space on a heap page following pruning. + * + * This routine is usable for heap pages only, but see PageIndexMultiDelete. + * + * This routine removes unused line pointers from the end of the line pointer + * array. This is possible when dead heap-only tuples get removed by pruning, + * especially when there were HOT chains with several tuples each beforehand. + * + * Caller had better have a full cleanup lock on page's buffer. As a side + * effect the page's PD_HAS_FREE_LINES hint bit will be set or unset as + * needed. Caller might also need to account for a reduction in the length of + * the line pointer array following array truncation. + */ +void +TdePageRepairFragmentation(Relation rel, Buffer buffer, Page page) +{ + Offset pd_lower = ((PageHeader) page)->pd_lower; + Offset pd_upper = ((PageHeader) page)->pd_upper; + Offset pd_special = ((PageHeader) page)->pd_special; + Offset last_offset; + itemIdCompactData itemidbase[MaxHeapTuplesPerPage]; + itemIdCompact itemidptr; + ItemId lp; + int nline, + nstorage, + nunused; + OffsetNumber finalusedlp = InvalidOffsetNumber; + int i; + Size totallen; + bool presorted = true; /* For now */ + + /* + * It's worth the trouble to be more paranoid here than in most places, + * because we are about to reshuffle data in (what is usually) a shared + * disk buffer. If we aren't careful then corrupted pointers, lengths, + * etc could cause us to clobber adjacent disk buffers, spreading the data + * loss further. So, check everything. + */ + if (pd_lower < SizeOfPageHeaderData || + pd_lower > pd_upper || + pd_upper > pd_special || + pd_special > BLCKSZ || + pd_special != MAXALIGN(pd_special)) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u", + pd_lower, pd_upper, pd_special))); + + /* + * Run through the line pointer array and collect data about live items. + */ + nline = PageGetMaxOffsetNumber(page); + itemidptr = itemidbase; + nunused = totallen = 0; + last_offset = pd_special; + for (i = FirstOffsetNumber; i <= nline; i++) + { + lp = PageGetItemId(page, i); + if (ItemIdIsUsed(lp)) + { + if (ItemIdHasStorage(lp)) + { + itemidptr->offsetindex = i - 1; + itemidptr->itemoff = ItemIdGetOffset(lp); + + if (last_offset > itemidptr->itemoff) + last_offset = itemidptr->itemoff; + else + presorted = false; + + if (unlikely(itemidptr->itemoff < (int) pd_upper || + itemidptr->itemoff >= (int) pd_special)) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("corrupted line pointer: %u", + itemidptr->itemoff))); + itemidptr->len = ItemIdGetLength(lp); + itemidptr->alignedlen = MAXALIGN(ItemIdGetLength(lp)); + totallen += itemidptr->alignedlen; + itemidptr++; + } + + finalusedlp = i; /* Could be the final non-LP_UNUSED item */ + } + else + { + /* Unused entries should have lp_len = 0, but make sure */ + Assert(!ItemIdHasStorage(lp)); + ItemIdSetUnused(lp); + nunused++; + } + } + + nstorage = itemidptr - itemidbase; + if (nstorage == 0) + { + /* Page is completely empty, so just reset it quickly */ + ((PageHeader) page)->pd_upper = pd_special; + } + else + { + /* Need to compact the page the hard way */ + if (totallen > (Size) (pd_special - pd_lower)) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("corrupted item lengths: total %u, available space %u", + (unsigned int) totallen, pd_special - pd_lower))); + + pgtde_compactify_tuples(rel, buffer, itemidbase, nstorage, page, presorted); + } + + if (finalusedlp != nline) + { + /* The last line pointer is not the last used line pointer */ + int nunusedend = nline - finalusedlp; + + Assert(nunused >= nunusedend && nunusedend > 0); + + /* remove trailing unused line pointers from the count */ + nunused -= nunusedend; + /* truncate the line pointer array */ + ((PageHeader) page)->pd_lower -= (sizeof(ItemIdData) * nunusedend); + } + + /* Set hint bit for PageAddItemExtended */ + if (nunused > 0) + PageSetHasFreeLinePointers(page); + else + PageClearHasFreeLinePointers(page); +} diff --git a/src/access/pg_tde_tdemap.c b/src/access/pg_tde_tdemap.c index c2ad9895..cdead368 100644 --- a/src/access/pg_tde_tdemap.c +++ b/src/access/pg_tde_tdemap.c @@ -10,8 +10,6 @@ *------------------------------------------------------------------------- */ -#define TDE_FORK_DEBUG 1 - #include "postgres.h" #include "access/pg_tde_tdemap.h" #include "transam/pg_tde_xact_handler.h" diff --git a/src/access/pg_tdeam.c b/src/access/pg_tdeam.c index aef070a1..ed706d1e 100644 --- a/src/access/pg_tdeam.c +++ b/src/access/pg_tdeam.c @@ -8799,6 +8799,7 @@ pg_tde_xlog_prune(XLogReaderState *record) int ndead; int nunused; Size datalen; + Relation reln; redirected = (OffsetNumber *) XLogRecGetBlockData(record, 0, &datalen); @@ -8811,7 +8812,8 @@ pg_tde_xlog_prune(XLogReaderState *record) Assert(nunused >= 0); /* Update all line pointers per the record, and repair fragmentation */ - pg_tde_page_prune_execute(buffer, + reln = CreateFakeRelcacheEntry(rlocator); + pg_tde_page_prune_execute(reln, buffer, redirected, nredirected, nowdead, ndead, nowunused, nunused); diff --git a/src/encryption/enc_tuple.c b/src/encryption/enc_tuple.c index 1d0abe4a..3aaf2499 100644 --- a/src/encryption/enc_tuple.c +++ b/src/encryption/enc_tuple.c @@ -1,5 +1,4 @@ #include "pg_tde_defines.h" -#define ENCRYPTION_DEBUG 1 #include "postgres.h" #include "utils/memutils.h" @@ -16,7 +15,7 @@ // t_data and out have to be different addresses without overlap! // The only difference between enc and dec is how we calculate offsetInPage -static void PGTdeCryptTupInternal(Oid tableOid, BlockNumber bn, unsigned long offsetInPage, char* t_data, char* out, unsigned from, unsigned to) +void PGTdeCryptTupInternal(Oid tableOid, BlockNumber bn, unsigned long offsetInPage, char* t_data, char* out, unsigned from, unsigned to) { const uint64_t offsetInFile = (bn * BLCKSZ) + offsetInPage; @@ -44,7 +43,7 @@ static void PGTdeCryptTupInternal(Oid tableOid, BlockNumber bn, unsigned long of Aes128EncryptedZeroBlocks(ki->data.data, aesBlockNumber1, aesBlockNumber2, encKey); #if ENCRYPTION_DEBUG - fprintf(stderr, " ---- (Oid: %i, Len: %u, AesBlock: %lu, BlockOffset: %lu) ----\n", tableOid, to - from, aesBlockNumber1, aesBlockOffset); + fprintf(stderr, " ---- (Oid: %i, Offset: %lu Len: %u, AesBlock: %lu, BlockOffset: %lu) ----\n", tableOid, offsetInPage, to - from, aesBlockNumber1, aesBlockOffset); #endif for(unsigned i = 0; i < to - from; ++i) { const char v = ((char*)(t_data))[i + from]; @@ -56,7 +55,7 @@ static void PGTdeCryptTupInternal(Oid tableOid, BlockNumber bn, unsigned long of } } -static void PGTdeDecryptTupInternal(Oid tableOid, BlockNumber bn, Page page, HeapTupleHeader t_data, char* out, unsigned from, unsigned to) +void PGTdeDecryptTupInternal(Oid tableOid, BlockNumber bn, Page page, HeapTupleHeader t_data, char* out, unsigned from, unsigned to) { const unsigned long offsetInPage = (char*)t_data - (char*)page; #if ENCRYPTION_DEBUG @@ -66,7 +65,7 @@ static void PGTdeDecryptTupInternal(Oid tableOid, BlockNumber bn, Page page, Hea } // t_data and out have to be different addresses without overlap! -static void PGTdeEncryptTupInternal(Oid tableOid, BlockNumber bn, char* page, char* t_data, char* out, unsigned from, unsigned to) +void PGTdeEncryptTupInternal(Oid tableOid, BlockNumber bn, char* page, char* t_data, char* out, unsigned from, unsigned to) { const unsigned long offsetInPage = out - page; #if ENCRYPTION_DEBUG @@ -107,7 +106,7 @@ static void PGTdeDecryptTupInternal2(BlockNumber bn, Page page, HeapTuple tuple, static void PGTdeDecryptTupData(BlockNumber bn, Page page, HeapTuple tuple) { - PGTdeDecryptTupInternal2(bn, page, tuple, sizeof(HeapTupleHeaderData), tuple->t_len, true); + PGTdeDecryptTupInternal2(bn, page, tuple, tuple->t_data->t_hoff, tuple->t_len, true); } OffsetNumber @@ -121,7 +120,7 @@ PGTdePageAddItemExtended(Oid oid, { OffsetNumber off = PageAddItemExtended(page,item,size,offsetNumber,flags); PageHeader phdr = (PageHeader) page; - unsigned long headerSize = sizeof(HeapTupleHeaderData); + unsigned long headerSize = ((HeapTupleHeader)item)->t_hoff; char* toAddr = ((char*)phdr) + phdr->pd_upper; diff --git a/src/include/access/pg_tdeam.h b/src/include/access/pg_tdeam.h index 46047270..864a7a15 100644 --- a/src/include/access/pg_tdeam.h +++ b/src/include/access/pg_tdeam.h @@ -290,7 +290,7 @@ extern int pg_tde_page_prune(Relation relation, Buffer buffer, TimestampTz old_snap_ts, int *nnewlpdead, OffsetNumber *off_loc); -extern void pg_tde_page_prune_execute(Buffer buffer, +extern void pg_tde_page_prune_execute(Relation rel, Buffer buffer, OffsetNumber *redirected, int nredirected, OffsetNumber *nowdead, int ndead, OffsetNumber *nowunused, int nunused); diff --git a/src/include/encryption/enc_tuple.h b/src/include/encryption/enc_tuple.h index c996d040..80b37061 100644 --- a/src/include/encryption/enc_tuple.h +++ b/src/include/encryption/enc_tuple.h @@ -6,6 +6,10 @@ #include "storage/bufpage.h" #include "executor/tuptable.h" +void PGTdeCryptTupInternal(Oid tableOid, BlockNumber bn, unsigned long offsetInPage, char* t_data, char* out, unsigned from, unsigned to); +void PGTdeEncryptTupInternal(Oid tableOid, BlockNumber bn, char* page, char* t_data, char* out, unsigned from, unsigned to); +void PGTdeDecryptTupInternal(Oid tableOid, BlockNumber bn, Page page, HeapTupleHeader t_data, char* out, unsigned from, unsigned to); + /* A wrapper to encrypt a tuple before adding it to the buffer */ OffsetNumber PGTdePageAddItemExtended(Oid oid, BlockNumber bn, Page page, diff --git a/src/include/pg_tde_defines.h b/src/include/pg_tde_defines.h index 3c6dc015..7ead923b 100644 --- a/src/include/pg_tde_defines.h +++ b/src/include/pg_tde_defines.h @@ -19,6 +19,10 @@ * ---------- */ +#define ENCRYPTION_DEBUG 1 +#define KEYRING_DEBUG 1 +#define TDE_FORK_DEBUG 1 + #define pg_tde_fill_tuple heap_fill_tuple #define pg_tde_form_tuple heap_form_tuple #define pg_tde_deform_tuple heap_deform_tuple diff --git a/src/keyring/keyring_api.c b/src/keyring/keyring_api.c index 839f7732..c8b5f4c6 100644 --- a/src/keyring/keyring_api.c +++ b/src/keyring/keyring_api.c @@ -1,6 +1,4 @@ -#define KEYRING_DEBUG 1 - #include "keyring/keyring_api.h" #include "keyring/keyring_file.h"