• Jon Olav Hauglid's avatar
    Fix for bug #48538 "Assertion in thr_lock() on LOAD DATA CONCURRENT · 1405f019
    Jon Olav Hauglid authored
                       INFILE".
    
    Attempts to execute an INSERT statement for a MEMORY table which invoked
    a trigger or called a stored function which tried to perform LOW_PRIORITY
    update on the table being inserted into, resulted in debug servers aborting
    due to an assertion failure. On non-debug servers such INSERTs failed with
    "Can't update table t1 in stored function/trigger because it is already used
    by statement which invoked this stored function/trigger" as expected.
    
    The problem was that in the above scenario TL_WRITE_CONCURRENT_INSERT
    is converted to TL_WRITE inside the thr_lock() function since the MEMORY
    engine does not support concurrent inserts. This triggered an assertion
    which assumed that for the same table, one thread always requests locks with
    higher thr_lock_type value first. When TL_WRITE_CONCURRENT_INSERT is
    upgraded to TL_WRITE after the locks have been sorted, this is no longer true.
    In this case, TL_WRITE was requested after acquiring a TL_WRITE_LOW_PRIORITY
    lock on the table, triggering the assert.
    
    This fix solves the problem by adjusting this assert to take this
    scenario into account.
    
    An alternative approach to change handler::store_locks() methods for all engines
    which do not support concurrent inserts in such way that
    TL_WRITE_CONCURRENT_INSERT is upgraded to TL_WRITE there instead, 
    was considered too intrusive.
    
    Commit on behalf of Dmitry Lenev.
    
    
    mysql-test/r/lock.result:
      Added simplified test for bug #48538 "Assertion in thr_lock() on LOAD
      DATA CONCURRENT INFILE".
    mysql-test/t/lock.test:
      Added simplified test for bug #48538 "Assertion in thr_lock() on LOAD
      DATA CONCURRENT INFILE".
    mysys/thr_lock.c:
      Adjusted assertion to account for situation when
      TL_WRITE_CONCURRENT_INSERT is converted to TL_WRITE inside of the
      thr_lock() function because the engine of the table being locked 
      does not support concurrent inserts.
      This scenario breaks assumption that for the same table one thread
      always requests locks with higher thr_lock_type value first, since
      TL_WRITE on the table (converted from TL_WRITE_CONCURRENT_INSERT)
      can be requested after acquiring a TL_WRITE_LOW_PRIORITY lock on the table.
      Note that it is still safe to grant a new lock without extra checks and
      waiting in such situation since TL_WRITE has the same compatibility
      rules as TL_WRITE_LOW_PRIORITY (their only difference is priority).
    1405f019
lock.test 11.4 KB