Обсуждение: BUG #13920: pg_try_advisory_xact_lock bigint trouble

Поиск
Список
Период
Сортировка

BUG #13920: pg_try_advisory_xact_lock bigint trouble

От
mtakvel@gmail.com
Дата:
The following bug has been logged on the website:

Bug reference:      13920
Logged by:          Valeriy
Email address:      mtakvel@gmail.com
PostgreSQL version: 9.5.0
Operating system:   Ubuntu
Description:

Hello, I have few high load big tables. My logic calls
pg_try_advisory_xact_lock(bitint) for locking row in current table. As I see
with bigint param pg_try_advisory_xact_lock lock same ids for all my tables.
Insthead lock only row in one current table. Looks like this is bug and will
be cool if you fix it.

Re: BUG #13920: pg_try_advisory_xact_lock bigint trouble

От
"David G. Johnston"
Дата:
On Friday, February 5, 2016, <mtakvel@gmail.com> wrote:

> The following bug has been logged on the website:
>
> Bug reference:      13920
> Logged by:          Valeriy
> Email address:      mtakvel@gmail.com <javascript:;>
> PostgreSQL version: 9.5.0
> Operating system:   Ubuntu
> Description:
>
> Hello, I have few high load big tables. My logic calls
> pg_try_advisory_xact_lock(bitint) for locking row in current table. As I
> see
> with bigint param pg_try_advisory_xact_lock lock same ids for all my
> tables.
> Insthead lock only row in one current table. Looks like this is bug and
> will
> be cool if you fix it.
>
>
Likely working as designed.  If you wish to provide an example of what you
are doing we can probably explain your misunderstanding.  Basically,
though, there is nothing about the ID you pass to the advisory lock
functions that cause them to be associated with a table.  The ID is simply
a number.   You should try the two-key version and associate the first key
with the table (probably oid) and the second with the row on that table.

David J.

Re: BUG #13920: pg_try_advisory_xact_lock bigint trouble

От
"David G. Johnston"
Дата:
On Monday, February 8, 2016, David G. Johnston <david.g.johnston@gmail.com>
wrote:

> On Friday, February 5, 2016, <mtakvel@gmail.com
> <javascript:_e(%7B%7D,'cvml','mtakvel@gmail.com');>> wrote:
>
>> The following bug has been logged on the website:
>>
>> Bug reference:      13920
>> Logged by:          Valeriy
>> Email address:      mtakvel@gmail.com
>> PostgreSQL version: 9.5.0
>> Operating system:   Ubuntu
>> Description:
>>
>> Hello, I have few high load big tables. My logic calls
>> pg_try_advisory_xact_lock(bitint) for locking row in current table. As I
>> see
>> with bigint param pg_try_advisory_xact_lock lock same ids for all my
>> tables.
>> Insthead lock only row in one current table. Looks like this is bug and
>> will
>> be cool if you fix it.
>>
>>
> Likely working as designed.  If you wish to provide an example of what you
> are doing we can probably explain your misunderstanding.  Basically,
> though, there is nothing about the ID you pass to the advisory lock
> functions that cause them to be associated with a table.  The ID is simply
> a number.   You should try the two-key version and associate the first key
> with the table (probably oid) and the second with the row on that table.
>
>
Though the two-arg uses Integer so maybe not...

You should poprobably explain your use case a bit on the -general list if
you'd like to discuss alternatives.  But the behavior described is how
things work right now.

 David J.

Re: BUG #13920: pg_try_advisory_xact_lock bigint trouble

От
"Valeriy A."
Дата:
Here my simple example

--- SQL Begin
create table table1 (
    id bigserial PRIMARY KEY
    -- other fields);

create table table2 (
    id bigserial PRIMARY KEY
    -- other fields);


CREATE FUNCTION do_action_on_table1(keyID bigint ) returns int2 LANGUAGE
plpgsql AS $$
DECLARE
  isLocked boolean;
BEGIN
  EXECUTE 'SELECT pg_try_advisory_xact_lock($1)' INTO isLocked USING keyID;

  if isLocked THEN
     --SOME action on table1
     RETURN 1;
  END IF;

  RETURN 0;
END$$

CREATE FUNCTION do_action_on_table2(keyID bigint ) returnS int2
LANGUAGE plpgsql
AS $$
DECLARE
  isLocked boolean;
BEGIN
  EXECUTE 'SELECT pg_try_advisory_xact_lock($1)' INTO isLocked USING keyID;

  if isLocked THEN
     --SOME action on table2
     RETURN 1;
  END IF;

  RETURN 0;
END$$
-- SQL End

In this case if sequences fields has same values then calls of functions
will be lock both tables and miss actions.

On Tue, Feb 9, 2016 at 6:28 AM, David G. Johnston <
david.g.johnston@gmail.com> wrote:

>
>
> On Monday, February 8, 2016, David G. Johnston <david.g.johnston@gmail.com>
> wrote:
>
>> On Friday, February 5, 2016, <mtakvel@gmail.com> wrote:
>>
>>> The following bug has been logged on the website:
>>>
>>> Bug reference:      13920
>>> Logged by:          Valeriy
>>> Email address:      mtakvel@gmail.com
>>> PostgreSQL version: 9.5.0
>>> Operating system:   Ubuntu
>>> Description:
>>>
>>> Hello, I have few high load big tables. My logic calls
>>> pg_try_advisory_xact_lock(bitint) for locking row in current table. As I
>>> see
>>> with bigint param pg_try_advisory_xact_lock lock same ids for all my
>>> tables.
>>> Insthead lock only row in one current table. Looks like this is bug and
>>> will
>>> be cool if you fix it.
>>>
>>>
>> Likely working as designed.  If you wish to provide an example of what
>> you are doing we can probably explain your misunderstanding.  Basically,
>> though, there is nothing about the ID you pass to the advisory lock
>> functions that cause them to be associated with a table.  The ID is simply
>> a number.   You should try the two-key version and associate the first key
>> with the table (probably oid) and the second with the row on that table.
>>
>>
> Though the two-arg uses Integer so maybe not...
>
> You should poprobably explain your use case a bit on the -general list if
> you'd like to discuss alternatives.  But the behavior described is how
> things work right now.
>
>  David J.
>



--
Thanks!
Valeriy

Re: BUG #13920: pg_try_advisory_xact_lock bigint trouble

От
Thomas Munro
Дата:
On Tue, Feb 9, 2016 at 10:01 PM, Valeriy A. <mtakvel@gmail.com> wrote:
> Here my simple example
>
> --- SQL Begin
> create table table1 (
>     id bigserial PRIMARY KEY
>     -- other fields);
>
> create table table2 (
>     id bigserial PRIMARY KEY
>     -- other fields);
>
>
> CREATE FUNCTION do_action_on_table1(keyID bigint ) returns int2 LANGUAGE
> plpgsql AS $$
> DECLARE
>   isLocked boolean;
> BEGIN
>   EXECUTE 'SELECT pg_try_advisory_xact_lock($1)' INTO isLocked USING keyID;
>
>   if isLocked THEN
>      --SOME action on table1
>      RETURN 1;
>   END IF;
>
>   RETURN 0;
> END$$
>
> CREATE FUNCTION do_action_on_table2(keyID bigint ) returnS int2
> LANGUAGE plpgsql
> AS $$
> DECLARE
>   isLocked boolean;
> BEGIN
>   EXECUTE 'SELECT pg_try_advisory_xact_lock($1)' INTO isLocked USING keyID;
>
>   if isLocked THEN
>      --SOME action on table2
>      RETURN 1;
>   END IF;
>
>   RETURN 0;
> END$$
> -- SQL End
>
> In this case if sequences fields has same values then calls of functions
> will be lock both tables and miss actions.

Have you considered using row locks with SKIP LOCKED instead of
advisory locks?  Then you don't have to come up with your own scheme
to map tables and keys to integer space.  Something like this:

CREATE OR REPLACE FUNCTION do_action_on_table1(keyID bigint)
RETURNS int2 LANGUAGE plpgsql AS
$$
BEGIN
  PERFORM * FROM table1 WHERE id = $1 FOR UPDATE SKIP LOCKED;
  IF FOUND THEN
     -- some action on table1
     RETURN 1;
  END IF;

  RETURN 0;
END
$$;

It seems likely you want to load data out of the row into variables
for processing, so you could replace the PERFORM statement with a
SELECT ... INTO ... FOR UPDATE SKIP LOCKED.

--
Thomas Munro
http://www.enterprisedb.com

Re: BUG #13920: pg_try_advisory_xact_lock bigint trouble

