• Peter Geoghegan's avatar
    Don't leave behind junk nbtree pages during split. · 9b42e713
    Peter Geoghegan authored
    Commit 8fa30f90 reduced the elevel of a number of "can't happen"
    _bt_split() errors from PANIC to ERROR.  At the same time, the new right
    page buffer for the split could continue to be acquired well before the
    critical section.  This was possible because it was relatively
    straightforward to make sure that _bt_split() could not throw an error,
    with a few specific exceptions.  The exceptional cases were safe because
    they involved specific, well understood errors, making it possible to
    consistently zero the right page before actually raising an error using
    elog().  There was no danger of leaving around a junk page, provided
    _bt_split() stuck to this coding rule.
    
    Commit 8224de4f, which introduced INCLUDE indexes, added code to make
    _bt_split() truncate away non-key attributes.  This happened at a point
    that broke the rule around zeroing the right page in _bt_split().  If
    truncation failed (perhaps due to palloc() failure), that would result
    in an errant right page buffer with junk contents.  This could confuse
    VACUUM when it attempted to delete the page, and should be avoided on
    general principle.
    
    To fix, reorganize _bt_split() so that truncation occurs before the new
    right page buffer is even acquired.  A junk page/buffer will not be left
    behind if _bt_nonkey_truncate()/_bt_truncate() raise an error.
    
    Discussion: https://postgr.es/m/CAH2-WzkcWT_-NH7EeL=Az4efg0KCV+wArygW8zKB=+HoP=VWMw@mail.gmail.com
    Backpatch: 11-, where INCLUDE indexes were introduced.
    9b42e713
nbtinsert.c 74.9 KB