From f644f3db51d203a7e4736f8e4bc3da7637be09f9 Mon Sep 17 00:00:00 2001 From: James Coleman Date: Fri, 29 Sep 2023 17:00:56 +0000 Subject: [PATCH v2] Correct HOT docs to account for LP_REDIRECT The original idea here was to correct the claim that index entries never point to old row versions, but upon further reflection I concluded that what we really needed was to break out the page pruning information into its own section since it applies to more than just HOT. --- doc/src/sgml/storage.sgml | 45 ++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/doc/src/sgml/storage.sgml b/doc/src/sgml/storage.sgml index 148fb1b49d..4c338f018e 100644 --- a/doc/src/sgml/storage.sgml +++ b/doc/src/sgml/storage.sgml @@ -1121,20 +1121,16 @@ data. Empty in ordinary tables. - Old versions of updated rows can be completely removed during normal - operation, including SELECTs, instead of requiring - periodic vacuum operations. (This is possible because indexes - do not reference their page - item identifiers.) + Old versions of updated rows may be + pruned during normal operation, including SELECTs, + instead of requiring periodic vacuum operations. - In summary, heap-only tuple updates can only be created - if columns used by indexes are not updated. You can - increase the likelihood of sufficient page space for + You can increase the likelihood of sufficient page space for HOT updates by decreasing a table's fillfactor. If you don't, HOT updates will still happen because @@ -1145,4 +1141,37 @@ data. Empty in ordinary tables. + + + Page Pruning + + + In addition to standard vacuum operations, PostgreSQL + opportunistically cleans and compacts pages during normal operations, + including SELECTs. + + + + Row versions no longer visible to any transaction have their tuple data + removed, but because indexes always refer to the + page item identifiers of the + original row version, the line pointer must remain in place. If that row + was previously updated with a heap-only tuple, + the line pointer has its LP_REDIRECT bit set and its + offset updated to the page item identifiers + of the updated row; otherwise the line point has its LP_DEAD + bit set. + + + + When a row is updated multiple times with + heap-only tuples, intermediate versions + that are no longer visible to anyone are completely removed, and the + associated page item identifiers are made available for reuse. Removing + these rows entirely is safe because indexes always refer to the + page item identifiers of the + original row version. + + + -- 2.30.2