mirror of
https://github.com/postgres/postgres.git
synced 2025-07-09 22:41:56 +03:00
Prevent excess SimpleLruTruncate() deletion.
Every core SLRU wraps around. With the exception of pg_notify, the wrap
point can fall in the middle of a page. Account for this in the
PagePrecedes callback specification and in SimpleLruTruncate()'s use of
said callback. Update each callback implementation to fit the new
specification. This changes SerialPagePrecedesLogically() from the
style of asyncQueuePagePrecedes() to the style of CLOGPagePrecedes().
(Whereas pg_clog and pg_serial share a key space, pg_serial is nothing
like pg_notify.) The bug fixed here has the same symptoms and user
followup steps as 592a589a04
. Back-patch
to 9.5 (all supported versions).
Reviewed by Andrey Borodin and (in earlier versions) by Tom Lane.
Discussion: https://postgr.es/m/20190202083822.GC32531@gust.leadboat.com
This commit is contained in:
@ -183,6 +183,7 @@ SUBTRANSShmemInit(void)
|
||||
SubtransControlLock, "pg_subtrans");
|
||||
/* Override default assumption that writes should be fsync'd */
|
||||
SubTransCtl->do_fsync = false;
|
||||
SlruPagePrecedesUnitTests(SubTransCtl, SUBTRANS_XACTS_PER_PAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -358,13 +359,8 @@ TruncateSUBTRANS(TransactionId oldestXact)
|
||||
|
||||
|
||||
/*
|
||||
* Decide which of two SUBTRANS page numbers is "older" for truncation purposes.
|
||||
*
|
||||
* We need to use comparison of TransactionIds here in order to do the right
|
||||
* thing with wraparound XID arithmetic. However, if we are asked about
|
||||
* page number zero, we don't want to hand InvalidTransactionId to
|
||||
* TransactionIdPrecedes: it'll get weird about permanent xact IDs. So,
|
||||
* offset both xids by FirstNormalTransactionId to avoid that.
|
||||
* Decide whether a SUBTRANS page number is "older" for truncation purposes.
|
||||
* Analogous to CLOGPagePrecedes().
|
||||
*/
|
||||
static bool
|
||||
SubTransPagePrecedes(int page1, int page2)
|
||||
@ -373,9 +369,10 @@ SubTransPagePrecedes(int page1, int page2)
|
||||
TransactionId xid2;
|
||||
|
||||
xid1 = ((TransactionId) page1) * SUBTRANS_XACTS_PER_PAGE;
|
||||
xid1 += FirstNormalTransactionId;
|
||||
xid1 += FirstNormalTransactionId + 1;
|
||||
xid2 = ((TransactionId) page2) * SUBTRANS_XACTS_PER_PAGE;
|
||||
xid2 += FirstNormalTransactionId;
|
||||
xid2 += FirstNormalTransactionId + 1;
|
||||
|
||||
return TransactionIdPrecedes(xid1, xid2);
|
||||
return (TransactionIdPrecedes(xid1, xid2) &&
|
||||
TransactionIdPrecedes(xid1, xid2 + SUBTRANS_XACTS_PER_PAGE - 1));
|
||||
}
|
||||
|
Reference in New Issue
Block a user