On Wed, 19 Jan 2005 18:57:48 +0100, I wrote: > My first vacuum.c >refactoring patch, rev 1.281 2004-06-08, added these comments in >repair_frag(): > >/* > * VACUUM FULL has an exclusive lock on the relation. So > * normally no other transaction can have pending INSERTs or > * DELETEs in this relation. A tuple is either > * (a) a tuple in a system catalog, inserted or deleted by > * a not yet committed transaction or > * (b) dead (XMIN_INVALID or XMAX_COMMITTED) or > * (c) inserted by a committed xact (XMIN_COMMITTED) or > * (d) moved by the currently running VACUUM. > * In case (a) we wouldn't be in repair_frag() at all. > * In case (b) we cannot be here, because scan_heap() has > * already marked the item as unused, see continue above. > * Case (c) is what normally is to be expected. > * Case (d) is only possible, if a whole tuple chain has been > * moved while processing this or a higher numbered block. > */
It turns out that this comment is not quite correct. It is incomplete. Case (b) should be: known dead (XMIN_INVALID, or XMAX_COMMITTED and xmax is visible to all active transactions). And there is a fifth possibility: (e) deleted (XMAX_COMMITTED) but at least one active transaction does not see the deleting transaction. The patch seems to imply that case (e) is a subcase of (b), but effectively tuples in this state are treated more like (c). Servus Manfred ---------------------------(end of broadcast)--------------------------- TIP 9: the planner will ignore your desire to choose an index scan if your joining column's datatypes do not match