On Wed, Jan 16, 2019 at 5:24 AM Robert Haas <robertmh...@gmail.com> wrote: > > On Mon, Jan 14, 2019 at 9:24 PM Masahiko Sawada <sawada.m...@gmail.com> wrote: > > I think that because the tuples that got dead after heap_page_prune() > > looked are recorded but not removed without lazy_vacuum_page() we need > > to process them in lazy_vacuum_page(). For decision about whether to > > truncate we should not change it, so I will fix it. It should be an > > another option to control whether to truncate if we want. > > I think that heap_page_prune() is going to truncate dead tuples to > dead line pointers. At that point the tuple is gone. The only > remaining step is to mark the dead line pointer as unused, which can't > be done without scanning the indexes. So I don't understand what > lazy_vacuum_page() would need to do in this case. >
vacuumlazy.c:L1022 switch (HeapTupleSatisfiesVacuum(&tuple, OldestXmin, buf)) { case HEAPTUPLE_DEAD: /* * Ordinarily, DEAD tuples would have been removed by * heap_page_prune(), but it's possible that the tuple * state changed since heap_page_prune() looked. In * particular an INSERT_IN_PROGRESS tuple could have * changed to DEAD if the inserter aborted. So this * cannot be considered an error condition. * (snip) */ if (HeapTupleIsHotUpdated(&tuple) || HeapTupleIsHeapOnly(&tuple)) nkeep += 1; else tupgone = true; /* we can delete the tuple */ all_visible = false; break; As the above comment says, it's possible that the state of an INSERT_IN_PROGRESS tuple could be changed to 'dead' after heap_page_prune(). Since such tuple is not truncated at this point we record it and set it as UNUSED in lazy_vacuum_page(). I think that the DISABLE_INDEX_CLEANUP case is the same; we need to process them after recorded. Am I missing something? Regards, -- Masahiko Sawada NIPPON TELEGRAPH AND TELEPHONE CORPORATION NTT Open Source Software Center