• Guilhem Bichot's avatar
    Fix for BUG#39710 "Maria assertion in maria_disable_non_unique_index". · 421973ec
    Guilhem Bichot authored
    No testcase, this requires concurrency and is automatically tested by
    maria_bulk_insert.yy in pushbuild2.
    
    storage/maria/ha_maria.cc:
      The case of BUG#39710 is:
      two threads want to INSERT SELECT into the same table.
      Thread1 (T1) starts, does external_lock, thr_lock (store_lock sees 0 records so
      upgrades to TL_WRITE), goes into bulk insert, starts writes
      T2 starts, external_lock, thr_lock (store_lock sees 0 records so
      upgrades to TL_WRITE), blocks on existing thr_lock of T1.
      T1 ends writes, ends bulk insert, commits (ha_maria::implicit_commit()
      at end of dispatch_command()), external_lock and thr_unlock
      (close_thread_tables() at end of dispatch_command()).
      T2 wakes up, gets thr_lock, goes into start_bulk_insert() where
      file->state is out-of-date and still says that file->state->records==0,
      so maria_disable_non_unique_index() is called, which asserts because
      the actual number of records (share->state.state.records) is >0.
      The solution, maybe temporary, is to also check share->state.state.records==0
      when deciding to do bulk insert, with the idea that such operation cannot
      rely on the view of the start of the transaction, as it uses repair,
      and can safely read share->state as it has acquired the exclusive
      TL_WRITE.
      Question for reviewer: if we enter the if() branch, do we also need to do:
      *(file->state)= share->state.state;
      or even call some existing function which does that?
    421973ec
ha_maria.cc 106 KB