Re: pg_amcheck contrib application
Mark Dilger <mark.dilger@enterprisedb.com>
> On Apr 1, 2021, at 9:56 AM, Robert Haas <robertmhaas@gmail.com> wrote: > > On Thu, Apr 1, 2021 at 12:32 PM Mark Dilger > <mark.dilger@enterprisedb.com> wrote: >>> - If xmax is a multi but seems to be garbled, I changed it to return >>> true rather than false. The inserter is known to have committed by >>> that point, so I think it's OK to try to deform the tuple. We just >>> shouldn't try to check TOAST. >> >> It is hard to know what to do when at least one tuple header field is corrupt. You don't necesarily know which one it is. For example, if HEAP_XMAX_IS_MULTI is set, we try to interpret the xmax as a mxid, and if it is out of bounds, we report it as corrupt. But was the xmax corrupt? Or was the HEAP_XMAX_IS_MULTI bit corrupt? It's not clear. I took the view that if either xmin or xmax appear to be corrupt when interpreted in light of the various tuple header bits, all we really know is that the set of fields/bits don't make sense as a whole, so we report corruption, don't trust any of them, and abort further checking of the tuple. You have be burden of proof the other way around. If the xmin appears fine, and xmax appears corrupt, then we only know that xmax is corrupt, so the tuple is checkable because according to the xmin it committed. > > I agree that it's hard to be sure what's gone once we start finding > corrupted data, but deciding that maybe xmin didn't really commit > because we see that there's something wrong with xmax seems excessive > to me. I thought about a related case: if xmax is a bad multi but is > also hinted invalid, should we try to follow TOAST pointers? I think > that's hard to say, because we don't know whether (1) the invalid > marking is in error, (2) it's wrong to consider it a multi rather than > an XID, (3) the stored multi got overwritten with a garbage value, or > (4) the stored multi got removed before the tuple was frozen. Not > knowing which of those is the case, how are we supposed to decide > whether the TOAST tuples might have been (or be about to get) pruned? > > But, in the case we're talking about here, I don't think it's a > particularly close decision. All we need to say is that if xmax or the > infomask bits pertaining to it are corrupted, we're still going to > suppose that xmin and the infomask bits pertaining to it, which are > all different bytes and bits, are OK. To me, the contrary decision, > namely that a bogus xmax means xmin was probably lying about the > transaction having been committed in the first place, seems like a > serious overreaction. As you say: > >> I don't think how you have it causes undue problems, since deforming the tuple when you shouldn't merely risks a bunch of extra not-so-helpful corruption messages. And hey, maybe they're helpful to somebody clever enough to diagnose why that particular bit of noise was generated. > > I agree. The biggest risk here is that we might omit >0 complaints > when only 0 are justified. That will panic users. The possibility that > we might omit >x complaints when only x are justified, for some x>0, > is also a risk, but it's not nearly as bad, because there's definitely > something wrong, and it's just a question of what it is exactly. So we > have to be really conservative about saying that X is corruption if > there's any possibility that it might be fine. But once we've > complained about one thing, we can take a more balanced approach about > whether to risk issuing more complaints. The possibility that > suppressing the additional complaints might complicate resolution of > the issue also needs to be considered. This all seems fine to me. The main thing is that we don't go on to check the toast, which we don't. >> * If xmin_status happens to be XID_IN_PROGRESS, then in theory >> >> Did you mean to say XID_IS_CURRENT_XID here? > > Yes, I did, thanks. Ouch. You've got a typo: s/XID_IN_CURRENT_XID/XID_IS_CURRENT_XID/ >> /* xmax is an MXID, not an MXID. Sanity check it. */ >> >> Is it an MXID or isn't it? > > Good catch. > > New patch attached. Seems fine other than the typo. — Mark Dilger EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
Commits
-
amcheck: Improve some confusing reports about TOAST problems.
- 50529e5b4e39 14.0 landed
-
amcheck: Reword some messages and fix an alignment problem.
- 9acaf1a62197 14.0 landed
-
amcheck: fix multiple problems with TOAST pointer validation
- ec7ffb8096e8 14.0 landed
-
amcheck: Remove duplicate XID/MXID bounds checks.
- 4573f6a9af6e 14.0 landed
-
amcheck: Fix verify_heapam's tuple visibility checking rules.
- 3b6c1259f9ca 14.0 landed
-
nbtree VACUUM: Cope with buggy opclasses.
- 5b861baa550a 14.0 landed
-
Improve pg_amcheck's TAP test 003_check.pl.
- 87d90ac61fa1 14.0 landed
-
Fix a confusing amcheck corruption message.
- 4078ce65a0f7 14.0 landed
-
Doc: add note about how to run the pg_amcheck regression tests.
- 58f57490facd 14.0 cited
-
In pg_amcheck tests, don't depend on perl's Q/q pack code.
- 945d2cb7d025 14.0 landed
-
pg_amcheck: Keep trying to fix the tests.
- 9e294d0f34d6 14.0 landed
-
pg_amcheck: Try to fix still more test failures.
- 24189277f6ff 14.0 landed
-
Try to avoid apparent platform-dependency in IPC::Run
- f371a4cdba6d 14.0 landed
-
Fix portability issues in pg_amcheck's 004_verify_heapam.pl.
- 661125612706 14.0 landed
-
Try to fix compiler warnings.
- d60e61de4fb4 14.0 landed
-
Add pg_amcheck, a CLI for contrib/amcheck.
- 9706092839db 14.0 landed
-
Refactor and generalize the ParallelSlot machinery.
- f71519e545a3 14.0 landed
-
Remove old-style VACUUM FULL (which was known for a little while as
- 0a469c87692d 9.0.0 cited