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 <[email protected]> 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);
}
}