• unknown's avatar
    Fix for bug#19403/12212 "Crash that happens during removing of database name · 10e0b276
    unknown authored
    from cache" and #21216 "Simultaneous DROP TABLE and SHOW OPEN TABLES causes
    server to crash".
    
    Crash happened when one ran DROP DATABASE or SHOW OPEN TABLES statements
    while concurrently doing DROP TABLE (or RENAME TABLE, CREATE TABLE LIKE
    or any other command that takes name-lock) in other connection.
    
    This problem was caused by the fact that table placeholders which were
    added to table cache in order to obtain name-lock on table had
    TABLE_SHARE::db and table_name set to 0. Therefore they broke assumption
    that these members are non-0 for all tables in table cache on which some
    of our code relies.
    
    The fix sets these members for such placeholders to appropriate value making
    this assumption true again. As attempt to avoid such problems in future
    we introduce auxiliary TABLE_SHARE::set_table_cache_key() methods which
    should be used when one wants to set TABLE_SHARE::table_cache_key and which
    ensure that TABLE_SHARE::table_name/db are set properly.
    
    Test cases for these bugs were added to 5.0 test-suite (with 5.0-specific
    fix for bug #21216).
    
    
    sql/lock.cc:
      Our code assumes that TABLE_SHARE::table_name/db for objects in table cache
      is set properly (and is non-NULL). For example look in list_open_tables()
      and remove_db_from_cache(). This was not true for table placeholders that
      were added to table cache for name-locking. Changed lock_table_name() to
      preserve this assumption (now it uses TABLE_SHARE::set_table_cache_key()
      to set all three table_cache_key/db/table_name members at once).
      Also now we use my_multi_malloc() to allocate memory for TABLE and
      TABLE_SHARE objects instead of using my_malloc() + summing sizes as
      it automatically provides proper alignment for memory allocated.
    sql/sql_base.cc:
      Now we use TABLE_SHARE::set_table_cache_key() auxiliary methods to set
      TABLE_SHARE::table_cache_key/db/table_name members at once.
      We also use multi_alloc_root() instead of alloc_root() for allocating
      memory for several objects as it is less error prone.
      Finally, we also got rid of unused code in reopen_name_locked_table().
    sql/sql_select.cc:
      Got rid of redundant code. TABLE_SHARE::db/table_cache_key are both set to
      empty string by the call to init_tmp_table_share() routine.
    sql/table.cc:
      Now alloc_table_share() uses auxiliary TABLE_SHARE::set_table_cache_key()
      method to properly set TABLE_SHARE::table_cache_key/db/table_name members.
      Also now we use multi_alloc_root() instead of alloc_root() for allocating
      memory for several objects as it is more clear/less error-prone.
    sql/table.h:
      Added comment about importance of apropriate setting of
      TABLE_SHARE::table_name/db/table_cache_key for tables in table cache.
      Introduced two auxiliary TABLE_SHARE::set_table_cache_key() methods which
      allow to set these three members at once.
    10e0b276
table.h 36.6 KB