Heikki Linnakangas <heikki.linnakan...@enterprisedb.com> wrote:
> heap_insert() calls CheckForSerializableConflictIn(), which checks if

> there is a predicate lock on the whole relation, or on the page we're

> inserting to. It does not check for tuple-level locks, because there

> can't be any locks on a tuple that didn't exist before.
> 
> AFAICS, the check for page lock is actually unnecessary. A page-level

> lock on a heap only occurs when tuple-level locks are promoted. It is

> just a coarser-grain representation of holding locks on all tuples on

> the page, *that exist already*. It is not a "gap" lock like the index

> locks are, it doesn't need to conflict with inserting new tuples on
the 
> page. In fact, if heap_insert chose to insert the tuple on some other

> heap page, there would have been no conflict.
 
Absolutely correct.  Patch attached.
 
-Kevin

*** a/src/backend/access/heap/heapam.c
--- b/src/backend/access/heap/heapam.c
***************
*** 1916,1926 **** heap_insert(Relation relation, HeapTuple tup, CommandId cid,
                                                                           
InvalidBuffer, options, bistate);
  
        /*
!        * We're about to do the actual insert -- check for conflict at the
!        * relation or buffer level first, to avoid possibly having to roll back
!        * work we've just done.
         */
!       CheckForSerializableConflictIn(relation, NULL, buffer);
  
        /* NO EREPORT(ERROR) from here till changes are logged */
        START_CRIT_SECTION();
--- 1916,1929 ----
                                                                           
InvalidBuffer, options, bistate);
  
        /*
!        * We're about to do the actual insert -- check for conflict first, to
!        * avoid possibly having to roll back work we've just done.
!        *
!        * NOTE: For a tuple insert, we only need to check for table locks, 
since
!        * predicate locking at the index level will cover ranges for anything
!        * except a table scan.  Therefore, only provide the relation.
         */
!       CheckForSerializableConflictIn(relation, NULL, InvalidBuffer);
  
        /* NO EREPORT(ERROR) from here till changes are logged */
        START_CRIT_SECTION();
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to