Thread

  1. It sorta works, but I'm confused about locking

    Tom Lane <tgl@sss.pgh.pa.us> — 1998-09-27T21:34:33Z

    I've got this new notify code almost working, but...
    
    What exactly is the protocol for locking a table that you intend to
    modify?  The old notify code just did RelationSetLockForWrite(),
    but it's not clear to me that that works correctly --- for one thing,
    it doesn't seem to offer any way of detecting failure to acquire the
    lock.  (RelationSetLockForWrite calls MultiLockReln, which *does*
    return a boolean, but RelationSetLockForWrite ignores it...)  Also,
    it's not at all clear whether I should call RelationUnsetLockForWrite
    at the end of the routine or not; some existing code does, some doesn't.
    
    I'm concerned because interlocking of the specialized NOTIFY-related
    statements seems to work fine, but they seem not to be interlocked
    against user operations on the pg_listener table.
    
    For example, this works as I'd expect:
    
    	psql#1				psql#2
    
    	begin;
    	listen z;
    
    					notify z;
    					(hangs up until #1 commits)
    
    	end;
    
    because "listen" acquires a write lock on the pg_listener table, which
    the notify has to wait for.
    
    But this doesn't work as I'd expect:
    
    	psql#1				psql#2
    
    	begin;
    	select * from pg_listener;
    
    					notify z;
    					(completes immediately)
    
    	end;
    
    Seems to me the "select" should acquire a read lock that would prevent
    the #2 backend from writing pg_listener until the end of #1's transaction.
    
    Is there a bug here, or is there some special definition of user access
    to a system table that means the select isn't acquiring a read lock?
    Selects and updates on ordinary user tables seem to interlock fine...
    
    			regards, tom lane
    
    
  2. Re: [HACKERS] It sorta works, but I'm confused about locking

    Massimo Dal Zotto <dz@cs.unitn.it> — 1998-09-28T16:46:58Z

    > 
    > I've got this new notify code almost working, but...
    
    Could you plase send it to me ?
    
    > What exactly is the protocol for locking a table that you intend to
    > modify?  The old notify code just did RelationSetLockForWrite(),
    > but it's not clear to me that that works correctly --- for one thing,
    > it doesn't seem to offer any way of detecting failure to acquire the
    > lock.  (RelationSetLockForWrite calls MultiLockReln, which *does*
    > return a boolean, but RelationSetLockForWrite ignores it...)  Also,
    > it's not at all clear whether I should call RelationUnsetLockForWrite
    > at the end of the routine or not; some existing code does, some doesn't.
    
    It is not done where there is an immediate CommitTransactionCommand which
    already releases the locks.
    
    > I'm concerned because interlocking of the specialized NOTIFY-related
    > statements seems to work fine, but they seem not to be interlocked
    > against user operations on the pg_listener table.
    > 
    > For example, this works as I'd expect:
    > 
    > 	psql#1				psql#2
    > 
    > 	begin;
    > 	listen z;
    > 
    > 					notify z;
    > 					(hangs up until #1 commits)
    > 
    > 	end;
    > 
    > because "listen" acquires a write lock on the pg_listener table, which
    > the notify has to wait for.
    > 
    > But this doesn't work as I'd expect:
    > 
    > 	psql#1				psql#2
    > 
    > 	begin;
    > 	select * from pg_listener;
    > 
    > 					notify z;
    > 					(completes immediately)
    > 
    > 	end;
    > 
    > Seems to me the "select" should acquire a read lock that would prevent
    > the #2 backend from writing pg_listener until the end of #1's transaction.
    > 
    > Is there a bug here, or is there some special definition of user access
    > to a system table that means the select isn't acquiring a read lock?
    > Selects and updates on ordinary user tables seem to interlock fine...
    
    Very strange, it seems a bug. But users should not know about pg_listener.
    
    -- 
    Massimo Dal Zotto
    
    +----------------------------------------------------------------------+
    |  Massimo Dal Zotto                email:  dz@cs.unitn.it             |
    |  Via Marconi, 141                 phone:  ++39-461-534251            |
    |  38057 Pergine Valsugana (TN)     www:  http://www.cs.unitn.it/~dz/  |
    |  Italy                            pgp:  finger dz@tango.cs.unitn.it  |
    +----------------------------------------------------------------------+
    
    
  3. Re: [HACKERS] It sorta works, but I'm confused about locking

    Bruce Momjian <maillist@candle.pha.pa.us> — 1998-10-01T21:29:42Z

    > I've got this new notify code almost working, but...
    > 
    > What exactly is the protocol for locking a table that you intend to
    > modify?  The old notify code just did RelationSetLockForWrite(),
    > but it's not clear to me that that works correctly --- for one thing,
    > it doesn't seem to offer any way of detecting failure to acquire the
    > lock.  (RelationSetLockForWrite calls MultiLockReln, which *does*
    > return a boolean, but RelationSetLockForWrite ignores it...)  Also,
    > it's not at all clear whether I should call RelationUnsetLockForWrite
    > at the end of the routine or not; some existing code does, some doesn't.
    
    Welcome to PostgreSQL.  This is the type of thing I saw when doing the
    mega-patch, were people were not doing things consistently, because some
    coders do not understand what is happening inside the code, and just
    write something that works, sort of.
    
    I recommend you check out what is currently done properly, and fix the
    ones that are incorrect.
    
    I can imagine some cases where you would want to get a lock and keep it
    until the end of the transaction, and other times when you would want to
    release it before transaction end.
    
    
    > 
    > I'm concerned because interlocking of the specialized NOTIFY-related
    > statements seems to work fine, but they seem not to be interlocked
    > against user operations on the pg_listener table.
    > 
    > For example, this works as I'd expect:
    > 
    > 	psql#1				psql#2
    > 
    > 	begin;
    > 	listen z;
    > 
    > 					notify z;
    > 					(hangs up until #1 commits)
    > 
    > 	end;
    > 
    > because "listen" acquires a write lock on the pg_listener table, which
    > the notify has to wait for.
    > 
    > But this doesn't work as I'd expect:
    > 
    > 	psql#1				psql#2
    > 
    > 	begin;
    > 	select * from pg_listener;
    > 
    > 					notify z;
    > 					(completes immediately)
    > 
    > 	end;
    > 
    > Seems to me the "select" should acquire a read lock that would prevent
    > the #2 backend from writing pg_listener until the end of #1's transaction.
    > 
    > Is there a bug here, or is there some special definition of user access
    > to a system table that means the select isn't acquiring a read lock?
    > Selects and updates on ordinary user tables seem to interlock fine...
    
    Select certainly should be locking.  Something is wrong, but I am not
    sure what.  If you want me to check into it, let me know.
    
    
    -- 
      Bruce Momjian                        |  http://www.op.net/~candle
      maillist@candle.pha.pa.us            |  (610) 853-3000
      +  If your life is a hard drive,     |  830 Blythe Avenue
      +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026