Hackers, I'm now exploring code working with heap tuples. The following code in heap_update() catch my eyes.
if (DoesMultiXactIdConflict((MultiXactId) xwait, infomask, > *lockmode)) > { > LockBuffer(buffer, BUFFER_LOCK_UNLOCK); > /* acquire tuple lock, if necessary */ > heap_acquire_tuplock(relation, &(oldtup.t_self), *lockmode, > LockWaitBlock, &have_tuple_lock); > /* wait for multixact */ > MultiXactIdWait((MultiXactId) xwait, mxact_status, infomask, > relation, &oldtup.t_self, XLTW_Update, > &remain); > checked_lockers = true; > locker_remains = remain != 0; > LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); > /* > * If xwait had just locked the tuple then some other xact > * could update this tuple before we get to this point. Check > * for xmax change, and start over if so. > */ > if (xmax_infomask_changed(oldtup.t_data->t_infomask, > infomask) || > !TransactionIdEquals(HeapTupleGetRawXmax(&oldtup), > xwait)) > goto l2; > } Is it safe to rely on same oldtup.t_data pointer after release and re-acquire of buffer content lock? Could the heap tuple be relocated between lock release and re-acquire? I know that we still hold a buffer pin and vacuum would wait for pin release. But other heap operations could still call heap_page_prune() which correspondingly can relocate tuple. Probably, I'm missing something... ------ Alexander Korotkov Postgres Professional: http://www.postgrespro.com The Russian Postgres Company