Re: Add 64-bit XIDs into PostgreSQL 15 - Mailing list pgsql-hackers
From | Daniil Davydov |
---|---|
Subject | Re: Add 64-bit XIDs into PostgreSQL 15 |
Date | |
Msg-id | CAJDiXghosLZQzBfsTf7QCoo-eTGAyYOBa90A46Et=udbL0_QPA@mail.gmail.com Whole thread Raw |
In response to | Re: Add 64-bit XIDs into PostgreSQL 15 ("Maksim.Melnikov" <m.melnikov@postgrespro.ru>) |
Responses |
Re: Add 64-bit XIDs into PostgreSQL 15
|
List | pgsql-hackers |
Hi, On Thu, Jul 17, 2025 at 8:36 PM Maksim.Melnikov <m.melnikov@postgrespro.ru> wrote: > > On 07.07.2025 11:17, Evgeny Voropaev wrote: > > Do-side: > > 1. Having page ABC with several tuples. > > 2. Starting to perform insertion of new tuple > > 2.1. In the case of an inappropriate xid_base, trying to fit base > > 2.1.1 Freezing and pruning tuples without further repairing > > fragmentation. > > 2.1.2 All tuples have been pruned (no alive tuples on the page > > since this moment) > > 3. Inserting a new tuple and setting XLOG_HEAP_INIT_PAGE, assuming > > that the only tuple located at the bottom of the page (assuming that > > fragmentation has been performed). > > > > > > Result: We have the ABC page with the new tuple inserted somewhere in > > the MIDDLE of the page and surrounded with garbage from dead and > > unused tuples. At the same time we have an xlog record bringing the > > XLOG_HEAP_INIT_PAGE bit. > > > > Redo-side > > 1. Observing XLOG_HEAP_INIT_PAGE > > 2. Creating a new page and inserting the new tuple into the first > > position of the page. > > > Evgeny, I've tried to reproduce described scenario, but I can't get > XLOG_HEAP_INIT_PAGE bit set. > > In attached file you can find detailed test description with results, so > you can repeat it. > > Maybe I missed something in your scenario, can you please clarify? > Or maybe it is't reproducable at all. > I have also tried to reproduce this bug. To do this, we need several conditions: 1) New tuple must be "linked" with the first line pointer on page 2) At the time the new tuple is inserted, there should be another tuple (A) on the page. 3) Freeze&prune must be able to truncate line pointer of the tuple (A) We can easily reach (1), (2) conditions : 1. Insert two tuples; 2. Delete first of them; 4. Call vacuum on table 5. Delete second tuple 6. Advance xid into the future (for example, via pg_resetwal) 6. Insert new tuple Thus, the new tuple will be associated with the first line pointer, and the page will have one dead tuple (associated with the second line pointer). But as far as I understand, (3) condition is unreachable, because we just cannot truncate the line pointer of the second tuple (and prune tuple itself). Possibly, it could have happened inside freeze_single_heap_page, but this function cannot mark the line pointer of the second tuple as LP_UNUSED (we don't specify HEAP_PAGE_PRUNE_MARK_UNUSED_NOW flag for heap_page_prune_and_freeze call). As a result, the page will always have more than one line pointer. Interference of parallel operations is excluded because we have an exclusive lock on buffer during heap_page_prepare_for_xid call. Maybe we have operations that might mark line pointers as unused without repairing fragmentation (it might be useful for reproduction of this bug), but I didn't find any. BTW, I think that "phdr->pd_special == phdr->pd_upper" is the best way to decide whether we need to set the XLOG_HEAP_INIT_PAGE flag to WAL record (at least this would eliminate the occurrence of the described problem). -- Best regards, Daniil Davydov
pgsql-hackers by date: