• Marko Mäkelä's avatar
    MDEV-24258 Merge dict_sys.mutex into dict_sys.latch · 82b7c561
    Marko Mäkelä authored
    In the parent commit, dict_sys.latch could theoretically have been
    replaced with a mutex. But, we can do better and merge dict_sys.mutex
    into dict_sys.latch. Generally, every occurrence of dict_sys.mutex_lock()
    will be replaced with dict_sys.lock().
    
    The PERFORMANCE_SCHEMA instrumentation for dict_sys_mutex
    will be removed along with dict_sys.mutex. The dict_sys.latch
    will remain instrumented as dict_operation_lock.
    
    Some use of dict_sys.lock() will be replaced with dict_sys.freeze(),
    which we will reintroduce for the new shared mode. Most notably,
    concurrent table lookups are possible as long as the tables are present
    in the dict_sys cache. In particular, this will allow more concurrency
    among InnoDB purge workers.
    
    Because dict_sys.mutex will no longer 'throttle' the threads that purge
    InnoDB transaction history, a performance degradation may be observed
    unless innodb_purge_threads=1.
    
    The table cache eviction policy will become FIFO-like,
    similar to what happened to fil_system.LRU
    in commit 45ed9dd9.
    The name of the list dict_sys.table_LRU will become somewhat misleading;
    that list contains tables that may be evicted, even though the
    eviction policy no longer is least-recently-used but first-in-first-out.
    (Note: Tables can never be evicted as long as locks exist on them or
    the tables are in use by some thread.)
    
    As demonstrated by the test perfschema.sxlock_func, there
    will be less contention on dict_sys.latch, because some previous
    use of exclusive latches will be replaced with shared latches.
    
    fts_parse_sql_no_dict_lock(): Replaced with pars_sql().
    
    fts_get_table_name_prefix(): Merged to fts_optimize_create().
    
    dict_stats_update_transient_for_index(): Deduplicated some code.
    
    ha_innobase::info_low(), dict_stats_stop_bg(): Use a combination
    of dict_sys.latch and table->stats_mutex_lock() to cover the
    changes of BG_STAT_SHOULD_QUIT, because the flag is being read
    in dict_stats_update_persistent() while not holding dict_sys.latch.
    
    row_discard_tablespace_for_mysql(): Protect stats_bg_flag by
    exclusive dict_sys.latch, like most other code does.
    
    row_quiesce_table_has_fts_index(): Remove unnecessary mutex
    acquisition. FLUSH TABLES...FOR EXPORT is protected by MDL.
    
    row_import::set_root_by_heuristic(): Remove unnecessary mutex
    acquisition. ALTER TABLE...IMPORT TABLESPACE is protected by MDL.
    
    row_ins_sec_index_entry_low(): Replace a call
    to dict_set_corrupted_index_cache_only(). Reads of index->type
    were not really protected by dict_sys.mutex, and writes
    (flagging an index corrupted) should be extremely rare.
    
    dict_stats_process_entry_from_defrag_pool(): Only freeze the dictionary,
    do not lock it exclusively.
    
    dict_stats_wait_bg_to_stop_using_table(), DICT_BG_YIELD: Remove trx.
    We can simply invoke dict_sys.unlock() and dict_sys.lock() directly.
    
    dict_acquire_mdl_shared()<trylock=false>: Assert that dict_sys.latch is
    only held in shared more, not exclusive mode. Only acquire it in
    exclusive mode if the table needs to be loaded to the cache.
    
    dict_sys_t::acquire(): Remove. Relocating elements in dict_sys.table_LRU
    would require holding an exclusive latch, which we want to avoid
    for performance reasons.
    
    dict_sys_t::allow_eviction(): Add the table first to dict_sys.table_LRU,
    to compensate for the removal of dict_sys_t::acquire(). This function
    is only invoked by INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS.
    
    dict_table_open_on_id(), dict_table_open_on_name(): If dict_locked=false,
    try to acquire dict_sys.latch in shared mode. Only acquire the latch in
    exclusive mode if the table is not found in the cache.
    
    Reviewed by: Thirunarayanan Balathandayuthapani
    82b7c561
srv0srv.cc 60.2 KB