BUG #17903: There is a bug in the KeepLogSeg()

From: PG Bug reporting form <noreply(at)postgresql(dot)org>
To: pgsql-bugs(at)lists(dot)postgresql(dot)org
Cc: xu(dot)xw2008(at)163(dot)com
Subject: BUG #17903: There is a bug in the KeepLogSeg()
Date: 2023-04-19 10:26:13
Message-ID: 17903-4288d439dee856c6@postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

The following bug has been logged on the website:

Bug reference: 17903
Logged by: xu xingwang
Email address: xu(dot)xw2008(at)163(dot)com
PostgreSQL version: 13.3
Operating system: openEuler
Description:

Hi,

I found that KeepLogSeg() has a piece of code that is not correctly.

segno may be larger than currSegNo, since the slot_keep_segs variable is of
type "uint64", in this case the code "if (currSegNo - segno >
slot_keep_segs)" is incorrect.

"if (currSegNo - segno < keep_segs)" is also the same.

Checkpoint calls the KeepLogSeg function, and there are many operations
between recptr and XLogGetReplicationSlotMinimumLSN, including updating the
pg_control file, so segno may be larger than currSegNo.

KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
{
XLogSegNo currSegNo;
XLogSegNo segno;
XLogRecPtr keep;

XLByteToSeg(recptr, currSegNo, wal_segment_size);
segno = currSegNo;

/*
* Calculate how many segments are kept by slots first, adjusting for
* max_slot_wal_keep_size.
*/
keep = XLogGetReplicationSlotMinimumLSN();
if (keep != InvalidXLogRecPtr)
{
XLByteToSeg(keep, segno, wal_segment_size);

/* Cap by max_slot_wal_keep_size ... */
if (max_slot_wal_keep_size_mb >= 0)
{
uint64 slot_keep_segs;

slot_keep_segs =
ConvertToXSegs(max_slot_wal_keep_size_mb, wal_segment_size);

if (currSegNo - segno > slot_keep_segs)
segno = currSegNo - slot_keep_segs;
}
}

/* but, keep at least wal_keep_size if that's set */
if (wal_keep_size_mb > 0)
{
uint64 keep_segs;

keep_segs = ConvertToXSegs(wal_keep_size_mb, wal_segment_size);
if (currSegNo - segno < keep_segs)
{
/* avoid underflow, don't go below 1 */
if (currSegNo <= keep_segs)
segno = 1;
else
segno = currSegNo - keep_segs;
}
}

regards.

--
xu xingwang

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Richard Guo 2023-04-19 10:30:10 Assert failure with ICU support
Previous Message Bruno Bonfils 2023-04-19 09:35:29 About #13489