Hi, Andrew! On Mon, Oct 2, 2017 at 1:40 PM, Andrew Borodin <amborodi...@gmail.com> wrote:
> Thanks for looking into the patch! > > On Thu, Sep 28, 2017 at 3:59 PM, Alexander Korotkov < > a.korot...@postgrespro.ru> wrote: > >> >> >> In gistdoinsert() you do CheckForSerializableConflictIn() only if page >> wasn't exclusively locked before (xlocked is false). >> >> if (!xlocked) >>> { >>> LockBuffer(stack->buffer, GIST_UNLOCK); >>> LockBuffer(stack->buffer, GIST_EXCLUSIVE); >>> CheckForSerializableConflictIn(r, NULL, stack->buffer); >>> xlocked = true; >> >> >> However, page might be exclusively locked before. And in this case >> CheckForSerializableConflictIn() would be skipped. That happens very >> rarely (someone fixes incomplete split before we did), but nevertheless. >> > > if xlocked = true, page was already checked for conflict after setting > exclusive lock on it's buffer. I still do not see any problem here... > What happen if exactly this "continue" fires? if (GistFollowRight(stack->page)) > { > if (!xlocked) > { > LockBuffer(stack->buffer, GIST_UNLOCK); > LockBuffer(stack->buffer, GIST_EXCLUSIVE); > xlocked = true; > /* someone might've completed the split when we unlocked */ > if (!GistFollowRight(stack->page)) > continue; In this case we might get xlocked == true without calling CheckForSerializableConflictIn(). This is very rare codepath, but still... I think it would be rather safe and easy for understanding to more CheckForSerializableConflictIn() directly before gistinserttuple(). ------ Alexander Korotkov Postgres Professional: http://www.postgrespro.com The Russian Postgres Company