• Magne Mahre's avatar
    Bug#41425 Assertion in Protocol::end_statement() (pushbuild2) · 323f20ea
    Magne Mahre authored
              (diagnostics_area)
          
    Execution of CREATE TABLE ... SELECT statement was not atomic in
    the sense that concurrent statements trying to affect its target
    table might have sneaked in between the moment when the table was
    created and moment when it was filled according to SELECT clause.
    This resulted in inconsistent binary log, unexpected target table
    contents. In cases when concurrent statement was a DDL statement
    CREATE TABLE ... SELECT might have failed with ER_CANT_LOCK error.
          
    In more detail:
    Due to premature metadata lock downgrade which occured after CREATE
    TABLE SELECT statement created table but before it managed to obtain
    table-level lock on it other statements were allowed to open, lock
    and change target table in the middle of CREATE TABLE SELECT
    execution. This also meant that it was possible that CREATE TABLE
    SELECT would wait in mysql_lock_tables() when it was called for newly
    created table and that this wait could have been aborted by concurrent
    DDL. The latter led to execution of unexpected branch of code and
    CREATE TABLE SELECT ending with ER_CANT_LOCK error.
          
    The premature downgrade occured because open_table(), which was called
    for newly created table, decided that it is OK to downgrade metadata
    lock from exclusive to shared since table exists, even although it
    was not acquired within this call.
          
    This fix ensures that open_table() does not downgrade metadata lock
    if it is not acquired during its current invocation.
          
    Testing:
    The bug is exposed in a race condition, and is thus difficult to
    expose in a standard mysql-test-run test case.  Instead, a stress
    test using the Random Query Generator (https://launchpad.net/randgen)
    will trip the problem occasionally.
          
       % perl  runall.pl \
                --basedir=<build dir> \
                 --mysqld=--table-lock-wait-timeout=5 \
                 --mysqld=--skip-safemalloc \
                 --grammar=conf/maria_bulk_insert.yy \
                 --reporters=ErrorLog,Backtrace,WinPackage \
                 --mysqld=--log-output=file  \
                 --queries=100000 \
                 --threads=10 \
                 --engine=myisam
          
    Note: You will need a debug build to expose the bug
          
    When the bug is tripped, the server will abort and dump core.
    
    
    Backport from 6.0-codebase   (revid: 2617.53.4)
    323f20ea
sql_base.cc 276 KB