Having seen a couple recent reports of "could not access status of transaction" for old, not-obviously-corrupt transaction numbers, I went looking to see if I could find a way that the system could truncate CLOG before it's really marked all occurrences of old transaction numbers as known-dead or known-good.
I found one. The problem is that there are several places where a tqual.c routine is called without checking to see if it changed the tuple's commit hint bits, and without necessarily writing the page immediately after. One example is the code path in heap_update where we decide that we can't update the tuple because a concurrent transaction did so. If HeapTupleSatisfiesUpdate had set the XMIN_COMMITTED or XMAX_COMMITTED bits, those bits would remain set in the shared buffer, but *the buffer would not get marked dirty*. Before PG 7.2 this was not a bug, because the hint bits could always be set again later. But now, consider this scenario: while the buffer remains in memory, VACUUM passes over the table. It doesn't find any changes needed in that page, so it doesn't write the page either. At completion of the vacuum, we check whether we can truncate CLOG, discover we can, and do so. At some later point, the in-memory buffer is discarded, still without having been written. When next read in, the page contains an un-hinted transaction status that could easily point to a transaction before the new CLOG boundary. Ooops. The odds of such a problem seem exceedingly small ... in other words, just about right to explain the small numbers of reports we get. I think what we ought to do to solve this problem permanently is to stop making the callers of the HeapTupleSatisfiesFoo() routines responsible for checking for hint bit updates. It would be a lot safer, and AFAICS not noticeably less efficient, for those routines to call SetBufferCommitInfoNeedsSave for themselves. This would require adding to their parameter lists, because they aren't currently told which buffer the tuple is in, but that's no big deal considering we get to simplify the calling logic in all the places that are faithfully doing the t_infomask update check. Comments? regards, tom lane ---------------------------(end of broadcast)--------------------------- TIP 5: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faqs/FAQ.html