От
Merlin Moncure
Дата:
On Tue, Feb 9, 2016 at 3:01 AM, Valeriy A. <mtakvel@gmail.com> wrote:
> Here my simple example
>
> --- SQL Begin
> create table table1 (
>     id bigserial PRIMARY KEY
>     -- other fields);
>
> create table table2 (
>     id bigserial PRIMARY KEY
>     -- other fields);
>
>
> CREATE FUNCTION do_action_on_table1(keyID bigint ) returns int2 LANGUAGE
> plpgsql AS $$
> DECLARE
>   isLocked boolean;
> BEGIN
>   EXECUTE 'SELECT pg_try_advisory_xact_lock($1)' INTO isLocked USING keyID;
>
>   if isLocked THEN
>      --SOME action on table1
>      RETURN 1;
>   END IF;
>
>   RETURN 0;
> END$$
>
> CREATE FUNCTION do_action_on_table2(keyID bigint ) returnS int2
> LANGUAGE plpgsql
> AS $$
> DECLARE
>   isLocked boolean;
> BEGIN
>   EXECUTE 'SELECT pg_try_advisory_xact_lock($1)' INTO isLocked USING keyID;
>
>   if isLocked THEN
>      --SOME action on table2
>      RETURN 1;
>   END IF;
>
>   RETURN 0;
> END$$
> -- SQL End

The problenm is
you can do it via:
create sequence lock_seq;
create domain lockid bigint default nextval('lock_seq');

create table table1 (
    id lockid PRIMARY KEY
    -- other fields);

create table table2 (
    id lockid PRIMARY KEY
    -- other fields);

...

merlin

Re: BUG #13920: pg_try_advisory_xact_lock bigint trouble

От
"Valeriy A."
Дата:
Thanks Tomcas, that the answer for my problem. Greate thanks!

On Fri, Mar 4, 2016 at 10:15 PM, Thomas Munro <thomas.munro@enterprisedb.com
> wrote:

> On Tue, Feb 9, 2016 at 10:01 PM, Valeriy A. <mtakvel@gmail.com> wrote:
> > Here my simple example
> >
> > --- SQL Begin
> > create table table1 (
> >     id bigserial PRIMARY KEY
> >     -- other fields);
> >
> > create table table2 (
> >     id bigserial PRIMARY KEY
> >     -- other fields);
> >
> >
> > CREATE FUNCTION do_action_on_table1(keyID bigint ) returns int2 LANGUAGE
> > plpgsql AS $$
> > DECLARE
> >   isLocked boolean;
> > BEGIN
> >   EXECUTE 'SELECT pg_try_advisory_xact_lock($1)' INTO isLocked USING
> keyID;
> >
> >   if isLocked THEN
> >      --SOME action on table1
> >      RETURN 1;
> >   END IF;
> >
> >   RETURN 0;
> > END$$
> >
> > CREATE FUNCTION do_action_on_table2(keyID bigint ) returnS int2
> > LANGUAGE plpgsql
> > AS $$
> > DECLARE
> >   isLocked boolean;
> > BEGIN
> >   EXECUTE 'SELECT pg_try_advisory_xact_lock($1)' INTO isLocked USING
> keyID;
> >
> >   if isLocked THEN
> >      --SOME action on table2
> >      RETURN 1;
> >   END IF;
> >
> >   RETURN 0;
> > END$$
> > -- SQL End
> >
> > In this case if sequences fields has same values then calls of functions
> > will be lock both tables and miss actions.
>
> Have you considered using row locks with SKIP LOCKED instead of
> advisory locks?  Then you don't have to come up with your own scheme
> to map tables and keys to integer space.  Something like this:
>
> CREATE OR REPLACE FUNCTION do_action_on_table1(keyID bigint)
> RETURNS int2 LANGUAGE plpgsql AS
> $$
> BEGIN
>   PERFORM * FROM table1 WHERE id = $1 FOR UPDATE SKIP LOCKED;
>   IF FOUND THEN
>      -- some action on table1
>      RETURN 1;
>   END IF;
>
>   RETURN 0;
> END
> $$;
>
> It seems likely you want to load data out of the row into variables
> for processing, so you could replace the PERFORM statement with a
> SELECT ... INTO ... FOR UPDATE SKIP LOCKED.
>
> --
> Thomas Munro
> http://www.enterprisedb.com
>



--
Thanks!
Valeriy