Re: [COMMITTERS] pgsql: Fix freezing of a dead HOT-updated tuple
Peter Geoghegan <pg@bowt.ie>
From: Peter Geoghegan <pg@bowt.ie>
To: Alvaro Herrera <alvherre@2ndquadrant.com>
Cc: PostgreSQL Hackers <pgsql-hackers@postgresql.org>, "Wood,
Dan" <hexpert@amazon.com>
Date: 2017-10-03T23:10:20Z
Lists: pgsql-hackers
Attachments
- suppress-bad-prune.patch (text/x-patch) patch
On Tue, Oct 3, 2017 at 9:48 AM, Alvaro Herrera <alvherre@2ndquadrant.com> wrote:
> But that still doesn't fix the problem;
> as far as I can see, vacuum removes the root of the chain, not yet sure
> why, and then things are just as corrupted as before.
Are you sure it's not opportunistic pruning? Another thing that I've
noticed with this problem is that the relevant IndexTuple will pretty
quickly vanish, presumably due to LP_DEAD setting (but maybe not
actually due to LP_DEAD setting).
(Studies the problem some more...)
I now think that it actually is a VACUUM problem, specifically a
problem with VACUUM pruning. You see the HOT xmin-to-xmax check
pattern that you mentioned within heap_prune_chain(), which looks like
where the incorrect tuple prune (or possibly, at times, redirect?)
takes place. (I refer to the prune/kill that you mentioned today, that
frustrated your first attempt at a fix -- "I modified the multixact
freeze code...".)
The attached patch "fixes" the problem -- I cannot get amcheck to
complain about corruption with this applied. And, "make check-world"
passes. Hopefully it goes without saying that this isn't actually my
proposed fix. It tells us something that this at least *masks* the
problem, though; it's a start.
FYI, the repro case page contents looks like this with the patch applied:
postgres=# select lp, lp_flags, t_xmin, t_xmax, t_ctid,
to_hex(t_infomask) as infomask,
to_hex(t_infomask2) as infomask2
from heap_page_items(get_raw_page('t', 0));
lp | lp_flags | t_xmin | t_xmax | t_ctid | infomask | infomask2
----+----------+---------+--------+--------+----------+-----------
1 | 1 | 1845995 | 0 | (0,1) | b02 | 3
2 | 2 | | | | |
3 | 0 | | | | |
4 | 0 | | | | |
5 | 0 | | | | |
6 | 0 | | | | |
7 | 1 | 1846001 | 0 | (0,7) | 2b02 | 8003
(7 rows)
--
Peter Geoghegan
Commits
-
Backport addition of rs_old_rel to rewriteheap's state.
- 152a56905658 9.3.21 landed
-
Perform a lot more sanity checks when freezing tuples.
- ed8e1aff6ace 9.4.16 landed
- d3044f8b0732 10.2 landed
- 986a9153b970 9.6.7 landed
- 94d1c88103ff 9.5.11 landed
- 4800f16a7ad0 9.3.21 landed
- 699bf7d05c68 11.0 landed
-
Revert bogus fixes of HOT-freezing bug
- c6764eb3aea6 11.0 landed
- f05ae2fa94b4 9.3.20 landed
- ef0339ee5dcf 9.4.15 landed
- b3888b60d3f0 9.5.10 landed
- 7a95966bc03c 10.1 landed
- 08ba67d596a1 9.6.6 landed
-
Fix traversal of half-frozen update chains
- a5736bf754c8 11.0 landed
- fc0df3bdafd6 9.5.10 landed
- d441cff14249 9.6.6 landed
- b052d524ca71 9.3.20 landed
- 8b6d85f2dc1e 9.4.15 landed
- 22576734b805 10.1 landed
-
Fix freezing of a dead HOT-updated tuple
- 46c35116ae1a 10.0 cited
- 20b655224249 11.0 cited
-
During index build, check and elog (not just Assert) for broken HOT chain.
- d70cf811f7dd 9.4.0 cited
-
Fix WAL replay of locking an updated tuple
- 6bfa88acd3df 9.4.0 cited
-
Change the way we mark tuples as frozen.
- 37484ad2aace 9.4.0 cited