Re: serializable transaction: exclude constraint violation (backed by GIST index) instead of ssi conflict

From: Thomas Munro <thomas(dot)munro(at)gmail(dot)com>
To: Peter Billen <peter(dot)billen(at)gmail(dot)com>
Cc: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: serializable transaction: exclude constraint violation (backed by GIST index) instead of ssi conflict
Date: 2019-04-10 22:54:44
Message-ID: CA+hUKGLC84WjMo_1qVYN30HKNbrE2BJsGf4UTFAZB3ZuXzU7QA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, Apr 11, 2019 at 9:43 AM Peter Billen <peter(dot)billen(at)gmail(dot)com> wrote:
> I understood that v11 includes predicate locking for gist indexes, as per https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=3ad55863e9392bff73377911ebbf9760027ed405.
>
> I tried this in combination with an exclude constraint as following:
>
> drop table if exists t;
> create table t(period tsrange);
> alter table t add constraint bla exclude using gist(period with &&);
> -- t1
> begin transaction isolation level serializable;
> select * from t where period && tsrange(now()::timestamp, now()::timestamp + interval '1 hour');
> insert into t(period) values(tsrange(now()::timestamp, now()::timestamp + interval '1 hour'));
> -- t2
> begin transaction isolation level serializable;
> select * from t where period && tsrange(now()::timestamp, now()::timestamp + interval '1 hour');
> insert into t(period) values(tsrange(now()::timestamp, now()::timestamp + interval '1 hour'));
> -- t1
> commit;
> -- t2
> ERROR: conflicting key value violates exclusion constraint "bla"
> DETAIL: Key (period)=(["2019-04-10 20:59:20.6265","2019-04-10 21:59:20.6265")) conflicts with existing key (period)=(["2019-04-10 20:59:13.332622","2019-04-10 21:59:13.332622")).
>
> I kinda expected/hoped that transaction t2 would get aborted by a serialization error, and not an exclude constraint violation. This makes the application session bound to transaction t2 failing, as only serialization errors are retried.
>
> We introduced the same kind of improvement/fix for btree indexes earlier, see https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=fcff8a575198478023ada8a48e13b50f70054766. Should this also be applied for (exclude) constraints backed by a gist index (as gist indexes now support predicate locking), or am I creating incorrect assumptions something here?

Hi Peter,

Yeah, I agree, the behaviour you are expecting is desirable and we
should figure out how to do that. The basic trick for btree unique
constraints was to figure out where the index *would* have written, to
give the SSI machinery a chance to object to that before raising the
UCV. I wonder if we can use the same technique here... at first
glance, check_exclusion_or_unique_constraint() is raising the error,
but is not index AM specific code, and it is somewhat removed from the
GIST code that would do the equivalent
CheckForSerializableConflictIn() call. I haven't looked into it
properly, but that certainly complicates matters somewhat... Perhaps
the index AM would actually need a new entrypoint that could be called
before the error is raised, or perhaps there is an easier way.

--
Thomas Munro
https://enterprisedb.com

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Euler Taveira 2019-04-10 23:09:34 Re: Should the docs have a warning about pg_stat_reset()?
Previous Message Tom Lane 2019-04-10 22:54:25 Re: Reducing the runtime of the core regression tests