| 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: | Whole Thread | Raw Message | 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
| 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 |