1
0
mirror of https://github.com/MariaDB/server.git synced 2025-11-09 11:41:36 +03:00
Files
mariadb/mysql-test/suite/perfschema/t/sxlock_func.test
Marko Mäkelä 82b7c561b7 MDEV-24258 Merge dict_sys.mutex into dict_sys.latch
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 45ed9dd957.
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
2021-08-31 13:51:35 +03:00

70 lines
2.4 KiB
Plaintext

# Performance schema tests, for SX-lock
# Note that only Innodb provides instrumented SX-locks,
# so this test depends largely on the innodb instrumentation.
--source include/not_embedded.inc
--source include/have_perfschema.inc
--source include/have_innodb.inc
UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES';
UPDATE performance_schema.setup_instruments SET enabled = 'YES'
WHERE name like 'wait/synch/sxlock/%';
UPDATE performance_schema.setup_instruments SET enabled = 'YES'
WHERE name like 'wait/synch/rwlock/innodb/%';
SELECT DISTINCT name FROM performance_schema.setup_instruments
WHERE name LIKE 'wait/synch/rwlock/innodb/%'
AND name!='wait/synch/rwlock/innodb/btr_search_latch' ORDER BY name;
TRUNCATE TABLE performance_schema.events_waits_history_long;
TRUNCATE TABLE performance_schema.events_waits_history;
TRUNCATE TABLE performance_schema.events_waits_current;
# Check some SX-locks classes are instrumented
select name from performance_schema.setup_instruments
where name like "wait/synch/sxlock/%" order by name;
# Check some SX-locks instances are instrumented
SELECT DISTINCT name FROM performance_schema.rwlock_instances
WHERE name LIKE 'wait/synch/sxlock/innodb/%'
ORDER BY name;
# Some Innodb payload, to produce data
create table t1(a int) engine=innodb;
begin;
insert into t1 values (1), (2), (3);
insert into t1 values (1), (2), (3);
insert into t1 values (1), (2), (3);
commit;
drop table t1;
# Make sure some rw-lock operations have been executed
# (there will only occasionally be waits on some rw-locks)
SELECT DISTINCT event_name FROM performance_schema.events_waits_history_long
WHERE event_name LIKE 'wait/synch/rwlock/innodb/%'
AND event_name NOT IN
('wait/synch/rwlock/innodb/btr_search_latch',
'wait/synch/rwlock/innodb/dict_operation_lock',
'wait/synch/rwlock/innodb/trx_purge_latch')
ORDER BY event_name;
# Make sure some shared_lock operations have been executed
SELECT event_name FROM performance_schema.events_waits_history_long
WHERE event_name = 'wait/synch/sxlock/innodb/index_tree_rw_lock'
AND operation IN ('try_shared_lock','shared_lock') LIMIT 1;
# Make sure some exclusive_lock operations have been executed
SELECT event_name from performance_schema.events_waits_history_long
WHERE event_name = 'wait/synch/sxlock/innodb/index_tree_rw_lock'
AND operation IN ('try_exclusive_lock','exclusive_lock') LIMIT 1;
# Cleanup
UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES';