Last week we fixed a problem in which REINDEX could corrupt pg_index's
own indexes by forbidding it from setting indcheckxmin on a system
catalog's index. While thinking about bug #5985 I realized that there's
a better, more general solution. Namely, that when reindexing an
existing index, there cannot be any need to advance the index's
indcheckxmin horizon. The existing code just blindly pushes the horizon
forward to current time if it finds any possibly-broken HOT chains ---
but if the index existed before, then any HOT chains that are actually
broken with respect to it must predate its existing horizon.
Therefore, when reindexing an existing index, we should never set
indcheckxmin if it wasn't set before. In particular, this rule fixes
the previous issue for system catalogs, which are certain to not have
had indcheckxmin set when initdb made them.
The existing code in index_build also forcibly updates the pg_index
row even if indcheckxmin was already set, thus pushing the row'x xmin
forward and moving the index's usability horizon. This effect isn't
In short, the entire update of pg_index in index_build is unwanted when
reindexing an existing index. index_build doesn't currently know
whether it's being called for a new index or a reindex operation,
but it wouldn't be hard to pass down a flag for that.
I'm intending to revert last week's patch in favor of this approach,
at least in HEAD. It'll be slightly more invasive than the previous
patch because of the API change for index_build, so I'm not sure whether
to back-patch or not --- comments?
regards, tom lane