• Heikki Linnakangas's avatar
    Fix predicate-locking of HOT updated rows. · 1169fcf1
    Heikki Linnakangas authored
    In serializable mode, heap_hot_search_buffer() incorrectly acquired a
    predicate lock on the root tuple, not the returned tuple that satisfied
    the visibility checks. As explained in README-SSI, the predicate lock does
    not need to be copied or extended to other tuple versions, but for that to
    work, the correct, visible, tuple version must be locked in the first
    place.
    
    The original SSI commit had this bug in it, but it was fixed back in 2013,
    in commit 81fbbfe3. But unfortunately, it was reintroduced a few months
    later in commit b89e1510. Wising up from that, add a regression test
    to cover this, so that it doesn't get reintroduced again. Also, move the
    code that sets 't_self', so that it happens at the same time that the
    other HeapTuple fields are set, to make it more clear that all the code in
    the loop operate on the "current" tuple in the chain, not the root tuple.
    
    Bug spotted by Andres Freund, analysis and original fix by Thomas Munro,
    test case and some additional changes to the fix by Heikki Linnakangas.
    Backpatch to all supported versions (9.4).
    
    Discussion: https://www.postgresql.org/message-id/20190731210630.nqhszuktygwftjty%40alap3.anarazel.de
    1169fcf1
isolation_schedule 2.08 KB
test: read-only-anomaly
test: read-only-anomaly-2
test: read-only-anomaly-3
test: read-write-unique
test: read-write-unique-2
test: read-write-unique-3
test: read-write-unique-4
test: simple-write-skew
test: receipt-report
test: temporal-range-integrity
test: project-manager
test: classroom-scheduling
test: total-cash
test: referential-integrity
test: ri-trigger
test: partial-index
test: two-ids
test: multiple-row-versions
test: index-only-scan
test: predicate-lock-hot-tuple
test: deadlock-simple
test: deadlock-hard
test: deadlock-soft
test: deadlock-soft-2
test: deadlock-parallel
test: fk-contention
test: fk-deadlock
test: fk-deadlock2
test: fk-partitioned-1
test: fk-partitioned-2
test: eval-plan-qual
test: lock-update-delete
test: lock-update-traversal
test: inherit-temp
test: insert-conflict-do-nothing
test: insert-conflict-do-nothing-2
test: insert-conflict-do-update
test: insert-conflict-do-update-2
test: insert-conflict-do-update-3
test: insert-conflict-toast
test: insert-conflict-specconflict
test: delete-abort-savept
test: delete-abort-savept-2
test: aborted-keyrevoke
test: multixact-no-deadlock
test: multixact-no-forget
test: lock-committed-update
test: lock-committed-keyupdate
test: update-locked-tuple
test: reindex-concurrently
test: propagate-lock-delete
test: tuplelock-conflict
test: tuplelock-update
test: tuplelock-upgrade-no-deadlock
test: freeze-the-dead
test: nowait
test: nowait-2
test: nowait-3
test: nowait-4
test: nowait-5
test: skip-locked
test: skip-locked-2
test: skip-locked-3
test: skip-locked-4
test: drop-index-concurrently-1
test: multiple-cic
test: alter-table-1
test: alter-table-2
test: alter-table-3
test: alter-table-4
test: create-trigger
test: sequence-ddl
test: async-notify
test: vacuum-reltuples
test: timeouts
test: vacuum-concurrent-drop
test: vacuum-conflict
test: vacuum-skip-locked
test: predicate-hash
test: predicate-gist
test: predicate-gin
test: partition-key-update-1
test: partition-key-update-2
test: partition-key-update-3
test: partition-key-update-4
test: plpgsql-toast
test: truncate-conflict
test: serializable-parallel
test: serializable-parallel-2