mirror of
https://github.com/postgres/postgres.git
synced 2025-06-23 14:01:44 +03:00
Avoid amcheck inline compression false positives.
The previous tacit assumption that index_form_tuple() hides differences in the TOAST state of its input datums was wrong. Normalize input varlena datums by decompressing compressed values, and forming a new index tuple for fingerprinting using uncompressed inputs. The final normalized representation may actually be compressed once again within index_form_tuple(), though that shouldn't matter. When the original tuple is found to have no datums that are compressed inline, fingerprint the original tuple directly. Normalization avoids false positive reports of corruption in certain cases. For example, the executor can apply toasting with some inline compression to an entire heap tuple because its input has a single external TOAST pointer. Varlena datums for other attributes that are not particularly good candidates for inline compression can be compressed in the heap tuple in passing, without the representation of the same values in index tuples ever receiving concomitant inline compression. Add a test case to recreate the issue in a simpler though less realistic way: by exploiting differences in pg_attribute.attstorage between heap and index relations. This bug was discovered by me during testing of an upcoming set of nbtree enhancements. It was also independently reported by Andreas Kunert, as bug #15597. His test case was rather more realistic than the one I ended up using. Bug: #15597 Discussion: https://postgr.es/m/CAH2-WznrVd9ie+TTJ45nDT+v2nUt6YJwQrT9SebCdQKtAvfPZw@mail.gmail.com Discussion: https://postgr.es/m/15597-294e5d3e7f01c407@postgresql.org Backpatch: 11-, where heapallindexed verification was introduced.
This commit is contained in:
@ -88,10 +88,26 @@ DELETE FROM delete_test_table WHERE a > 10;
|
||||
VACUUM delete_test_table;
|
||||
SELECT bt_index_parent_check('delete_test_table_pkey', true);
|
||||
|
||||
--
|
||||
-- BUG #15597: must not assume consistent input toasting state when forming
|
||||
-- tuple. Bloom filter must fingerprint normalized index tuple representation.
|
||||
--
|
||||
CREATE TABLE toast_bug(buggy text);
|
||||
ALTER TABLE toast_bug ALTER COLUMN buggy SET STORAGE plain;
|
||||
-- pg_attribute entry for toasty.buggy will have plain storage:
|
||||
CREATE INDEX toasty ON toast_bug(buggy);
|
||||
-- Whereas pg_attribute entry for toast_bug.buggy now has extended storage:
|
||||
ALTER TABLE toast_bug ALTER COLUMN buggy SET STORAGE extended;
|
||||
-- Insert compressible heap tuple (comfortably exceeds TOAST_TUPLE_THRESHOLD):
|
||||
INSERT INTO toast_bug SELECT repeat('a', 2200);
|
||||
-- Should not get false positive report of corruption:
|
||||
SELECT bt_index_check('toasty', true);
|
||||
|
||||
-- cleanup
|
||||
DROP TABLE bttest_a;
|
||||
DROP TABLE bttest_b;
|
||||
DROP TABLE bttest_multi;
|
||||
DROP TABLE delete_test_table;
|
||||
DROP TABLE toast_bug;
|
||||
DROP OWNED BY bttest_role; -- permissions
|
||||
DROP ROLE bttest_role;
|
||||
|
Reference in New Issue
Block a user