Skip to content

Commit 5a2f154

Browse files
Improve nbtree README's LP_DEAD section.
The description of how LP_DEAD bit setting by index scans works following commit 2ed5b87 was rather unclear. Clean that up a bit. Also refer to LP_DEAD bit setting within _bt_check_unique() at the start of the same section. This mechanism may actually be more important than the generic kill_prior_tuple mechanism that the section focuses on, so it at least deserves to be mentioned in passing.
1 parent 52eec1c commit 5a2f154

File tree

1 file changed

+13
-7
lines changed
  • src/backend/access/nbtree

1 file changed

+13
-7
lines changed

src/backend/access/nbtree/README

+13-7
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,10 @@ allowing subsequent index scans to skip visiting the heap tuple. The
429429
"known dead" marking works by setting the index item's lp_flags state
430430
to LP_DEAD. This is currently only done in plain indexscans, not bitmap
431431
scans, because only plain scans visit the heap and index "in sync" and so
432-
there's not a convenient way to do it for bitmap scans.
432+
there's not a convenient way to do it for bitmap scans. Note also that
433+
LP_DEAD bits are often set when checking a unique index for conflicts on
434+
insert (this is simpler because it takes place when we hold an exclusive
435+
lock on the leaf page).
433436

434437
Once an index tuple has been marked LP_DEAD it can actually be removed
435438
from the index immediately; since index scans only stop "between" pages,
@@ -456,12 +459,15 @@ that this breaks the interlock between VACUUM and indexscans, but that is
456459
not so: as long as an indexscanning process has a pin on the page where
457460
the index item used to be, VACUUM cannot complete its btbulkdelete scan
458461
and so cannot remove the heap tuple. This is another reason why
459-
btbulkdelete has to get a super-exclusive lock on every leaf page, not
460-
only the ones where it actually sees items to delete. So that we can
461-
handle the cases where we attempt LP_DEAD flagging for a page after we
462-
have released its pin, we remember the LSN of the index page when we read
463-
the index tuples from it; we do not attempt to flag index tuples as dead
464-
if the we didn't hold the pin the entire time and the LSN has changed.
462+
btbulkdelete has to get a super-exclusive lock on every leaf page, not only
463+
the ones where it actually sees items to delete.
464+
465+
LP_DEAD setting by index scans cannot be sure that a TID whose index tuple
466+
it had planned on LP_DEAD-setting has not been recycled by VACUUM if it
467+
drops its pin in the meantime. It must conservatively also remember the
468+
LSN of the page, and only act to set LP_DEAD bits when the LSN has not
469+
changed at all. (Avoiding dropping the pin entirely also makes it safe, of
470+
course.)
465471

466472
WAL Considerations
467473
------------------

0 commit comments

Comments
 (0)