I found another bug as a result of using amcheck on Heroku customer databases. This time, the bug is in core Postgres. It's one of mine.
There was a thinko in tuplesort's abbreviation abort logic, causing certain SortTuples to be spuriously marked NULL (and so, subsequently sorted as a NULL tuple, despite not actually changing anything about the representation of caller tuples). The attached patch fixes this bug. I noticed this following a complaint by amcheck about a tuple in the wrong order on a leaf page in some random text index. The leaf page was entirely full of NULL values, aside from this one tuple at some seemingly random position. All non-NULL index tuples were of the kind that you'd expect to trigger abbreviation to abort (many distinct values, but with little entropy at the beginning). I believe that this particular problem has been observed on a tiny fraction of all databases tested, so I don't think it's very common in the wild. I'd be surprised if amcheck does not bring more bugs like this to my attention before too long. We should work on improving it, so that we have greater visibility into problems that occur in the field. -- Peter Geoghegan
From d570b9bbfc00cbd861291f47425aa1da1bc32db5 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan <p...@bowt.ie> Date: Fri, 19 Aug 2016 14:34:34 -0700 Subject: [PATCH] Fix thinko in abbreviated key abort code Due to an error in the abbreviated key abort logic, the most recently processed SortTuple could be incorrectly marked NULL, resulting in an incorrect final sort order. This bug may have resulted in corrupt B-Tree indexes in cases where abbreviation is aborted. In general, abbreviation is aborted due to a lack of entropy in the abbreviated keys that were generated so far. --- src/backend/utils/sort/tuplesort.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 510565c..ae384a8 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -1443,7 +1443,7 @@ tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel, mtup->datum1 = index_getattr(tuple, 1, RelationGetDescr(state->indexRel), - &stup.isnull1); + &mtup->isnull1); } } @@ -4271,7 +4271,7 @@ copytup_cluster(Tuplesortstate *state, SortTuple *stup, void *tup) mtup->datum1 = heap_getattr(tuple, state->indexInfo->ii_KeyAttrNumbers[0], state->tupDesc, - &stup->isnull1); + &mtup->isnull1); } } } @@ -4588,7 +4588,7 @@ copytup_index(Tuplesortstate *state, SortTuple *stup, void *tup) mtup->datum1 = index_getattr(tuple, 1, RelationGetDescr(state->indexRel), - &stup->isnull1); + &mtup->isnull1); } } } -- 2.7.4
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers