Re: Patch: Global Unique Index

From: David Zhang <david(dot)zhang(at)highgo(dot)ca>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Bruce Momjian <bruce(at)momjian(dot)us>
Cc: Greg Stark <stark(at)mit(dot)edu>, Simon Riggs <simon(dot)riggs(at)enterprisedb(dot)com>, Cary Huang <cary(dot)huang(at)highgo(dot)ca>, Pgsql Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Patch: Global Unique Index
Date: 2022-12-03 00:05:08
Message-ID: 6b69efba-5f4f-04a5-46b4-b92e38cbb69b@highgo.ca
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 2022-11-29 6:16 p.m., Tom Lane wrote:
> Assuming that you are inserting into index X, and you've checked
> index Y to find that it has no conflicts, what prevents another
> backend from inserting a conflict into index Y just after you look?
> AIUI the idea is to prevent that by continuing to hold an exclusive
> lock on the whole index Y until you've completed the insertion.
> Perhaps there's a better way to do that, but it's not what was
> described.
Another main change in patch
`0004-support-global-unique-index-insert-and-update.patch`,
+                search_global:
+                        stack = _bt_search(iRel, insertstate.itup_key,
+                                           &insertstate.buf, BT_READ,
NULL);
+                        xwait = _bt_check_unique_gi(iRel, &insertstate,
+                                                    hRel, checkUnique,
&is_unique,
+ &speculativeToken, heapRel);
+                        if (unlikely(TransactionIdIsValid(xwait)))
+                        {
... ...
+                            goto search_global;
+                        }

Here, I am trying to use `BT_READ` to require a LW_SHARED lock on the
buffer block if a match found using `itup_key` search key. The
cross-partition uniqueness checking will wait if the index tuple
insertion on this buffer block has not done yet, otherwise runs the
uniqueness check to see if there is an ongoing transaction which may
insert a conflict value. Once the ongoing insertion is done, it will go
back and check again (I think it can also handle the case that a
potential conflict index tuple was later marked as dead in the same
transaction). Based on this change, my test results are:

1) a select-only query will not be blocked by the ongoing insertion on
index X

2) insertion happening on index Y may wait for the buffer block lock
when inserting a different value but it does not wait for the
transaction lock held by insertion on index X.

3) when an insertion inserting a conflict value on index Y,
    3.1) it waits for buffer block lock if the lock has been held by
the insertion on index X.
    3.2) then, it waits for transaction lock until the insertion on
index X is done.

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Nathan Bossart 2022-12-03 00:31:58 Re: WAL Insertion Lock Improvements (was: Re: Avoid LWLockWaitForVar() for currently held WAL insertion lock in WaitXLogInsertionsToFinish())
Previous Message Zheng Li 2022-12-02 23:48:59 Re: Support logical replication of DDLs