diff options
author | Noah Misch <noah@leadboat.com> | 2021-01-16 12:21:35 -0800 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2021-01-16 12:21:35 -0800 |
commit | 6db992833c04c0322f7f34a486adece01651f929 (patch) | |
tree | 3ef1ce108c34f616ef2603b49e5c2cbd3ca232ba /src/backend/commands/async.c | |
parent | c95765f47673b16ed36acbfe98e1242e3c3822a3 (diff) | |
download | postgresql-6db992833c04c0322f7f34a486adece01651f929.tar.gz postgresql-6db992833c04c0322f7f34a486adece01651f929.zip |
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 592a589a04bd456410b853d86bd05faa9432cbbb. 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
Diffstat (limited to 'src/backend/commands/async.c')
-rw-r--r-- | src/backend/commands/async.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 7c133ec8d33..42b232d98b1 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -490,7 +490,12 @@ asyncQueuePageDiff(int p, int q) return diff; } -/* Is p < q, accounting for wraparound? */ +/* + * Is p < q, accounting for wraparound? + * + * Since asyncQueueIsFull() blocks creation of a page that could precede any + * extant page, we need not assess entries within a page. + */ static bool asyncQueuePagePrecedes(int p, int q) { @@ -1352,8 +1357,8 @@ asyncQueueIsFull(void) * logically precedes the current global tail pointer, ie, the head * pointer would wrap around compared to the tail. We cannot create such * a head page for fear of confusing slru.c. For safety we round the tail - * pointer back to a segment boundary (compare the truncation logic in - * asyncQueueAdvanceTail). + * pointer back to a segment boundary (truncation logic in + * asyncQueueAdvanceTail does not do this, so doing it here is optional). * * Note that this test is *not* dependent on how much space there is on * the current head page. This is necessary because asyncQueueAddEntries |