提交 a47c62bd 编写于 作者: H Heikki Linnakangas

Avoid "HEAP_MOVED_OFF was expected" errors in VACUUM FULL.

If a page has hint bits set, but the buffer has not been marked as dirty,
and it gets evicted between the 1st and 2nd vacuum pass, the 2nd pass
gets upset. That can't happen in the upstream, as setting a hint bit
always marks the buffer as dirty, but that is not guaranteed in GPDB, because
of gp_disable_tuple_hints.
上级 32df7e2d
......@@ -3279,6 +3279,25 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
* processing this or a higher numbered block.
* ---
*/
/*
* In PostgreSQL, we assume that the first pass of vacuum already
* set the hint bit. However, we cannot rely on that in GPDB,
* because of gp_disable_tuple_hints GUC. If it's ever set, then
* the first pass might've seen that all the hint bits on the page
* were already set, but the backend that set those bits didn't
* mark the buffer as dirty. If the buffer is subsequently evicted
* from the buffer cache, the hint bit updates are lost, and we
* will see them as not set here, even though they were set in the
* first pass.
*
* To fix that, just call HeapTupleSatisfiesVacuum() here to set
* the hint bits again, if not set already.
*/
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
(void) HeapTupleSatisfiesVacuum(tuple.t_data, OldestXmin, buf);
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
if (!(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED))
{
if (tuple.t_data->t_infomask & HEAP_MOVED_IN)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册