On Fri, Aug 12, 2016 at 3:15 PM, Alexander Korotkov < a.korot...@postgrespro.ru> wrote:
> 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... > Please, forget it. heap_page_prune_opt() do: > /* OK, try to get exclusive buffer lock */ > if (!ConditionalLockBufferForCleanup(buffer)) > return; Nobody repairs buffer fragmentation while there is a pin. Everything is right. ------ Alexander Korotkov Postgres Professional: http://www.postgrespro.com The Russian Postgres Company