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

Поиск
Список
Период
Сортировка
От PG Bug reporting form
Тема BUG #17903: There is a bug in the KeepLogSeg()
Дата
Msg-id 17903-4288d439dee856c6@postgresql.org
обсуждение исходный текст
Ответы Re: BUG #17903: There is a bug in the KeepLogSeg()  (Kyotaro Horiguchi <horikyota.ntt@gmail.com>)
Список pgsql-bugs
The following bug has been logged on the website:

Bug reference:      17903
Logged by:          xu xingwang
Email address:      xu.xw2008@163.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


В списке pgsql-bugs по дате отправления:

Предыдущее
От: Bruno Bonfils
Дата:
Сообщение: About #13489
Следующее
От: Richard Guo
Дата:
Сообщение: Assert failure with ICU support