On Sun, Jul 28, 2019 at 10:33:03PM -0400, Bruce Momjian wrote: > I am thinking of writing some Assert() code that checks that all buffers > using a single LSN are from the same relation (and therefore different > page numbers). I would do it by creating a static array, clearing it on > XLogBeginInsert(), adding to it for each XLogInsert(), then checking on > PageSetLSN() that everything in the array is from the same file. Does > that make sense?
So, I started looking at how to implement the Assert checks and found that Heikki has already added (in commit 2c03216d83) Assert checks to avoid duplicate block numbers in WAL. I just added the attached patch to check that all RelFileNodes are the same. I ran the regression tests with asserts on and got no failures, so I think we are good. -- Bruce Momjian <br...@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + As you are, so once was I. As I am, so you will be. + + Ancient Roman grave inscription +
diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c new file mode 100644 index 3ec67d4..f6c678c *** a/src/backend/access/transam/xloginsert.c --- b/src/backend/access/transam/xloginsert.c *************** XLogRegisterBuffer(uint8 block_id, Buffe *** 235,241 **** /* * Check that this page hasn't already been registered with some other ! * block_id. */ #ifdef USE_ASSERT_CHECKING { --- 235,241 ---- /* * Check that this page hasn't already been registered with some other ! * block_id, and check for different RelFileNodes in the WAL record. */ #ifdef USE_ASSERT_CHECKING { *************** XLogRegisterBuffer(uint8 block_id, Buffe *** 248,255 **** if (i == block_id || !regbuf_old->in_use) continue; ! Assert(!RelFileNodeEquals(regbuf_old->rnode, regbuf->rnode) || ! regbuf_old->forkno != regbuf->forkno || regbuf_old->block != regbuf->block); } } --- 248,267 ---- if (i == block_id || !regbuf_old->in_use) continue; ! /* ! * The initialization vector (IV) is used for page-level ! * encryption. We use the LSN and page number as the IV, and IV ! * values must never be reused since it is insecure. It is safe ! * to use the LSN on multiple pages in the same relation since ! * the page number is part of the IV. It is unsafe to reuse the ! * LSN in different relations because the page number might be ! * the same, and hence the IV. Therefore, we check here that ! * we don't have WAL records for different relations using the ! * same LSN. ! */ ! Assert(RelFileNodeEquals(regbuf_old->rnode, regbuf->rnode)); ! ! Assert(regbuf_old->forkno != regbuf->forkno || regbuf_old->block != regbuf->block); } }