MDEV-21452: Replace ib_mutex_t with mysql_mutex_t

SHOW ENGINE INNODB MUTEX functionality is completely removed,
as are the InnoDB latching order checks.

We will enforce innodb_fatal_semaphore_wait_threshold
only for dict_sys.mutex and lock_sys.mutex.

dict_sys_t::mutex_lock(): A single entry point for dict_sys.mutex.

lock_sys_t::mutex_lock(): A single entry point for lock_sys.mutex.

FIXME: srv_sys should be removed altogether; it is duplicating tpool
functionality.

fil_crypt_threads_init(): To prevent SAFE_MUTEX warnings, we must
not hold fil_system.mutex.

fil_close_all_files(): To prevent SAFE_MUTEX warnings for
fil_space_destroy_crypt_data(), we must not hold fil_system.mutex
while invoking fil_space_free_low() on a detached tablespace.
This commit is contained in:
Marko Mäkelä 2020-12-04 19:02:58 +02:00
parent db006a9a43
commit ff5d306e29
117 changed files with 1500 additions and 5085 deletions

View file

@ -1789,7 +1789,6 @@ copy_back()
}
srv_max_n_threads = 1000;
sync_check_init();
/* copy undo tablespaces */
@ -1990,7 +1989,6 @@ cleanup:
ds_data = NULL;
sync_check_close();
return(ret);
}
@ -2086,7 +2084,6 @@ decrypt_decompress()
datadir_iter_t *it = NULL;
srv_max_n_threads = 1000;
sync_check_init();
/* cd to backup directory */
if (my_setwd(xtrabackup_target_dir, MYF(MY_WME)))
@ -2115,8 +2112,6 @@ decrypt_decompress()
ds_data = NULL;
sync_check_close();
return(ret);
}

View file

@ -91,14 +91,14 @@ xb_fil_node_close_file(
{
ibool ret;
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
ut_ad(node);
ut_a(!node->being_extended);
if (!node->is_open()) {
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
return;
}
@ -107,10 +107,10 @@ xb_fil_node_close_file(
ut_a(ret);
node->handle = OS_FILE_CLOSED;
mutex_exit(&fil_system.mutex);
ut_a(fil_system.n_open > 0);
fil_system.n_open--;
mysql_mutex_unlock(&fil_system.mutex);
}
/************************************************************************
@ -230,12 +230,12 @@ xb_fil_cur_open(
&& os_file_read(IORequestRead,
node->handle, cursor->buf, 0,
cursor->page_size) == DB_SUCCESS) {
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (!node->space->crypt_data) {
node->space->crypt_data = fil_space_read_crypt_data(
node->space->zip_size(), cursor->buf);
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
cursor->space_size = (ulint)(cursor->statinfo.st_size

View file

@ -2724,9 +2724,9 @@ static my_bool xtrabackup_copy_datafile(fil_node_t *node, uint thread_n,
pthread_mutex_unlock(&backup_mutex);
if (was_dropped) {
if (node->is_open()) {
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
node->close();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
goto skip;
}
@ -3315,10 +3315,11 @@ static void xb_load_single_table_tablespace(const char *dirname,
ut_a(space != NULL);
space->add(file->filepath(),
skip_node_page0 ? file->detach() : pfs_os_file_t(), 0, false, false);
mutex_enter(&fil_system.mutex);
skip_node_page0 ? file->detach() : pfs_os_file_t(),
0, false, false);
mysql_mutex_lock(&fil_system.mutex);
space->read_page0();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (srv_operation == SRV_OPERATION_RESTORE_DELTA
|| xb_close_files) {
@ -4244,7 +4245,6 @@ fail:
computers */
}
srv_thread_pool_init();
sync_check_init();
/* Reset the system variables in the recovery module. */
trx_pool_init();
recv_sys.create();
@ -4631,9 +4631,9 @@ void backup_fix_ddl(CorruptedPages &corrupted_pages)
if (n->space->id == 0)
continue;
if (n->is_open()) {
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
n->close();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
fil_space_free(n->space->id, false);
}
@ -4777,7 +4777,7 @@ xb_space_create_file(
static fil_space_t* fil_space_get_by_name(const char* name)
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system.space_list);
space != NULL;
space = UT_LIST_GET_NEXT(space_list, space))
@ -4883,9 +4883,9 @@ exit:
HASH_INSERT(xb_filter_entry_t, name_hash, &inc_dir_tables_hash,
ut_fold_string(table->name), table);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
fil_space = fil_space_get_by_name(dest_space_name);
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (fil_space != NULL) {
if (fil_space->id == info.space_id
@ -4916,9 +4916,9 @@ exit:
die("Can't handle DDL operation on tablespace "
"%s\n", dest_space_name);
}
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
fil_space = fil_space_get_by_id(info.space_id);
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (fil_space != NULL) {
char tmpname[FN_REFLEN];
@ -5679,7 +5679,6 @@ static bool xtrabackup_prepare_func(char** argv)
goto error_cleanup;
}
sync_check_init();
recv_sys.create();
log_sys.create();
recv_sys.recovery_on = true;
@ -5708,7 +5707,6 @@ static bool xtrabackup_prepare_func(char** argv)
fil_system.close();
innodb_free_param();
log_sys.close();
sync_check_close();
if (!ok) goto error_cleanup;
}

View file

@ -4,9 +4,6 @@
# dict_update_statistics_low can still be run concurrently on same table
#
# This is a symbolic test, it would not fail if the bug is present.
# Rather those SQL commands have been used during manual testing under
# innodb_sync_debug to test all changed codepaths for locking
# correctness.
#
CREATE TABLE bug53046_1 (c1 INT PRIMARY KEY) ENGINE=INNODB;

View file

@ -493,7 +493,6 @@ insert into test.sanity values
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_STATUS_OUTPUT_LOCKS"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_SYNC_ARRAY_SIZE"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_SYNC_SPIN_LOOPS"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_SYNC_DEBUG"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_TEMP_DATA_FILE_PATH"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_TRX_RSEG_N_SLOTS_DEBUG"),

View file

@ -12,4 +12,3 @@
all_vars: obsolete, see sysvars_* tests
innodb_buffer_pool_dump_pct_function: MDEV-11454 follow-up needed (unstable)
innodb_fatal_semaphore_wait_threshold : MDEV-21452 TODO: lock_sys.mutex

View file

@ -1,11 +0,0 @@
#
# Basic test for innodb_sync_debug
#
SELECT @@global.innodb_sync_debug;
@@global.innodb_sync_debug
0
set global innodb_sync_debug = 1;
ERROR HY000: Variable 'innodb_sync_debug' is a read only variable
SELECT @@global.innodb_sync_debug;
@@global.innodb_sync_debug
0

View file

@ -1665,18 +1665,6 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST OFF,ON
READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_SYNC_DEBUG
SESSION_VALUE NULL
DEFAULT_VALUE OFF
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN
VARIABLE_COMMENT Enable the sync debug checks
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST OFF,ON
READ_ONLY YES
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_SYNC_SPIN_LOOPS
SESSION_VALUE NULL
DEFAULT_VALUE 30

View file

@ -1,16 +0,0 @@
--echo #
--echo # Basic test for innodb_sync_debug
--echo #
--source include/have_innodb.inc
# The config variable is a debug read-only variable
-- source include/have_debug.inc
SELECT @@global.innodb_sync_debug;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
set global innodb_sync_debug = 1;
SELECT @@global.innodb_sync_debug;

View file

@ -163,7 +163,6 @@ SET(INNOBASE_SOURCES
include/ha0storage.ic
include/handler0alter.h
include/hash0hash.h
include/ib0mutex.h
include/ibuf0ibuf.h
include/ibuf0ibuf.ic
include/ibuf0types.h
@ -238,11 +237,7 @@ SET(INNOBASE_SOURCES
include/srv0mon.ic
include/srv0srv.h
include/srv0start.h
include/sync0debug.h
include/sync0policy.h
include/sux_lock.h
include/sync0sync.h
include/sync0types.h
include/trx0i_s.h
include/trx0purge.h
include/trx0rec.h
@ -267,7 +262,6 @@ SET(INNOBASE_SOURCES
include/ut0lst.h
include/ut0mem.h
include/ut0mem.ic
include/ut0mutex.h
include/ut0new.h
include/ut0pool.h
include/ut0rbt.h
@ -324,8 +318,6 @@ SET(INNOBASE_SOURCES
srv/srv0srv.cc
srv/srv0start.cc
sync/srw_lock.cc
sync/sync0debug.cc
sync/sync0sync.cc
trx/trx0i_s.cc
trx/trx0purge.cc
trx/trx0rec.cc

View file

@ -388,11 +388,11 @@ btr_root_adjust_on_import(
tf &= ~FSP_FLAGS_MEM_MASK;
if (fil_space_t::is_flags_equal(tf, sf)
|| fil_space_t::is_flags_equal(sf, tf)) {
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
table->space->flags = (table->space->flags
& ~FSP_FLAGS_MEM_MASK)
| (tf & FSP_FLAGS_MEM_MASK);
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
err = DB_SUCCESS;
} else {
err = DB_CORRUPTION;
@ -3293,10 +3293,10 @@ btr_lift_page_up(
if (!dict_table_is_locking_disabled(index->table)) {
/* Free predicate page locks on the block */
if (dict_index_is_spatial(index)) {
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
lock_prdt_page_free_from_discard(
block, &lock_sys.prdt_page_hash);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
}
lock_update_copy_and_discard(father_block, block);
}
@ -3546,11 +3546,11 @@ retry:
}
/* No GAP lock needs to be worrying about */
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
lock_prdt_page_free_from_discard(
block, &lock_sys.prdt_page_hash);
lock_rec_free_all_from_discard_page(block);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
} else {
btr_cur_node_ptr_delete(&father_cursor, mtr);
if (!dict_table_is_locking_disabled(index->table)) {
@ -3699,11 +3699,11 @@ retry:
offsets2, offsets,
merge_page, mtr);
}
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
lock_prdt_page_free_from_discard(
block, &lock_sys.prdt_page_hash);
lock_rec_free_all_from_discard_page(block);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
} else {
compressed = btr_cur_pessimistic_delete(&err, TRUE,

View file

@ -1222,8 +1222,6 @@ BtrBulk::finish(dberr_t err)
ut_ad(err == DB_SUCCESS);
}
ut_ad(!sync_check_iterate(dict_sync_check()));
ut_ad(err != DB_SUCCESS
|| btr_validate_index(m_index, NULL) == DB_SUCCESS);
return(err);

View file

@ -1997,11 +1997,11 @@ retry_page_get:
trx_t* trx = thr_get_trx(cursor->thr);
lock_prdt_t prdt;
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
lock_init_prdt_from_mbr(
&prdt, &cursor->rtr_info->mbr, mode,
trx->lock.lock_heap);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
if (rw_latch == RW_NO_LATCH && height != 0) {
block->lock.s_lock();

View file

@ -223,12 +223,12 @@ void btr_search_disable()
{
dict_table_t* table;
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
btr_search_x_lock_all();
if (!btr_search_enabled) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
btr_search_x_unlock_all();
return;
}
@ -249,7 +249,7 @@ void btr_search_disable()
btr_search_disable_ref_count(table);
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
/* Set all block->index = NULL. */
buf_pool.clear_hash_index();
@ -1250,7 +1250,7 @@ retry:
ut_ad(page_is_leaf(block->frame));
/* We must not dereference block->index here, because it could be freed
if (index->table->n_ref_count == 0 && !mutex_own(&dict_sys.mutex)).
if (index->table->n_ref_count == 0).
Determine the ahi_slot based on the block contents. */
const index_id_t index_id
@ -1410,8 +1410,10 @@ void btr_search_drop_page_hash_when_freed(const page_id_t page_id)
/* In all our callers, the table handle should
be open, or we should be in the process of
dropping the table (preventing eviction). */
ut_ad(block->index->table->get_ref_count() > 0
|| mutex_own(&dict_sys.mutex));
#ifdef SAFE_MUTEX
DBUG_ASSERT(block->index->table->get_ref_count()
|| dict_sys.mutex_is_locked());
#endif /* SAFE_MUTEX */
btr_search_drop_page_hash_index(block);
}
}

View file

@ -63,7 +63,6 @@ Created 11/5/1995 Heikki Tuuri
#include "fil0pagecompress.h"
#endif /* !UNIV_INNOCHECKSUM */
#include "page0zip.h"
#include "sync0sync.h"
#include "buf0dump.h"
#include <map>
#include <sstream>
@ -2035,11 +2034,11 @@ withdraw_retry:
message_interval *= 2;
}
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
bool found = false;
trx_sys.trx_list.for_each(find_interesting_trx{
found, withdraw_started, current_time});
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
withdraw_started = current_time;
}

View file

@ -29,7 +29,6 @@ Created 2011/12/19
#include "buf0checksum.h"
#include "srv0start.h"
#include "srv0srv.h"
#include "sync0sync.h"
#include "page0zip.h"
#include "trx0sys.h"
#include "fil0crypt.h"

View file

@ -241,8 +241,6 @@ void buf_flush_remove_pages(ulint id)
@return number dirty pages that there were for this tablespace */
ulint buf_flush_dirty_pages(ulint id)
{
ut_ad(!sync_check_iterate(dict_sync_check()));
ulint n= 0;
mysql_mutex_lock(&buf_pool.flush_list_mutex);
@ -2289,8 +2287,6 @@ ATTRIBUTE_COLD void buf_flush_buffer_pool()
NOTE: The calling thread is not allowed to hold any buffer page latches! */
void buf_flush_sync()
{
ut_ad(!sync_check_iterate(dict_sync_check()));
for (;;)
{
const ulint n_flushed= buf_flush_lists(srv_max_io_capacity, LSN_MAX);

View file

@ -37,6 +37,7 @@ Created 11/5/1995 Heikki Tuuri
#include "log0recv.h"
#include "srv0srv.h"
#include "srv0mon.h"
#include "my_cpu.h"
/** Flush this many pages in buf_LRU_get_free_block() */
size_t innodb_lru_flush_size;

View file

@ -235,7 +235,7 @@ dict_boot(void)
heap = mem_heap_create(450);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
/* Get the dictionary header */
const byte* dict_hdr = &dict_hdr_get(&mtr)->frame[DICT_HDR];
@ -429,7 +429,7 @@ dict_boot(void)
dict_load_sys_table(dict_sys.sys_fields);
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
return(err);
}

View file

@ -343,7 +343,7 @@ dict_build_table_def_step(
que_thr_t* thr, /*!< in: query thread */
tab_node_t* node) /*!< in: table create node */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
dict_table_t* table = node->table;
trx_t* trx = thr_get_trx(thr);
ut_ad(!table->is_temporary());
@ -483,7 +483,7 @@ dict_create_sys_indexes_tuple(
dfield_t* dfield;
byte* ptr;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_ad(index);
ut_ad(index->table->space || index->table->file_unreadable);
ut_ad(!index->table->space
@ -712,7 +712,7 @@ dict_build_index_def_step(
dtuple_t* row;
trx_t* trx;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
trx = thr_get_trx(thr);
@ -763,7 +763,7 @@ dict_build_index_def(
dict_index_t* index, /*!< in/out: index */
trx_t* trx) /*!< in/out: InnoDB transaction handle */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
if (trx->table_id == 0) {
/* Record only the first table id. */
@ -811,7 +811,7 @@ dict_create_index_tree_step(
dict_index_t* index;
dtuple_t* search_tuple;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
index = node->index;
@ -880,7 +880,7 @@ dict_create_index_tree_in_mem(
{
mtr_t mtr;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_ad(!(index->type & DICT_FTS));
mtr_start(&mtr);
@ -910,7 +910,7 @@ void dict_drop_index_tree(btr_pcur_t* pcur, trx_t* trx, mtr_t* mtr)
byte* ptr;
ulint len;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_a(!dict_table_is_comp(dict_sys.sys_indexes));
ptr = rec_get_nth_field_old(rec, DICT_FLD__SYS_INDEXES__PAGE_NO, &len);
@ -1056,7 +1056,7 @@ dict_create_table_step(
trx_t* trx;
ut_ad(thr);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
trx = thr_get_trx(thr);
@ -1199,7 +1199,7 @@ dict_create_index_step(
trx_t* trx;
ut_ad(thr);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
trx = thr_get_trx(thr);
@ -1359,7 +1359,7 @@ dict_check_if_system_table_exists(
ut_ad(!srv_any_background_activity());
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
sys_table = dict_table_get_low(tablename);
@ -1377,7 +1377,7 @@ dict_check_if_system_table_exists(
dict_table_prevent_eviction(sys_table);
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
return(error);
}
@ -1545,9 +1545,9 @@ dict_create_or_check_sys_virtual()
"SYS_VIRTUAL", DICT_NUM_FIELDS__SYS_VIRTUAL + 1, 1);
if (err == DB_SUCCESS) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_sys.sys_virtual = dict_table_get_low("SYS_VIRTUAL");
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
return(DB_SUCCESS);
}
@ -1620,9 +1620,9 @@ dict_create_or_check_sys_virtual()
dberr_t sys_virtual_err = dict_check_if_system_table_exists(
"SYS_VIRTUAL", DICT_NUM_FIELDS__SYS_VIRTUAL + 1, 1);
ut_a(sys_virtual_err == DB_SUCCESS);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_sys.sys_virtual = dict_table_get_low("SYS_VIRTUAL");
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
return(err);
}
@ -1646,7 +1646,7 @@ dict_foreign_eval_sql(
error = que_eval_sql(info, sql, FALSE, trx);
if (error == DB_DUPLICATE_KEY) {
mutex_enter(&dict_foreign_err_mutex);
mysql_mutex_lock(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
fputs(" Error in foreign key constraint creation for table ",
@ -1666,7 +1666,7 @@ dict_foreign_eval_sql(
"explicitly with unique names.\n",
ef);
mutex_exit(&dict_foreign_err_mutex);
mysql_mutex_unlock(&dict_foreign_err_mutex);
return(error);
}
@ -1675,7 +1675,7 @@ dict_foreign_eval_sql(
ib::error() << "Foreign key constraint creation failed: "
<< error;
mutex_enter(&dict_foreign_err_mutex);
mysql_mutex_lock(&dict_foreign_err_mutex);
ut_print_timestamp(ef);
fputs(" Internal error in foreign key constraint creation"
" for table ", ef);
@ -1683,7 +1683,7 @@ dict_foreign_eval_sql(
fputs(".\n"
"See the MySQL .err log in the datadir"
" for more information.\n", ef);
mutex_exit(&dict_foreign_err_mutex);
mysql_mutex_unlock(&dict_foreign_err_mutex);
return(error);
}
@ -2019,7 +2019,7 @@ dict_create_add_foreigns_to_dictionary(
dict_foreign_t* foreign;
dberr_t error;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
if (NULL == dict_table_get_low("SYS_FOREIGN")) {

View file

@ -30,11 +30,7 @@ Created 25/08/2016 Jan Lindström
#include "btr0btr.h"
#include "srv0start.h"
static ib_mutex_t defrag_pool_mutex;
#ifdef MYSQL_PFS
static mysql_pfs_key_t defrag_pool_mutex_key;
#endif
static mysql_mutex_t defrag_pool_mutex;
/** Iterator type for iterating over the elements of objects of type
defrag_pool_t. */
@ -52,9 +48,7 @@ dict_defrag_pool_init(void)
/*=======================*/
{
ut_ad(!srv_read_only_mode);
/* We choose SYNC_STATS_DEFRAG to be below SYNC_FSP_PAGE. */
mutex_create(LATCH_ID_DEFRAGMENT_MUTEX, &defrag_pool_mutex);
mysql_mutex_init(0, &defrag_pool_mutex, nullptr);
}
/*****************************************************************//**
@ -66,7 +60,7 @@ dict_defrag_pool_deinit(void)
{
ut_ad(!srv_read_only_mode);
mutex_free(&defrag_pool_mutex);
mysql_mutex_destroy(&defrag_pool_mutex);
}
/*****************************************************************//**
@ -84,10 +78,10 @@ dict_stats_defrag_pool_get(
{
ut_ad(!srv_read_only_mode);
mutex_enter(&defrag_pool_mutex);
mysql_mutex_lock(&defrag_pool_mutex);
if (defrag_pool.empty()) {
mutex_exit(&defrag_pool_mutex);
mysql_mutex_unlock(&defrag_pool_mutex);
return(false);
}
@ -97,7 +91,7 @@ dict_stats_defrag_pool_get(
defrag_pool.pop_back();
mutex_exit(&defrag_pool_mutex);
mysql_mutex_unlock(&defrag_pool_mutex);
return(true);
}
@ -117,7 +111,7 @@ dict_stats_defrag_pool_add(
ut_ad(!srv_read_only_mode);
mutex_enter(&defrag_pool_mutex);
mysql_mutex_lock(&defrag_pool_mutex);
/* quit if already in the list */
for (defrag_pool_iterator_t iter = defrag_pool.begin();
@ -125,7 +119,7 @@ dict_stats_defrag_pool_add(
++iter) {
if ((*iter).table_id == index->table->id
&& (*iter).index_id == index->id) {
mutex_exit(&defrag_pool_mutex);
mysql_mutex_unlock(&defrag_pool_mutex);
return;
}
}
@ -137,7 +131,7 @@ dict_stats_defrag_pool_add(
/* Kick off dict stats optimizer work */
dict_stats_schedule_now();
}
mutex_exit(&defrag_pool_mutex);
mysql_mutex_unlock(&defrag_pool_mutex);
}
/*****************************************************************//**
@ -151,9 +145,9 @@ dict_stats_defrag_pool_del(
{
ut_a((table && !index) || (!table && index));
ut_ad(!srv_read_only_mode);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
mutex_enter(&defrag_pool_mutex);
mysql_mutex_lock(&defrag_pool_mutex);
defrag_pool_iterator_t iter = defrag_pool.begin();
while (iter != defrag_pool.end()) {
@ -170,7 +164,7 @@ dict_stats_defrag_pool_del(
}
}
mutex_exit(&defrag_pool_mutex);
mysql_mutex_unlock(&defrag_pool_mutex);
}
/*****************************************************************//**
@ -193,7 +187,7 @@ dict_stats_process_entry_from_defrag_pool()
dict_table_t* table;
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
/* If the table is no longer cached, we've already lost the in
memory stats so there's nothing really to write to disk. */
@ -208,11 +202,11 @@ dict_stats_process_entry_from_defrag_pool()
if (table) {
dict_table_close(table, TRUE, FALSE);
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
return;
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
dict_stats_save_defrag_stats(index);
dict_table_close(table, FALSE, FALSE);
}

View file

@ -72,7 +72,6 @@ extern uint ibuf_debug;
#include "row0upd.h"
#include "srv0mon.h"
#include "srv0start.h"
#include "sync0sync.h"
#include "trx0undo.h"
#include <vector>
@ -81,6 +80,12 @@ extern uint ibuf_debug;
/** the dictionary system */
dict_sys_t dict_sys;
/** Diagnostic message for exceeding the mutex_lock_wait() timeout */
const char dict_sys_t::fatal_msg[]=
"innodb_fatal_semaphore_wait_threshold was exceeded for dict_sys.mutex. "
"Please refer to "
"https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/";
/** Percentage of compression failures that are allowed in a single
round */
ulong zip_failure_threshold_pct = 5;
@ -168,7 +173,7 @@ dict_lru_validate(void);
and unique key errors. Only created if !srv_read_only_mode */
FILE* dict_foreign_err_file = NULL;
/* mutex protecting the foreign and unique error buffers */
ib_mutex_t dict_foreign_err_mutex;
mysql_mutex_t dict_foreign_err_mutex;
/********************************************************************//**
Checks if the database name in two table names is the same.
@ -288,11 +293,11 @@ dict_table_try_drop_aborted_and_mutex_exit(
was aborted. */
table_id_t table_id = table->id;
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
dict_table_try_drop_aborted(table, table_id, 1);
} else {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
}
@ -313,10 +318,10 @@ dict_table_close(
MDL_ticket* mdl)
{
if (!dict_locked) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_a(table->get_ref_count() > 0);
const bool last_handle = table->release();
@ -343,7 +348,7 @@ dict_table_close(
&& table->drop_aborted
&& dict_table_get_first_index(table);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
/* dict_table_try_drop_aborted() can generate undo logs.
So it should be avoided after shutdown of background
@ -738,9 +743,8 @@ bool dict_table_t::parse_name(char (&db_name)[NAME_LEN + 1],
char tbl_buf[MAX_TABLE_NAME_LEN + 1];
if (!dict_locked)
mutex_enter(&dict_sys.mutex); /* protect against renaming */
else
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.mutex_lock(); /* protect against renaming */
dict_sys.assert_locked();
const size_t db_len= name.dblen();
ut_ad(db_len <= MAX_DATABASE_NAME_LEN);
@ -761,7 +765,7 @@ bool dict_table_t::parse_name(char (&db_name)[NAME_LEN + 1],
tbl_buf[tbl_len]= 0;
if (!dict_locked)
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
*db_name_len= filename_to_tablename(db_buf, db_name,
MAX_DATABASE_NAME_LEN + 1, true);
@ -801,13 +805,13 @@ dict_acquire_mdl_shared(dict_table_t *table,
if (trylock)
{
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
db_len= dict_get_db_name_len(table->name.m_name);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
else
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
db_len= dict_get_db_name_len(table->name.m_name);
}
@ -846,7 +850,7 @@ is_unaccessible:
return nullptr;
if (!trylock)
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
{
MDL_request request;
MDL_REQUEST_INIT(&request,MDL_key::TABLE, db_buf, tbl_buf, MDL_SHARED, MDL_EXPLICIT);
@ -867,7 +871,7 @@ is_unaccessible:
}
if (!trylock)
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
else if (!*mdl)
return nullptr;
@ -940,10 +944,10 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked,
ut_ad(!dict_locked || !thd);
if (!dict_locked) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
dict_table_t* table = dict_table_open_on_id_low(
table_id,
@ -1029,7 +1033,7 @@ void dict_sys_t::create()
UT_LIST_INIT(table_LRU, &dict_table_t::table_LRU);
UT_LIST_INIT(table_non_LRU, &dict_table_t::table_LRU);
mutex_create(LATCH_ID_DICT_SYS, &mutex);
mysql_mutex_init(dict_sys_mutex_key, &mutex, nullptr);
const ulint hash_size = buf_pool_get_curr_size()
/ (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE);
@ -1046,9 +1050,11 @@ void dict_sys_t::create()
ut_a(dict_foreign_err_file);
}
mutex_create(LATCH_ID_DICT_FOREIGN_ERR, &dict_foreign_err_mutex);
mysql_mutex_init(dict_foreign_err_mutex_key, &dict_foreign_err_mutex,
nullptr);
}
/** Acquire a reference to a cached table. */
inline void dict_sys_t::acquire(dict_table_t* table)
{
@ -1062,6 +1068,54 @@ inline void dict_sys_t::acquire(dict_table_t* table)
table->acquire();
}
void dict_sys_t::mutex_lock_wait()
{
ulonglong now= my_hrtime_coarse().val, old= 0;
if (mutex_wait_start.compare_exchange_strong
(old, now, std::memory_order_relaxed, std::memory_order_relaxed))
{
mysql_mutex_lock(&mutex);
mutex_wait_start.store(0, std::memory_order_relaxed);
return;
}
ut_ad(old);
/* We could have old > now due to our use of my_hrtime_coarse(). */
ulong waited= old <= now ? static_cast<ulong>((now - old) / 1000000) : 0;
const ulong threshold= srv_fatal_semaphore_wait_threshold;
if (waited >= threshold)
ib::fatal() << fatal_msg;
if (waited > threshold / 4)
ib::warn() << "A long wait (" << waited
<< " seconds) was observed for dict_sys.mutex";
mysql_mutex_lock(&mutex);
}
#ifdef HAVE_PSI_MUTEX_INTERFACE
/** Acquire the mutex */
void dict_sys_t::mutex_lock()
{
if (mysql_mutex_trylock(&mutex))
mutex_lock_wait();
}
/** Release the mutex */
void dict_sys_t::mutex_unlock() { mysql_mutex_unlock(&mutex); }
#endif
/** Lock the data dictionary cache. */
void dict_sys_t::lock(SRW_LOCK_ARGS(const char *file, unsigned line))
{
ut_ad(this == &dict_sys);
ut_ad(is_initialised());
latch.wr_lock(SRW_LOCK_ARGS(file, line));
ut_ad(!latch_ex);
ut_d(latch_ex= true);
mutex_lock();
}
/**********************************************************************//**
Returns a table object and increment its open handle count.
NOTE! This is a high-level function to be used mainly from outside the
@ -1085,11 +1139,11 @@ dict_table_open_on_name(
DBUG_PRINT("dict_table_open_on_name", ("table: '%s'", table_name));
if (!dict_locked) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
ut_ad(table_name);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
table = dict_table_check_if_in_cache_low(table_name);
@ -1113,7 +1167,7 @@ dict_table_open_on_name(
<< " is corrupted. Please "
"drop the table and recreate.";
if (!dict_locked) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
DBUG_RETURN(NULL);
@ -1122,7 +1176,7 @@ dict_table_open_on_name(
dict_sys.acquire(table);
if (!dict_locked) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
DBUG_RETURN(table);
@ -1509,7 +1563,7 @@ dict_table_rename_in_cache(
char old_name[MAX_FULL_NAME_LEN + 1];
os_file_type_t ftype;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
/* store the old/current name to an automatic variable */
ut_a(strlen(table->name.m_name) < sizeof old_name);
@ -1890,7 +1944,7 @@ dict_table_change_id_in_cache(
dict_table_t* table, /*!< in/out: table object already in cache */
table_id_t new_id) /*!< in: new id to set */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_ad(!table->is_temporary());
@ -2049,7 +2103,7 @@ dict_index_add_to_cache(
ulint n_ord;
ulint i;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_ad(index->n_def == index->n_fields);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(!dict_index_is_online_ddl(index));
@ -2180,7 +2234,7 @@ dict_index_remove_from_cache_low(
ut_ad(table && index);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_ad(table->id);
#ifdef BTR_CUR_HASH_ADAPT
ut_ad(!index->freed());
@ -2200,9 +2254,9 @@ dict_index_remove_from_cache_low(
/* The index is being dropped, remove any compression stats for it. */
if (!lru_evict && DICT_TF_GET_ZIP_SSIZE(index->table->flags)) {
mutex_enter(&page_zip_stat_per_index_mutex);
mysql_mutex_lock(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index.erase(index->id);
mutex_exit(&page_zip_stat_per_index_mutex);
mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
}
/* Remove the index from affected virtual column index list */
@ -2260,7 +2314,7 @@ dict_index_find_cols(
const dict_table_t* table = index->table;
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
for (ulint i = 0; i < index->n_fields; i++) {
ulint j;
@ -2529,7 +2583,7 @@ dict_index_build_internal_clust(
ut_ad(dict_index_is_clust(index));
ut_ad(!dict_index_is_ibuf(index));
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
/* Create a new index object with certainly enough fields */
new_index = dict_mem_index_create(index->table, index->name,
@ -2684,7 +2738,7 @@ dict_index_build_internal_non_clust(
ut_ad(table && index);
ut_ad(!dict_index_is_clust(index));
ut_ad(!dict_index_is_ibuf(index));
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
/* The clustered index should be the first in the list of indexes */
clust_index = UT_LIST_GET_FIRST(table->indexes);
@ -2778,7 +2832,7 @@ dict_index_build_internal_fts(
dict_index_t* new_index;
ut_ad(index->type == DICT_FTS);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
/* Create a new index */
new_index = dict_mem_index_create(index->table, index->name,
@ -2830,7 +2884,7 @@ dict_foreign_remove_from_cache(
/*===========================*/
dict_foreign_t* foreign) /*!< in, own: foreign constraint */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_a(foreign);
if (foreign->referenced_table != NULL) {
@ -2855,7 +2909,7 @@ dict_foreign_find(
dict_table_t* table, /*!< in: table object */
dict_foreign_t* foreign) /*!< in: foreign constraint */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_ad(dict_foreign_set_validate(table->foreign_set));
ut_ad(dict_foreign_set_validate(table->referenced_set));
@ -2909,7 +2963,7 @@ dict_foreign_find_index(
/*!< out: index where error
happened */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
if (error) {
*error = FK_INDEX_NOT_FOUND;
@ -2962,7 +3016,7 @@ dict_foreign_error_report(
const char* msg) /*!< in: the error message */
{
std::string fk_str;
mutex_enter(&dict_foreign_err_mutex);
mysql_mutex_lock(&dict_foreign_err_mutex);
dict_foreign_error_report_low(file, fk->foreign_table_name);
fputs(msg, file);
fputs(" Constraint:\n", file);
@ -2974,7 +3028,7 @@ dict_foreign_error_report(
" %s\n%s\n", fk->foreign_index->name(),
FOREIGN_KEY_CONSTRAINTS_MSG);
}
mutex_exit(&dict_foreign_err_mutex);
mysql_mutex_unlock(&dict_foreign_err_mutex);
}
/**********************************************************************//**
@ -3007,7 +3061,7 @@ dict_foreign_add_to_cache(
DBUG_ENTER("dict_foreign_add_to_cache");
DBUG_PRINT("dict_foreign_add_to_cache", ("id: %s", foreign->id));
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
for_table = dict_table_check_if_in_cache_low(
foreign->foreign_table_name_lookup);
@ -3652,7 +3706,7 @@ dict_foreign_parse_drop_constraints(
ptr = str;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
loop:
ptr = dict_scan_to(ptr, "DROP");
@ -3711,7 +3765,7 @@ loop:
if (!srv_read_only_mode) {
FILE* ef = dict_foreign_err_file;
mutex_enter(&dict_foreign_err_mutex);
mysql_mutex_lock(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
fputs(" Error in dropping of a foreign key"
@ -3720,7 +3774,7 @@ loop:
fprintf(ef, ",\nin SQL command\n%s"
"\nCannot find a constraint with the"
" given id %s.\n", str, id);
mutex_exit(&dict_foreign_err_mutex);
mysql_mutex_unlock(&dict_foreign_err_mutex);
}
ut_free(str);
@ -3734,7 +3788,7 @@ syntax_error:
if (!srv_read_only_mode) {
FILE* ef = dict_foreign_err_file;
mutex_enter(&dict_foreign_err_mutex);
mysql_mutex_lock(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
fputs(" Syntax error in dropping of a"
@ -3742,7 +3796,7 @@ syntax_error:
ut_print_name(ef, NULL, table->name.m_name);
fprintf(ef, ",\n"
"close to:\n%s\n in SQL command\n%s\n", ptr, str);
mutex_exit(&dict_foreign_err_mutex);
mysql_mutex_unlock(&dict_foreign_err_mutex);
}
ut_free(str);
@ -3761,7 +3815,7 @@ dict_index_get_if_in_cache_low(
/*===========================*/
index_id_t index_id) /*!< in: index id */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
return(dict_index_find_on_id_low(index_id));
}
@ -3781,11 +3835,11 @@ dict_index_get_if_in_cache(
return(NULL);
}
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
index = dict_index_get_if_in_cache_low(index_id);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
return(index);
}
@ -4066,7 +4120,7 @@ dict_print_info_on_foreign_keys(
dict_foreign_t* foreign;
std::string str;
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
for (dict_foreign_set::iterator it = table->foreign_set.begin();
it != table->foreign_set.end();
@ -4133,7 +4187,7 @@ dict_print_info_on_foreign_keys(
}
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
return str;
}
@ -4231,10 +4285,9 @@ dict_set_corrupted(
row_mysql_lock_data_dictionary(trx);
}
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_ad(!dict_table_is_comp(dict_sys.sys_tables));
ut_ad(!dict_table_is_comp(dict_sys.sys_indexes));
ut_ad(!sync_check_iterate(dict_sync_check()));
/* Mark the table as corrupted only if the clustered index
is corrupted */
@ -4320,7 +4373,7 @@ dict_set_corrupted_index_cache_only(
{
ut_ad(index != NULL);
ut_ad(index->table != NULL);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_ad(!dict_table_is_comp(dict_sys.sys_tables));
ut_ad(!dict_table_is_comp(dict_sys.sys_indexes));
@ -4430,14 +4483,14 @@ void
dict_set_merge_threshold_all_debug(
uint merge_threshold_all)
{
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_set_merge_threshold_list_debug(
&dict_sys.table_LRU, merge_threshold_all);
dict_set_merge_threshold_list_debug(
&dict_sys.table_non_LRU, merge_threshold_all);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
#endif /* UNIV_DEBUG */
@ -4555,7 +4608,7 @@ dict_table_check_for_dup_indexes(
const dict_index_t* index1;
const dict_index_t* index2;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
/* The primary index _must_ exist */
ut_a(UT_LIST_GET_LEN(table->indexes) > 0);
@ -4632,7 +4685,7 @@ dict_table_schema_check(
dict_table_t* table;
ulint i;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
table = dict_table_get_low(req_schema->table_name);
@ -4881,7 +4934,7 @@ void dict_sys_t::resize()
{
ut_ad(this == &dict_sys);
ut_ad(is_initialised());
mutex_enter(&mutex);
mutex_lock();
/* all table entries are in table_LRU and table_non_LRU lists */
table_hash.free();
@ -4919,7 +4972,7 @@ void dict_sys_t::resize()
HASH_INSERT(dict_table_t, id_hash, id_hash, id_fold, table);
}
mutex_exit(&mutex);
mutex_unlock();
}
/** Close the data dictionary cache on shutdown. */
@ -4928,7 +4981,7 @@ void dict_sys_t::close()
ut_ad(this == &dict_sys);
if (!is_initialised()) return;
mutex_enter(&mutex);
mutex_lock();
/* Free the hash elements. We don't remove them from the table
because we are going to destroy the table anyway. */
@ -4946,11 +4999,11 @@ void dict_sys_t::close()
/* No temporary tables should exist at this point. */
temp_id_hash.free();
mutex_exit(&mutex);
mutex_free(&mutex);
mutex_unlock();
mysql_mutex_destroy(&mutex);
latch.destroy();
mutex_free(&dict_foreign_err_mutex);
mysql_mutex_destroy(&dict_foreign_err_mutex);
if (dict_foreign_err_file)
{
@ -4972,7 +5025,7 @@ dict_lru_validate(void)
{
dict_table_t* table;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
for (table = UT_LIST_GET_FIRST(dict_sys.table_LRU);
table != NULL;

View file

@ -218,7 +218,7 @@ dict_get_first_table_name_in_db(
ulint len;
mtr_t mtr;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
heap = mem_heap_create(1000);
@ -673,7 +673,7 @@ dict_sys_tables_rec_check(
const byte* field;
ulint len;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
if (rec_get_deleted_flag(rec, 0)) {
return("delete-marked record in SYS_TABLES");
@ -1397,7 +1397,7 @@ dict_load_columns(
mtr_t mtr;
ulint n_skipped = 0;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
mtr_start(&mtr);
@ -1513,7 +1513,7 @@ dict_load_virtual_one_col(
mtr_t mtr;
ulint skipped = 0;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
if (v_col->num_base == 0) {
return;
@ -1746,7 +1746,7 @@ dict_load_fields(
mtr_t mtr;
dberr_t error;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
mtr_start(&mtr);
@ -1977,7 +1977,7 @@ dict_load_indexes(
mtr_t mtr;
dberr_t error = DB_SUCCESS;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
mtr_start(&mtr);
@ -2271,7 +2271,7 @@ dict_save_data_dir_path(
dict_table_t* table, /*!< in/out: table */
const char* filepath) /*!< in: filepath of tablespace */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_a(DICT_TF_HAS_DATA_DIR(table->flags));
ut_a(!table->data_dir_path);
@ -2308,7 +2308,7 @@ dict_get_and_save_data_dir_path(
if (!table->data_dir_path && table->space_id && table->space) {
if (!dict_mutex_own) {
dict_mutex_enter_for_mysql();
dict_sys.mutex_lock();
}
table->flags |= 1 << DICT_TF_POS_DATA_DIR
@ -2327,7 +2327,7 @@ dict_get_and_save_data_dir_path(
}
if (!dict_mutex_own) {
dict_mutex_exit_for_mysql();
dict_sys.mutex_unlock();
}
}
}
@ -2351,7 +2351,7 @@ dict_table_t* dict_load_table(const char* name, dict_err_ignore_t ignore_err)
DBUG_ENTER("dict_load_table");
DBUG_PRINT("dict_load_table", ("loading table: '%s'", name));
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
result = dict_table_check_if_in_cache_low(name);
@ -2484,7 +2484,7 @@ dict_load_table_one(
DBUG_ENTER("dict_load_table_one");
DBUG_PRINT("dict_load_table_one", ("table: %s", name.m_name));
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
heap = mem_heap_create(32000);
@ -2730,7 +2730,7 @@ dict_load_table_on_id(
dict_table_t* table;
mtr_t mtr;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
table = NULL;
@ -2815,7 +2815,7 @@ dict_load_sys_table(
{
mem_heap_t* heap;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
heap = mem_heap_create(1000);
@ -2852,7 +2852,7 @@ dict_load_foreign_cols(
mtr_t mtr;
size_t id_len;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
id_len = strlen(foreign->id);
@ -2998,7 +2998,7 @@ dict_load_foreign(
DBUG_PRINT("dict_load_foreign",
("id: '%s', check_recursive: %d", id, check_recursive));
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
id_len = strlen(id);
@ -3173,7 +3173,7 @@ dict_load_foreigns(
DBUG_ENTER("dict_load_foreigns");
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
sys_foreign = dict_table_get_low("SYS_FOREIGN");
@ -3332,7 +3332,7 @@ dict_load_table_id_on_index_id(
bool found = false;
mtr_t mtr;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
/* NOTE that the operation of this function is protected by
the dictionary mutex, and therefore no deadlocks can occur

View file

@ -35,7 +35,6 @@ Created 1/8/1996 Heikki Tuuri
#include "dict0dict.h"
#include "fts0priv.h"
#include "lock0lock.h"
#include "sync0sync.h"
#include "row0row.h"
#include "sql_string.h"
#include <iostream>
@ -791,8 +790,8 @@ dict_mem_index_create(
index->rtr_track = new
(mem_heap_alloc(heap, sizeof *index->rtr_track))
rtr_info_track_t();
mutex_create(LATCH_ID_RTR_ACTIVE_MUTEX,
&index->rtr_track->rtr_active_mutex);
mysql_mutex_init(rtr_active_mutex_key,
&index->rtr_track->rtr_active_mutex, nullptr);
}
return(index);
@ -1101,7 +1100,7 @@ dict_mem_index_free(
rtr_info->index = NULL;
}
mutex_destroy(&index->rtr_track->rtr_active_mutex);
mysql_mutex_destroy(&index->rtr_track->rtr_active_mutex);
index->rtr_track->~rtr_info_track_t();
}

View file

@ -33,7 +33,6 @@ Created Jan 06, 2010 Vasil Dimov
#include "pars0pars.h"
#include <mysql_com.h>
#include "btr0btr.h"
#include "sync0sync.h"
#include <algorithm>
#include <map>
@ -236,10 +235,10 @@ dict_stats_persistent_storage_check(
dberr_t ret;
if (!caller_has_dict_sys_mutex) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
/* first check table_stats */
ret = dict_table_schema_check(&table_stats_schema, errstr,
@ -251,7 +250,7 @@ dict_stats_persistent_storage_check(
}
if (!caller_has_dict_sys_mutex) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
if (ret != DB_SUCCESS && ret != DB_STATS_DO_NOT_EXIST) {
@ -511,7 +510,7 @@ dict_stats_empty_index(
{
ut_ad(!(index->type & DICT_FTS));
ut_ad(!dict_index_is_ibuf(index));
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ulint n_uniq = index->n_uniq;
@ -541,7 +540,7 @@ dict_stats_empty_table(
bool empty_defrag_stats)
/*!< in: whether to empty defrag stats */
{
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
/* Zero the stats members */
table->stat_n_rows = 0;
@ -567,7 +566,7 @@ dict_stats_empty_table(
}
table->stat_initialized = TRUE;
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
/*********************************************************************//**
@ -666,7 +665,7 @@ dict_stats_copy(
to have the same statistics as if
the table was empty */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
dst->stats_last_recalc = src->stats_last_recalc;
dst->stat_n_rows = src->stat_n_rows;
@ -783,7 +782,7 @@ dict_table_t*
dict_stats_snapshot_create(
dict_table_t* table)
{
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_stats_assert_initialized(table);
@ -798,7 +797,7 @@ dict_stats_snapshot_create(
t->stats_sample_pages = table->stats_sample_pages;
t->stats_bg_flag = table->stats_bg_flag;
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
return(t);
}
@ -837,14 +836,14 @@ dict_stats_update_transient_for_index(
Initialize some bogus index cardinality
statistics, so that the data can be queried in
various means, also via secondary indexes. */
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_stats_empty_index(index, false);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
} else if (ibuf_debug && !dict_index_is_clust(index)) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_stats_empty_index(index, false);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
} else {
mtr_t mtr;
@ -865,9 +864,9 @@ dict_stats_update_transient_for_index(
switch (size) {
case ULINT_UNDEFINED:
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_stats_empty_index(index, false);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
return;
case 0:
/* The root node of the tree is a leaf */
@ -884,8 +883,7 @@ dict_stats_update_transient_for_index(
index);
if (!stats.empty()) {
ut_ad(!mutex_own(&dict_sys.mutex));
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
for (size_t i = 0; i < stats.size(); ++i) {
index->stat_n_diff_key_vals[i]
= stats[i].n_diff_key_vals;
@ -894,7 +892,7 @@ dict_stats_update_transient_for_index(
index->stat_n_non_null_key_vals[i]
= stats[i].n_non_null_key_vals;
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
}
}
@ -912,7 +910,7 @@ dict_stats_update_transient(
/*========================*/
dict_table_t* table) /*!< in/out: table */
{
ut_ad(!mutex_own(&dict_sys.mutex));
dict_sys.assert_not_locked();
dict_index_t* index;
ulint sum_of_index_sizes = 0;
@ -945,9 +943,9 @@ dict_stats_update_transient(
if (dict_stats_should_ignore_index(index)
|| !index->is_readable()) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_stats_empty_index(index, false);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
continue;
}
@ -956,7 +954,7 @@ dict_stats_update_transient(
sum_of_index_sizes += index->stat_index_size;
}
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
index = dict_table_get_first_index(table);
@ -974,7 +972,7 @@ dict_stats_update_transient(
table->stat_initialized = TRUE;
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
/* @{ Pseudo code about the relation between the following functions
@ -1932,7 +1930,7 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index)
DBUG_PRINT("info", ("index: %s, online status: %d", index->name(),
dict_index_get_online_status(index)));
ut_ad(!mutex_own(&dict_sys.mutex)); // because this function is slow
dict_sys.assert_not_locked(); // this function is slow
ut_ad(index->table->get_ref_count());
/* Disable update statistic for Rtree */
@ -2004,14 +2002,14 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index)
mtr.commit();
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
for (ulint i = 0; i < n_uniq; i++) {
result.stats[i].n_diff_key_vals = index->stat_n_diff_key_vals[i];
result.stats[i].n_sample_sizes = total_pages;
result.stats[i].n_non_null_key_vals = index->stat_n_non_null_key_vals[i];
}
result.n_leaf_pages = index->stat_n_leaf_pages;
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
DBUG_RETURN(result);
}
@ -2245,13 +2243,13 @@ dict_stats_update_persistent(
}
ut_ad(!dict_index_is_ibuf(index));
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_stats_empty_index(index, false);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
index_stats_t stats = dict_stats_analyze_index(index);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
index->stat_index_size = stats.index_size;
index->stat_n_leaf_pages = stats.n_leaf_pages;
for (size_t i = 0; i < stats.stats.size(); ++i) {
@ -2287,9 +2285,9 @@ dict_stats_update_persistent(
}
if (!(table->stats_bg_flag & BG_STAT_SHOULD_QUIT)) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
stats = dict_stats_analyze_index(index);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
index->stat_index_size = stats.index_size;
index->stat_n_leaf_pages = stats.n_leaf_pages;
@ -2315,7 +2313,7 @@ dict_stats_update_persistent(
dict_stats_assert_initialized(table);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
return(DB_SUCCESS);
}
@ -2991,8 +2989,6 @@ dict_stats_fetch_from_ps(
char db_utf8[MAX_DB_UTF8_LEN];
char table_utf8[MAX_TABLE_UTF8_LEN];
ut_ad(!mutex_own(&dict_sys.mutex));
/* Initialize all stats to dummy values before fetching because if
the persistent storage contains incomplete stats (e.g. missing stats
for some index) then we would end up with (partially) uninitialized
@ -3127,13 +3123,13 @@ dict_stats_update_for_index(
{
DBUG_ENTER("dict_stats_update_for_index");
ut_ad(!mutex_own(&dict_sys.mutex));
dict_sys.assert_not_locked();
if (dict_stats_is_persistent_enabled(index->table)) {
if (dict_stats_persistent_storage_check(false)) {
index_stats_t stats = dict_stats_analyze_index(index);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
index->stat_index_size = stats.index_size;
index->stat_n_leaf_pages = stats.n_leaf_pages;
for (size_t i = 0; i < stats.stats.size(); ++i) {
@ -3146,7 +3142,7 @@ dict_stats_update_for_index(
}
index->table->stat_sum_of_other_index_sizes
+= index->stat_index_size;
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
dict_stats_save(index->table, &index->id);
DBUG_VOID_RETURN;
@ -3187,7 +3183,7 @@ dict_stats_update(
the persistent statistics
storage */
{
ut_ad(!mutex_own(&dict_sys.mutex));
dict_sys.assert_not_locked();
if (!table->is_readable()) {
return (dict_stats_report_error(table));
@ -3322,7 +3318,7 @@ dict_stats_update(
switch (err) {
case DB_SUCCESS:
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
/* Pass reset_ignored_indexes=true as parameter
to dict_stats_copy. This will cause statictics
@ -3331,7 +3327,7 @@ dict_stats_update(
dict_stats_assert_initialized(table);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
dict_stats_table_clone_free(t);
@ -3417,7 +3413,7 @@ dict_stats_drop_index(
pars_info_t* pinfo;
dberr_t ret;
ut_ad(!mutex_own(&dict_sys.mutex));
dict_sys.assert_not_locked();
/* skip indexes whose table names do not contain a database name
e.g. if we are dropping an index from SYS_TABLES */
@ -3953,7 +3949,7 @@ test_dict_table_schema_check()
/* prevent any data dictionary modifications while we are checking
the tables' structure */
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
/* check that a valid table is reported as valid */
schema.n_cols = 7;
@ -4029,7 +4025,7 @@ test_dict_table_schema_check()
test_dict_table_schema_check_end:
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
/* @} */

View file

@ -51,7 +51,7 @@ my_bool innodb_dict_stats_disabled_debug;
#endif /* UNIV_DEBUG */
/** This mutex protects the "recalc_pool" variable. */
static ib_mutex_t recalc_pool_mutex;
static mysql_mutex_t recalc_pool_mutex;
/** Allocator type, used by std::vector */
typedef ut_allocator<table_id_t>
@ -112,7 +112,7 @@ dict_stats_recalc_pool_add(
{
ut_ad(!srv_read_only_mode);
mutex_enter(&recalc_pool_mutex);
mysql_mutex_lock(&recalc_pool_mutex);
/* quit if already in the list */
for (recalc_pool_iterator_t iter = recalc_pool.begin();
@ -120,7 +120,7 @@ dict_stats_recalc_pool_add(
++iter) {
if (*iter == table->id) {
mutex_exit(&recalc_pool_mutex);
mysql_mutex_unlock(&recalc_pool_mutex);
return;
}
}
@ -129,7 +129,7 @@ dict_stats_recalc_pool_add(
if (recalc_pool.size() == 1 && schedule_dict_stats_task) {
dict_stats_schedule_now();
}
mutex_exit(&recalc_pool_mutex);
mysql_mutex_unlock(&recalc_pool_mutex);
}
@ -147,7 +147,7 @@ void dict_stats_update_if_needed_func(dict_table_t *table)
#endif
{
ut_ad(table->stat_initialized);
ut_ad(!mutex_own(&dict_sys.mutex));
dict_sys.assert_not_locked();
ulonglong counter = table->stat_modified_counter++;
ulonglong n_rows = dict_table_get_n_rows(table);
@ -215,10 +215,10 @@ dict_stats_recalc_pool_get(
{
ut_ad(!srv_read_only_mode);
mutex_enter(&recalc_pool_mutex);
mysql_mutex_lock(&recalc_pool_mutex);
if (recalc_pool.empty()) {
mutex_exit(&recalc_pool_mutex);
mysql_mutex_unlock(&recalc_pool_mutex);
return(false);
}
@ -226,7 +226,7 @@ dict_stats_recalc_pool_get(
recalc_pool.erase(recalc_pool.begin());
mutex_exit(&recalc_pool_mutex);
mysql_mutex_unlock(&recalc_pool_mutex);
return(true);
}
@ -240,9 +240,9 @@ dict_stats_recalc_pool_del(
const dict_table_t* table) /*!< in: table to remove */
{
ut_ad(!srv_read_only_mode);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
mutex_enter(&recalc_pool_mutex);
mysql_mutex_lock(&recalc_pool_mutex);
ut_ad(table->id > 0);
@ -257,7 +257,7 @@ dict_stats_recalc_pool_del(
}
}
mutex_exit(&recalc_pool_mutex);
mysql_mutex_unlock(&recalc_pool_mutex);
}
/*****************************************************************//**
@ -286,26 +286,10 @@ Initialize global variables needed for the operation of dict_stats_thread()
Must be called before dict_stats_thread() is started. */
void dict_stats_init()
{
ut_ad(!srv_read_only_mode);
/* The recalc_pool_mutex is acquired from:
1) the background stats gathering thread before any other latch
and released without latching anything else in between (thus
any level would do here)
2) from dict_stats_update_if_needed()
and released without latching anything else in between. We know
that dict_sys.mutex (SYNC_DICT) is not acquired when
dict_stats_update_if_needed() is called and it may be acquired
inside that function (thus a level <=SYNC_DICT would do).
3) from row_drop_table_for_mysql() after dict_sys.mutex (SYNC_DICT)
and dict_sys.latch have been locked
(thus a level <SYNC_DICT would do)
So we choose SYNC_STATS_AUTO_RECALC to be about below SYNC_DICT. */
mutex_create(LATCH_ID_RECALC_POOL, &recalc_pool_mutex);
dict_defrag_pool_init();
stats_initialised = true;
ut_ad(!srv_read_only_mode);
mysql_mutex_init(recalc_pool_mutex_key, &recalc_pool_mutex, nullptr);
dict_defrag_pool_init();
stats_initialised= true;
}
/*****************************************************************//**
@ -323,7 +307,7 @@ void dict_stats_deinit()
dict_stats_recalc_pool_deinit();
dict_defrag_pool_deinit();
mutex_free(&recalc_pool_mutex);
mysql_mutex_destroy(&recalc_pool_mutex);
}
/**
@ -345,28 +329,28 @@ next_table_id:
dict_table_t* table;
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
table = dict_table_open_on_id(table_id, TRUE, DICT_TABLE_OP_NORMAL);
if (table == NULL) {
/* table does not exist, must have been DROPped
after its id was enqueued */
mutex_exit(&dict_sys.mutex);
goto next_table_id;
goto no_table;
}
ut_ad(!table->is_temporary());
if (!table->is_accessible()) {
dict_table_close(table, TRUE, FALSE);
mutex_exit(&dict_sys.mutex);
no_table:
dict_sys.mutex_unlock();
goto next_table_id;
}
table->stats_bg_flag |= BG_STAT_IN_PROGRESS;
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
/* time() could be expensive, the current function
is called once every time a table has been changed more than 10% and
@ -391,13 +375,13 @@ next_table_id:
ret = true;
}
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
table->stats_bg_flag = BG_STAT_NONE;
dict_table_close(table, TRUE, FALSE);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
return ret;
}

View file

@ -353,7 +353,7 @@ void fil_crypt_parse(fil_space_t* space, const byte* data)
static_cast<fil_encryption_t>
(data[10 + MY_AES_BLOCK_SIZE]));
memcpy(crypt_data->iv, data + 2, MY_AES_BLOCK_SIZE);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (space->crypt_data) {
fil_space_merge_crypt_data(space->crypt_data,
crypt_data);
@ -362,7 +362,7 @@ void fil_crypt_parse(fil_space_t* space, const byte* data)
} else {
space->crypt_data = crypt_data;
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
}
@ -997,12 +997,12 @@ fil_crypt_read_crypt_data(fil_space_t* space)
mtr.start();
if (buf_block_t* block = buf_page_get(page_id_t(space->id, 0),
zip_size, RW_S_LATCH, &mtr)) {
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (!space->crypt_data) {
space->crypt_data = fil_space_read_crypt_data(
zip_size, block->frame);
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
mtr.commit();
}
@ -1063,12 +1063,12 @@ func_exit:
crypt_data->rotate_state.starting = true;
crypt_data->rotate_state.active_threads = 1;
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
const bool stopping = space->is_stopping();
if (!stopping) {
space->crypt_data = crypt_data;
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (stopping) {
goto abort;
@ -1404,7 +1404,7 @@ the encryption parameters were changed
inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
bool recheck, bool encrypt)
{
ut_ad(mutex_own(&mutex));
mysql_mutex_assert_owner(&mutex);
sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it=
space && space->is_in_rotation_list ? space : rotation_list.begin();
@ -1456,7 +1456,7 @@ encryption parameters were changed
inline fil_space_t *fil_space_t::next(fil_space_t *space, bool recheck,
bool encrypt)
{
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (!srv_fil_crypt_rotate_key_age)
space= fil_system.keyrotate_next(space, recheck, encrypt);
@ -1483,7 +1483,7 @@ inline fil_space_t *fil_space_t::next(fil_space_t *space, bool recheck,
}
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
return space;
}
@ -2143,7 +2143,7 @@ fil_crypt_set_thread_cnt(
if innodb_encryption_rotate_key_age=0. */
static void fil_crypt_rotation_list_fill()
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system.space_list);
space != NULL;
@ -2193,11 +2193,11 @@ Adjust max key age
void fil_crypt_set_rotate_key_age(uint val)
{
mysql_mutex_lock(&fil_crypt_threads_mutex);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
srv_fil_crypt_rotate_key_age= val;
if (val == 0)
fil_crypt_rotation_list_fill();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
mysql_cond_broadcast(&fil_crypt_threads_cond);
mysql_mutex_unlock(&fil_crypt_threads_mutex);
}
@ -2220,13 +2220,13 @@ void fil_crypt_set_encrypt_tables(ulong val)
{
mysql_mutex_lock(&fil_crypt_threads_mutex);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
srv_encrypt_tables= val;
if (srv_fil_crypt_rotate_key_age == 0)
fil_crypt_rotation_list_fill();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
mysql_cond_broadcast(&fil_crypt_threads_cond);
mysql_mutex_unlock(&fil_crypt_threads_mutex);
@ -2234,9 +2234,7 @@ void fil_crypt_set_encrypt_tables(ulong val)
/*********************************************************************
Init threads for key rotation */
UNIV_INTERN
void
fil_crypt_threads_init()
void fil_crypt_threads_init()
{
if (!fil_crypt_threads_inited) {
mysql_cond_init(0, &fil_crypt_cond, nullptr);
@ -2290,7 +2288,7 @@ fil_space_crypt_close_tablespace(
mysql_mutex_unlock(&crypt_data->mutex);
/* release dict mutex so that scrub threads can release their
* table references */
dict_mutex_exit_for_mysql();
dict_sys.mutex_unlock();
/* wakeup throttle (all) sleepers */
mysql_mutex_lock(&fil_crypt_threads_mutex);
@ -2299,7 +2297,7 @@ fil_space_crypt_close_tablespace(
mysql_mutex_unlock(&fil_crypt_threads_mutex);
os_thread_sleep(20000);
dict_mutex_enter_for_mysql();
dict_sys.mutex_lock();
mysql_mutex_lock(&crypt_data->mutex);
time_t now = time(0);

View file

@ -46,7 +46,6 @@ Created 10/25/1995 Heikki Tuuri
#include "trx0purge.h"
#include "buf0lru.h"
#include "ibuf0ibuf.h"
#include "sync0sync.h"
#include "buf0flu.h"
#ifdef UNIV_LINUX
# include <sys/types.h>
@ -68,7 +67,7 @@ inline bool fil_is_user_tablespace_id(ulint space_id)
@return whether a file was closed */
bool fil_space_t::try_to_close(bool print_info)
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
for (fil_space_t *space= UT_LIST_GET_FIRST(fil_system.space_list); space;
space= UT_LIST_GET_NEXT(space_list, space))
{
@ -239,7 +238,7 @@ fil_space_get_by_id(
fil_space_t* space;
ut_ad(fil_system.is_initialised());
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
HASH_SEARCH(hash, &fil_system.spaces, id,
fil_space_t*, space,
@ -261,9 +260,9 @@ fil_space_t*
fil_space_get(
ulint id)
{
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
fil_space_t* space = fil_space_get_by_id(id);
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
return(space);
}
@ -343,7 +342,7 @@ fil_node_t* fil_space_t::add(const char* name, pfs_os_file_t handle,
node->atomic_write = atomic_write;
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
this->size += size;
UT_LIST_ADD_LAST(chain, node);
if (node->is_open()) {
@ -354,7 +353,7 @@ fil_node_t* fil_space_t::add(const char* name, pfs_os_file_t handle,
release();
}
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
return node;
}
@ -366,7 +365,7 @@ static bool fil_node_open_file_low(fil_node_t *node)
{
ut_ad(!node->is_open());
ut_ad(node->space->is_closing());
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
const auto flags= node->space->flags;
bool o_direct_possible= !FSP_FLAGS_HAS_PAGE_COMPRESSION(flags);
static_assert(((UNIV_ZIP_SIZE_MIN >> 1) << 3) == 4096, "compatibility");
@ -423,7 +422,7 @@ static bool fil_node_open_file_low(fil_node_t *node)
@return whether the file was successfully opened */
static bool fil_node_open_file(fil_node_t *node)
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
ut_ad(!node->is_open());
ut_ad(fil_is_user_tablespace_id(node->space->id) ||
srv_operation == SRV_OPERATION_BACKUP ||
@ -445,11 +444,11 @@ static bool fil_node_open_file(fil_node_t *node)
}
else
{
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
os_thread_sleep(20000);
/* Flush tablespaces so that we can close modified files. */
fil_flush_file_spaces();
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
}
}
@ -478,7 +477,7 @@ pfs_os_file_t fil_node_t::detach()
void fil_node_t::prepare_to_close_or_detach()
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
ut_ad(space->is_ready_to_close() || srv_operation == SRV_OPERATION_BACKUP ||
srv_operation == SRV_OPERATION_RESTORE_DELTA);
ut_a(is_open());
@ -493,7 +492,7 @@ void fil_node_t::prepare_to_close_or_detach()
/** Flush any writes cached by the file system. */
void fil_space_t::flush_low()
{
ut_ad(!mutex_own(&fil_system.mutex));
mysql_mutex_assert_not_owner(&fil_system.mutex);
uint32_t n= 1;
while (!n_pending.compare_exchange_strong(n, n | NEEDS_FSYNC,
@ -522,13 +521,13 @@ void fil_space_t::flush_low()
if (is_in_unflushed_spaces)
{
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (is_in_unflushed_spaces)
{
is_in_unflushed_spaces= false;
fil_system.unflushed_spaces.remove(*this);
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
clear_flush();
@ -549,7 +548,7 @@ fil_space_extend_must_retry(
uint32_t size,
bool* success)
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
ut_ad(UT_LIST_GET_LAST(space->chain) == node);
ut_ad(size >= FIL_IBD_FILE_INITIAL_SIZE);
ut_ad(node->space == space);
@ -567,7 +566,7 @@ fil_space_extend_must_retry(
for it to finish.
It'd have been better to use event driven mechanism but
the entire module is peppered with polling stuff. */
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
os_thread_sleep(100000);
return(true);
}
@ -577,7 +576,7 @@ fil_space_extend_must_retry(
/* At this point it is safe to release fil_system.mutex. No
other thread can rename, delete, close or extend the file because
we have set the node->being_extended flag. */
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
ut_ad(size >= space->size);
@ -609,7 +608,7 @@ fil_space_extend_must_retry(
last_page_no = uint32_t(fsize / page_size)
+ file_start_page_no;
}
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
ut_a(node->being_extended);
node->being_extended = false;
@ -629,10 +628,10 @@ fil_space_extend_must_retry(
srv_sys_space.set_last_file_size(pages_in_MiB);
do_flush:
space->reacquire();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
space->flush_low();
space->release();
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
break;
default:
ut_ad(space->purpose == FIL_TYPE_TABLESPACE
@ -656,8 +655,8 @@ ATTRIBUTE_COLD bool fil_space_t::prepare(bool have_mutex)
{
ut_ad(referenced());
if (!have_mutex)
mutex_enter(&fil_system.mutex);
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_lock(&fil_system.mutex);
mysql_mutex_assert_owner(&fil_system.mutex);
fil_node_t *node= UT_LIST_GET_LAST(chain);
ut_ad(!id || purpose == FIL_TYPE_TEMPORARY ||
node == UT_LIST_GET_FIRST(chain));
@ -670,9 +669,9 @@ ATTRIBUTE_COLD bool fil_space_t::prepare(bool have_mutex)
{
bool success;
while (fil_space_extend_must_retry(this, node, desired_size, &success))
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
/* Crash recovery requires the file extension to succeed. */
ut_a(success);
/* InnoDB data files cannot shrink. */
@ -702,7 +701,7 @@ clear:
n_pending.fetch_and(~CLOSING, std::memory_order_relaxed);
if (!have_mutex)
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
return is_open;
}
@ -715,14 +714,14 @@ bool fil_space_extend(fil_space_t *space, uint32_t size)
ut_ad(!srv_read_only_mode || space->purpose == FIL_TYPE_TEMPORARY);
bool success= false;
const bool acquired= space->acquire();
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (acquired || space->is_being_truncated)
{
while (fil_space_extend_must_retry(space, UT_LIST_GET_LAST(space->chain),
size, &success))
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (acquired)
space->release();
return success;
@ -731,7 +730,7 @@ bool fil_space_extend(fil_space_t *space, uint32_t size)
/** Prepare to free a file from fil_system. */
inline pfs_os_file_t fil_node_t::close_to_free(bool detach_handle)
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
ut_a(magic_n == FIL_NODE_MAGIC_N);
ut_a(!being_extended);
@ -740,10 +739,10 @@ inline pfs_os_file_t fil_node_t::close_to_free(bool detach_handle)
std::memory_order_acquire) &
fil_space_t::PENDING))
{
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
while (space->referenced())
os_thread_sleep(100);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
}
while (is_open())
@ -775,7 +774,7 @@ inline pfs_os_file_t fil_node_t::close_to_free(bool detach_handle)
std::vector<pfs_os_file_t> fil_system_t::detach(fil_space_t *space,
bool detach_handle)
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
HASH_DELETE(fil_space_t, hash, &spaces, space->id, space);
if (space->is_in_unflushed_spaces)
@ -871,14 +870,14 @@ fil_space_free(
{
ut_ad(id != TRX_SYS_SPACE);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
fil_space_t* space = fil_space_get_by_id(id);
if (space != NULL) {
fil_system.detach(space);
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (space != NULL) {
if (x_latched) {
@ -967,14 +966,14 @@ fil_space_t *fil_space_t::create(const char *name, ulint id, ulint flags,
space->atomic_write_supported = true;
}
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (const fil_space_t *old_space = fil_space_get_by_id(id)) {
ib::error() << "Trying to add tablespace '" << name
<< "' with id " << id
<< " to the tablespace memory cache, but tablespace '"
<< old_space->name << "' already exists in the cache!";
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
space->~fil_space_t();
ut_free(space->name);
ut_free(space);
@ -1019,7 +1018,7 @@ fil_space_t *fil_space_t::create(const char *name, ulint id, ulint flags,
space->is_in_rotation_list = true;
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (rotate) {
fil_crypt_threads_signal();
@ -1041,7 +1040,7 @@ fil_assign_new_space_id(
ulint id;
bool success;
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
id = *space_id;
@ -1073,7 +1072,7 @@ fil_assign_new_space_id(
*space_id = ULINT_UNDEFINED;
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
return(success);
}
@ -1083,7 +1082,7 @@ fil_assign_new_space_id(
bool fil_space_t::read_page0()
{
ut_ad(fil_system.is_initialised());
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
if (size)
return true;
@ -1114,7 +1113,7 @@ static fil_space_t *fil_space_get_space(ulint id)
void fil_space_set_recv_size_and_flags(ulint id, uint32_t size, uint32_t flags)
{
ut_ad(id < SRV_SPACE_ID_UPPER_BOUND);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (fil_space_t *space= fil_space_get_space(id))
{
if (size)
@ -1122,7 +1121,7 @@ void fil_space_set_recv_size_and_flags(ulint id, uint32_t size, uint32_t flags)
if (flags != FSP_FLAGS_FCRC32_MASK_MARKER)
space->flags= flags;
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
/** Open each file. Never invoked on .ibd files.
@ -1136,7 +1135,7 @@ bool fil_space_t::open(bool create_new_db)
bool success= true;
bool skip_read= create_new_db;
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
for (fil_node_t *node= UT_LIST_GET_FIRST(chain); node;
node= UT_LIST_GET_NEXT(chain, node))
@ -1169,7 +1168,7 @@ err_exit:
if (!create_new_db)
committed_size= size;
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
return success;
}
@ -1180,7 +1179,7 @@ void fil_space_t::close()
return;
}
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
ut_ad(this == fil_system.temp_space
|| srv_operation == SRV_OPERATION_BACKUP
|| srv_operation == SRV_OPERATION_RESTORE
@ -1194,7 +1193,7 @@ void fil_space_t::close()
}
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
void fil_system_t::create(ulint hash_size)
@ -1212,7 +1211,7 @@ void fil_system_t::create(ulint hash_size)
ut_ad(hash_size > 0);
mutex_create(LATCH_ID_FIL_SYSTEM, &mutex);
mysql_mutex_init(fil_system_mutex_key, &mutex, nullptr);
spaces.create(hash_size);
@ -1291,7 +1290,7 @@ void fil_system_t::close()
{
m_initialised= false;
spaces.free();
mutex_free(&mutex);
mysql_mutex_destroy(&mutex);
fil_space_crypt_cleanup();
}
@ -1318,7 +1317,7 @@ void fil_space_t::close_all()
|| UT_LIST_GET_LEN(fil_system.named_spaces) == 0);
fil_flush_file_spaces();
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
for (space = UT_LIST_GET_FIRST(fil_system.space_list); space; ) {
fil_node_t* node;
@ -1338,9 +1337,9 @@ next:
node->close();
goto next;
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
os_thread_sleep(100);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (!node->is_open()) {
goto next;
}
@ -1353,10 +1352,12 @@ next:
space = UT_LIST_GET_NEXT(space_list, space);
fil_system.detach(prev_space);
mysql_mutex_unlock(&fil_system.mutex);
fil_space_free_low(prev_space);
mysql_mutex_lock(&fil_system.mutex);
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
ut_ad(srv_fast_shutdown == 2
|| !srv_was_started
@ -1375,14 +1376,14 @@ fil_set_max_space_id_if_bigger(
ib::fatal() << "Max tablespace id is too high, " << max_id;
}
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (fil_system.max_assigned_id < max_id) {
fil_system.max_assigned_id = max_id;
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
/** Write the flushed LSN to the page header of the first page in the
@ -1433,10 +1434,10 @@ fil_write_flushed_lsn(
@retval nullptr if the tablespace is missing or inaccessible */
fil_space_t *fil_space_t::get(ulint id)
{
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
fil_space_t *space= fil_space_get_by_id(id);
const uint32_t n= space ? space->acquire_low() : 0;
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (n & STOPPING)
space= nullptr;
@ -1644,7 +1645,7 @@ fil_op_replay_rename(
@return 0 if no operations else count + 1. */
static ulint fil_check_pending_ops(const fil_space_t* space, ulint count)
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
if (!space) {
return 0;
@ -1677,7 +1678,7 @@ fil_check_pending_io(
fil_node_t** node, /*!< out: Node in space list */
ulint count) /*!< in: number of attempts so far */
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
/* The following code must change when InnoDB supports
multiple datafiles per tablespace. */
@ -1716,16 +1717,16 @@ fil_check_pending_operations(
ulint count = 0;
ut_a(!is_system_tablespace(id));
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
fil_space_t* sp = fil_space_get_by_id(id);
if (sp) {
sp->set_stopping(true);
if (sp->crypt_data) {
sp->reacquire();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
fil_space_crypt_close_tablespace(sp);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
sp->release();
}
}
@ -1735,7 +1736,7 @@ fil_check_pending_operations(
do {
count = fil_check_pending_ops(sp, count);
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (count) {
os_thread_sleep(20000); // Wait 0.02 seconds
@ -1743,7 +1744,7 @@ fil_check_pending_operations(
return nullptr;
}
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
sp = fil_space_get_by_id(id);
} while (count);
@ -1763,18 +1764,18 @@ fil_check_pending_operations(
*path = mem_strdup(node->name);
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (count == 0) {
break;
}
os_thread_sleep(20000); // Wait 0.02 seconds
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
sp = fil_space_get_by_id(id);
if (!sp) {
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
break;
}
}
@ -1902,7 +1903,7 @@ dberr_t fil_delete_tablespace(ulint id, bool if_exists,
RemoteDatafile::delete_link_file(space->name);
}
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
/* Double check the sanity of pending ops after reacquiring
the fil_system::mutex. */
@ -1915,7 +1916,7 @@ dberr_t fil_delete_tablespace(ulint id, bool if_exists,
if (detached_handles) {
*detached_handles = std::move(handles);
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
mysql_mutex_lock(&log_sys.mutex);
@ -1937,7 +1938,7 @@ dberr_t fil_delete_tablespace(ulint id, bool if_exists,
err = DB_IO_ERROR;
}
} else {
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
err = DB_TABLESPACE_NOT_FOUND;
}
@ -2107,7 +2108,7 @@ fil_rename_tablespace_check(
a possibly existing tablespace that is associated with the
new tablespace file. */
retry:
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system.space_list);
space; space = UT_LIST_GET_NEXT(space_list, space)) {
ulint id = space->id;
@ -2117,7 +2118,7 @@ retry:
UT_LIST_GET_FIRST(space->chain)->name)) {
ib::info() << "TRUNCATE rollback: " << id
<< "," << new_path;
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
dberr_t err = fil_delete_tablespace(id);
if (err != DB_SUCCESS) {
return err;
@ -2125,7 +2126,7 @@ retry:
goto retry;
}
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
fil_delete_file(new_path);
return(DB_SUCCESS);
@ -2172,7 +2173,7 @@ fil_rename_tablespace(
ut_ad(strchr(new_name, '/') != NULL);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
space = fil_space_get_by_id(id);
@ -2181,7 +2182,7 @@ fil_rename_tablespace(
<< " in the tablespace memory cache, though the file '"
<< old_path
<< "' in a rename operation should have that id.";
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
return(false);
}
@ -2191,7 +2192,7 @@ fil_rename_tablespace(
node = UT_LIST_GET_FIRST(space->chain);
space->reacquire();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
char* new_file_name = new_path_in == NULL
? fil_make_filepath(NULL, new_name, IBD, false)
@ -2210,7 +2211,7 @@ fil_rename_tablespace(
/* log_sys.mutex is above fil_system.mutex in the latching order */
mysql_mutex_assert_owner(&log_sys.mutex);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
space->release();
ut_ad(space->name == old_space_name);
ut_ad(node->name == old_file_name);
@ -2244,7 +2245,7 @@ skip_second_rename:
old_space_name = new_space_name;
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
ut_free(old_file_name);
ut_free(old_space_name);
@ -2493,7 +2494,7 @@ fil_ibd_open(
const char* path_in,
dberr_t* err)
{
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (fil_space_t* space = fil_space_get_by_id(id)) {
if (strcmp(space->name, tablename.m_name)) {
table_name_t space_name;
@ -2506,7 +2507,7 @@ fil_ibd_open(
if (err) *err = DB_TABLESPACE_EXISTS;
} else if (err) *err = DB_SUCCESS;
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (space && validate && !srv_read_only_mode) {
fsp_flags_try_adjust(space,
@ -2515,7 +2516,7 @@ fil_ibd_open(
return space;
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
Datafile df_default; /* default location */
RemoteDatafile df_remote; /* remote location */
@ -2730,7 +2731,7 @@ fil_space_read_name_and_filepath(
*name = NULL;
*filepath = NULL;
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
fil_space_t* space = fil_space_get_by_id(space_id);
@ -2743,7 +2744,7 @@ fil_space_read_name_and_filepath(
success = true;
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
return(success);
}
@ -2923,9 +2924,9 @@ fil_ibd_load(
{
/* If the a space is already in the file system cache with this
space ID, then there is nothing to do. */
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
space = fil_space_get_by_id(space_id);
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (space != NULL) {
/* Compare the filename we are trying to open with the
@ -3152,7 +3153,7 @@ fil_space_for_table_exists_in_mem(
{
const ulint expected_flags = dict_tf_to_fsp_flags(table_flags);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (fil_space_t* space = fil_space_get_by_id(id)) {
ulint tf = expected_flags & ~FSP_FLAGS_MEM_MASK;
ulint sf = space->flags & ~FSP_FLAGS_MEM_MASK;
@ -3177,7 +3178,7 @@ fil_space_for_table_exists_in_mem(
FSP_SPACE_FLAGS will not be written back here. */
space->flags = (space->flags & ~FSP_FLAGS_MEM_MASK)
| (expected_flags & FSP_FLAGS_MEM_MASK);
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (!srv_read_only_mode) {
fsp_flags_try_adjust(space, expected_flags
& ~FSP_FLAGS_MEM_MASK);
@ -3186,7 +3187,7 @@ fil_space_for_table_exists_in_mem(
}
func_exit:
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
return NULL;
}
@ -3207,19 +3208,19 @@ fil_report_invalid_page_access(const char *name,
/** Update the data structures on write completion */
inline void fil_node_t::complete_write()
{
ut_ad(!mutex_own(&fil_system.mutex));
mysql_mutex_assert_not_owner(&fil_system.mutex);
if (space->purpose != FIL_TYPE_TEMPORARY &&
srv_file_flush_method != SRV_O_DIRECT_NO_FSYNC &&
space->set_needs_flush())
{
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
if (!space->is_in_unflushed_spaces)
{
space->is_in_unflushed_spaces= true;
fil_system.unflushed_spaces.push_front(*space);
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
}
@ -3381,28 +3382,28 @@ void fil_flush_file_spaces()
{
if (srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)
{
ut_d(mutex_enter(&fil_system.mutex));
ut_d(mysql_mutex_lock(&fil_system.mutex));
ut_ad(fil_system.unflushed_spaces.empty());
ut_d(mutex_exit(&fil_system.mutex));
ut_d(mysql_mutex_unlock(&fil_system.mutex));
return;
}
rescan:
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
for (fil_space_t &space : fil_system.unflushed_spaces)
{
if (space.needs_flush_not_stopping())
{
space.reacquire();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
space.flush_low();
space.release();
goto rescan;
}
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
/** Functor to validate the file node list of a tablespace. */
@ -3428,7 +3429,7 @@ struct Check {
@return number of open file nodes */
static ulint validate(const fil_space_t* space)
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
Check check;
ut_list_validate(space->chain, check);
ut_a(space->size == check.size);
@ -3457,7 +3458,7 @@ bool fil_validate()
{
ulint n_open = 0;
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
for (fil_space_t *space = UT_LIST_GET_FIRST(fil_system.space_list);
space != NULL;
@ -3467,7 +3468,7 @@ bool fil_validate()
ut_a(fil_system.n_open == n_open);
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
return(true);
}
@ -3516,7 +3517,7 @@ void
fil_space_validate_for_mtr_commit(
const fil_space_t* space)
{
ut_ad(!mutex_own(&fil_system.mutex));
mysql_mutex_assert_not_owner(&fil_system.mutex);
ut_ad(space != NULL);
ut_ad(space->purpose == FIL_TYPE_TABLESPACE);
ut_ad(!is_predefined_tablespace(space->id));

View file

@ -48,7 +48,6 @@ Updated 14/02/2015
#include "row0mysql.h"
#include "buf0lru.h"
#include "ibuf0ibuf.h"
#include "sync0sync.h"
#include "zlib.h"
#ifdef __linux__
#include <linux/fs.h>

View file

@ -119,11 +119,7 @@ fts_config_get_value(
trx->op_info = "getting FTS config value";
error = fts_eval_sql(trx, graph);
mutex_enter(&dict_sys.mutex);
que_graph_free(graph);
mutex_exit(&dict_sys.mutex);
fts_que_graph_free(graph);
return(error);
}

View file

@ -37,7 +37,6 @@ Full Text Search interface
#include "dict0priv.h"
#include "dict0stats.h"
#include "btr0pcur.h"
#include "sync0sync.h"
static const ulint FTS_MAX_ID_LEN = 32;
@ -189,6 +188,14 @@ struct fts_tokenize_param_t {
ulint add_pos; /*!< Added position for tokens */
};
/** Free a query graph */
void fts_que_graph_free(que_t *graph)
{
dict_sys.mutex_lock();
que_graph_free(graph);
dict_sys.mutex_unlock();
}
/** Run SYNC on the table, i.e., write out data from the cache to the
FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] sync sync state
@ -454,7 +461,7 @@ fts_load_user_stopword(
fts_stopword_t* stopword_info) /*!< in: Stopword info */
{
if (!fts->dict_locked) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
/* Validate the user table existence in the right format */
@ -463,7 +470,7 @@ fts_load_user_stopword(
if (!stopword_info->charset) {
cleanup:
if (!fts->dict_locked) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
return ret;
@ -905,15 +912,15 @@ fts_que_graph_free_check_lock(
}
if (!has_dict) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
que_graph_free(graph);
if (!has_dict) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
}
@ -3514,7 +3521,9 @@ fts_add_doc_by_id(
"fts_instrument_sync",
fts_optimize_request_sync_table(table);
mysql_mutex_lock(&cache->lock);
mysql_cond_wait(&cache->sync->cond,
if (cache->sync->in_progress)
mysql_cond_wait(
&cache->sync->cond,
&cache->lock);
mysql_mutex_unlock(&cache->lock);
);
@ -4311,7 +4320,7 @@ end_sync:
ut_ad(sync->in_progress);
sync->interrupted = false;
sync->in_progress = false;
mysql_cond_signal(&sync->cond);
mysql_cond_broadcast(&sync->cond);
mysql_mutex_unlock(&cache->lock);
/* We need to check whether an optimize is required, for that
@ -5720,7 +5729,7 @@ fts parent table id and index id.
index id */
static void fil_get_fts_spaces(fts_space_set_t& fts_space_set)
{
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
for (fil_space_t *space= UT_LIST_GET_FIRST(fil_system.space_list);
space;
@ -5734,7 +5743,7 @@ static void fil_get_fts_spaces(fts_space_set_t& fts_space_set)
fts_space_set.insert(std::make_pair(table_id, index_id));
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
/** Check whether the parent table id and index id of fts auxilary
@ -6205,7 +6214,7 @@ fts_init_index(
fts_cache_t* cache = table->fts->cache;
bool need_init = false;
ut_ad(!mutex_own(&dict_sys.mutex));
dict_sys.assert_not_locked();
/* First check cache->get_docs is initialized */
if (!has_cache_lock) {
@ -6270,10 +6279,10 @@ func_exit:
}
if (need_init) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
/* Register the table with the optimize thread. */
fts_optimize_add_table(table);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
}

View file

@ -1005,10 +1005,7 @@ fts_table_fetch_doc_ids(
error = fts_eval_sql(trx, graph);
fts_sql_commit(trx);
mutex_enter(&dict_sys.mutex);
que_graph_free(graph);
mutex_exit(&dict_sys.mutex);
fts_que_graph_free(graph);
if (error == DB_SUCCESS) {
ib_vector_sort(doc_ids->doc_ids, fts_doc_id_cmp);
@ -2594,7 +2591,7 @@ fts_optimize_remove_table(
if (table->fts->in_queue)
{
ut_ad(!mutex_own(&dict_sys.mutex));
dict_sys.assert_not_locked();
fts_msg_t *msg= fts_optimize_create_msg(FTS_MSG_DEL_TABLE, nullptr);
mysql_cond_t cond;
mysql_cond_init(0, &cond, nullptr);
@ -2938,7 +2935,7 @@ fts_optimize_init(void)
/* Add fts tables to fts_slots which could be skipped
during dict_load_table_one() because fts_optimize_thread
wasn't even started. */
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
for (dict_table_t* table = UT_LIST_GET_FIRST(dict_sys.table_LRU);
table != NULL;
table = UT_LIST_GET_NEXT(table_LRU, table)) {
@ -2953,7 +2950,7 @@ fts_optimize_init(void)
fts_optimize_new_table(table);
table->fts->in_queue = true;
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
mysql_cond_init(0, &fts_opt_shutdown_cond, nullptr);
last_check_sync_time = time(NULL);
@ -2967,13 +2964,13 @@ fts_optimize_shutdown()
/* If there is an ongoing activity on dictionary, such as
srv_master_evict_from_table_cache(), wait for it */
dict_mutex_enter_for_mysql();
dict_sys.mutex_lock();
mysql_mutex_lock(&fts_optimize_wq->mutex);
/* Tells FTS optimizer system that we are exiting from
optimizer thread, message send their after will not be
processed */
fts_opt_start_shutdown = true;
dict_mutex_exit_for_mysql();
dict_sys.mutex_unlock();
/* We tell the OPTIMIZE thread to switch to state done, we
can't delete the work queue here because the add thread needs

View file

@ -93,7 +93,7 @@ char* fts_get_table_name_prefix(const fts_table_t* fts_table)
char table_id[FTS_AUX_MIN_TABLE_ID_LENGTH];
const size_t table_id_len = size_t(fts_get_table_id(fts_table,
table_id)) + 1;
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
/* Include the separator as well. */
const size_t dbname_len = fts_table->table->name.dblen() + 1;
ut_ad(dbname_len > 1);
@ -101,7 +101,7 @@ char* fts_get_table_name_prefix(const fts_table_t* fts_table)
char* prefix_name = static_cast<char*>(
ut_malloc_nokey(prefix_name_len));
memcpy(prefix_name, fts_table->table->name.m_name, dbname_len);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
memcpy(prefix_name + dbname_len, "FTS_", 4);
memcpy(prefix_name + dbname_len + 4, table_id, table_id_len);
return prefix_name;
@ -115,15 +115,15 @@ void fts_get_table_name(const fts_table_t* fts_table, char* table_name,
bool dict_locked)
{
if (!dict_locked) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
/* Include the separator as well. */
const size_t dbname_len = fts_table->table->name.dblen() + 1;
ut_ad(dbname_len > 1);
memcpy(table_name, fts_table->table->name.m_name, dbname_len);
if (!dict_locked) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
memcpy(table_name += dbname_len, "FTS_", 4);
table_name += 4;
@ -152,17 +152,15 @@ fts_parse_sql(
&& fts_table->table->fts->dict_locked);
if (!dict_locked) {
ut_ad(!mutex_own(&dict_sys.mutex));
/* The InnoDB SQL parser is not re-entrant. */
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
graph = pars_sql(info, str);
ut_a(graph);
if (!dict_locked) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
ut_free(str);
@ -182,7 +180,7 @@ fts_parse_sql_no_dict_lock(
char* str;
que_t* graph;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);

View file

@ -158,7 +158,7 @@ rtr_pcur_getnext_from_path(
ulint rw_latch = RW_X_LATCH;
ulint tree_idx;
mutex_enter(&rtr_info->rtr_path_mutex);
mysql_mutex_lock(&rtr_info->rtr_path_mutex);
next_rec = rtr_info->path->back();
rtr_info->path->pop_back();
level = next_rec.level;
@ -201,7 +201,7 @@ rtr_pcur_getnext_from_path(
== rtr_info->parent_path->back().child_no);
}
mutex_exit(&rtr_info->rtr_path_mutex);
mysql_mutex_unlock(&rtr_info->rtr_path_mutex);
skip_parent = false;
new_split = false;
@ -386,11 +386,11 @@ rtr_pcur_getnext_from_path(
trx_t* trx = thr_get_trx(
btr_cur->rtr_info->thr);
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
lock_init_prdt_from_mbr(
&prdt, &btr_cur->rtr_info->mbr,
mode, trx->lock.lock_heap);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
if (rw_latch == RW_NO_LATCH) {
block->lock.s_lock();
@ -479,13 +479,13 @@ rtr_pcur_move_to_next(
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
mutex_enter(&rtr_info->matches->rtr_match_mutex);
mysql_mutex_lock(&rtr_info->matches->rtr_match_mutex);
/* First retrieve the next record on the current page */
if (!rtr_info->matches->matched_recs->empty()) {
rtr_rec_t rec;
rec = rtr_info->matches->matched_recs->back();
rtr_info->matches->matched_recs->pop_back();
mutex_exit(&rtr_info->matches->rtr_match_mutex);
mysql_mutex_unlock(&rtr_info->matches->rtr_match_mutex);
cursor->btr_cur.page_cur.rec = rec.r_rec;
cursor->btr_cur.page_cur.block = &rtr_info->matches->block;
@ -494,7 +494,7 @@ rtr_pcur_move_to_next(
return(true);
}
mutex_exit(&rtr_info->matches->rtr_match_mutex);
mysql_mutex_unlock(&rtr_info->matches->rtr_match_mutex);
/* Fetch the next page */
return(rtr_pcur_getnext_from_path(tuple, mode, &cursor->btr_cur,
@ -920,20 +920,21 @@ rtr_create_rtr_info(
rtr_info->matches->bufp = page_align(rtr_info->matches->rec_buf
+ UNIV_PAGE_SIZE_MAX + 1);
mutex_create(LATCH_ID_RTR_MATCH_MUTEX,
&rtr_info->matches->rtr_match_mutex);
mysql_mutex_init(rtr_match_mutex_key,
&rtr_info->matches->rtr_match_mutex,
nullptr);
rtr_info->matches->block.lock.init();
}
rtr_info->path = UT_NEW_NOKEY(rtr_node_path_t());
rtr_info->parent_path = UT_NEW_NOKEY(rtr_node_path_t());
rtr_info->need_prdt_lock = need_prdt;
mutex_create(LATCH_ID_RTR_PATH_MUTEX,
&rtr_info->rtr_path_mutex);
mysql_mutex_init(rtr_path_mutex_key, &rtr_info->rtr_path_mutex,
nullptr);
mutex_enter(&index->rtr_track->rtr_active_mutex);
mysql_mutex_lock(&index->rtr_track->rtr_active_mutex);
index->rtr_track->rtr_active.push_front(rtr_info);
mutex_exit(&index->rtr_track->rtr_active_mutex);
mysql_mutex_unlock(&index->rtr_track->rtr_active_mutex);
return(rtr_info);
}
@ -972,8 +973,8 @@ rtr_init_rtr_info(
rtr_info->parent_path = NULL;
rtr_info->matches = NULL;
mutex_create(LATCH_ID_RTR_PATH_MUTEX,
&rtr_info->rtr_path_mutex);
mysql_mutex_init(rtr_path_mutex_key, &rtr_info->rtr_path_mutex,
nullptr);
memset(rtr_info->tree_blocks, 0x0,
sizeof(rtr_info->tree_blocks));
@ -1004,9 +1005,9 @@ rtr_init_rtr_info(
rtr_info->cursor = cursor;
rtr_info->index = index;
mutex_enter(&index->rtr_track->rtr_active_mutex);
mysql_mutex_lock(&index->rtr_track->rtr_active_mutex);
index->rtr_track->rtr_active.push_front(rtr_info);
mutex_exit(&index->rtr_track->rtr_active_mutex);
mysql_mutex_unlock(&index->rtr_track->rtr_active_mutex);
}
/**************************************************************//**
@ -1027,7 +1028,7 @@ rtr_clean_rtr_info(
index = rtr_info->index;
if (index) {
mutex_enter(&index->rtr_track->rtr_active_mutex);
mysql_mutex_lock(&index->rtr_track->rtr_active_mutex);
}
while (rtr_info->parent_path && !rtr_info->parent_path->empty()) {
@ -1058,7 +1059,7 @@ rtr_clean_rtr_info(
if (index) {
index->rtr_track->rtr_active.remove(rtr_info);
mutex_exit(&index->rtr_track->rtr_active_mutex);
mysql_mutex_unlock(&index->rtr_track->rtr_active_mutex);
}
if (free_all) {
@ -1069,7 +1070,8 @@ rtr_clean_rtr_info(
rtr_info->matches->block.lock.free();
mutex_destroy(&rtr_info->matches->rtr_match_mutex);
mysql_mutex_destroy(
&rtr_info->matches->rtr_match_mutex);
}
if (rtr_info->heap) {
@ -1077,7 +1079,7 @@ rtr_clean_rtr_info(
}
if (initialized) {
mutex_destroy(&rtr_info->rtr_path_mutex);
mysql_mutex_destroy(&rtr_info->rtr_path_mutex);
}
if (rtr_info->allocated) {
@ -1164,24 +1166,24 @@ rtr_check_discard_page(
{
const ulint pageno = block->page.id().page_no();
mutex_enter(&index->rtr_track->rtr_active_mutex);
mysql_mutex_lock(&index->rtr_track->rtr_active_mutex);
for (const auto& rtr_info : index->rtr_track->rtr_active) {
if (cursor && rtr_info == cursor->rtr_info) {
continue;
}
mutex_enter(&rtr_info->rtr_path_mutex);
mysql_mutex_lock(&rtr_info->rtr_path_mutex);
for (const node_visit_t& node : *rtr_info->path) {
if (node.page_no == pageno) {
rtr_rebuild_path(rtr_info, pageno);
break;
}
}
mutex_exit(&rtr_info->rtr_path_mutex);
mysql_mutex_unlock(&rtr_info->rtr_path_mutex);
if (rtr_info->matches) {
mutex_enter(&rtr_info->matches->rtr_match_mutex);
mysql_mutex_lock(&rtr_info->matches->rtr_match_mutex);
if ((&rtr_info->matches->block)->page.id().page_no()
== pageno) {
@ -1192,16 +1194,16 @@ rtr_check_discard_page(
rtr_info->matches->valid = false;
}
mutex_exit(&rtr_info->matches->rtr_match_mutex);
mysql_mutex_unlock(&rtr_info->matches->rtr_match_mutex);
}
}
mutex_exit(&index->rtr_track->rtr_active_mutex);
mysql_mutex_unlock(&index->rtr_track->rtr_active_mutex);
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
lock_prdt_page_free_from_discard(block, &lock_sys.prdt_hash);
lock_prdt_page_free_from_discard(block, &lock_sys.prdt_page_hash);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
}
/** Structure acts as functor to get the optimistic access of the page.

View file

@ -115,7 +115,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "trx0trx.h"
#include "fil0pagecompress.h"
#include "ut0mem.h"
#include "ut0mutex.h"
#include "row0ext.h"
#include <limits>
@ -146,7 +145,6 @@ void close_thread_tables(THD* thd);
#include "ha_innodb.h"
#include "i_s.h"
#include "sync0sync.h"
#include <string>
#include <sstream>
@ -208,7 +206,7 @@ static char* innodb_version_str = (char*) INNODB_VERSION_STR;
extern uint srv_fil_crypt_rotate_key_age;
extern uint srv_n_fil_crypt_iops;
#ifdef UNIV_DEBUG
#if defined SAFE_MUTEX && defined UNIV_DEBUG
my_bool innodb_evict_tables_on_commit_debug;
#endif
@ -509,6 +507,46 @@ static PSI_cond_info all_innodb_conds[] = {
};
# ifdef UNIV_PFS_MUTEX
mysql_pfs_key_t buf_pool_mutex_key;
mysql_pfs_key_t dict_foreign_err_mutex_key;
mysql_pfs_key_t dict_sys_mutex_key;
mysql_pfs_key_t fil_system_mutex_key;
mysql_pfs_key_t flush_list_mutex_key;
mysql_pfs_key_t fts_cache_mutex_key;
mysql_pfs_key_t fts_cache_init_mutex_key;
mysql_pfs_key_t fts_delete_mutex_key;
mysql_pfs_key_t fts_doc_id_mutex_key;
mysql_pfs_key_t fts_pll_tokenize_mutex_key;
mysql_pfs_key_t ibuf_bitmap_mutex_key;
mysql_pfs_key_t ibuf_mutex_key;
mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
mysql_pfs_key_t log_sys_mutex_key;
mysql_pfs_key_t log_cmdq_mutex_key;
mysql_pfs_key_t log_flush_order_mutex_key;
mysql_pfs_key_t recalc_pool_mutex_key;
mysql_pfs_key_t purge_sys_pq_mutex_key;
mysql_pfs_key_t recv_sys_mutex_key;
mysql_pfs_key_t redo_rseg_mutex_key;
mysql_pfs_key_t noredo_rseg_mutex_key;
mysql_pfs_key_t page_zip_stat_per_index_mutex_key;
mysql_pfs_key_t rtr_active_mutex_key;
mysql_pfs_key_t rtr_match_mutex_key;
mysql_pfs_key_t rtr_path_mutex_key;
mysql_pfs_key_t srv_innodb_monitor_mutex_key;
mysql_pfs_key_t srv_misc_tmpfile_mutex_key;
mysql_pfs_key_t srv_monitor_file_mutex_key;
mysql_pfs_key_t buf_dblwr_mutex_key;
mysql_pfs_key_t trx_pool_mutex_key;
mysql_pfs_key_t trx_pool_manager_mutex_key;
mysql_pfs_key_t lock_mutex_key;
mysql_pfs_key_t lock_wait_mutex_key;
mysql_pfs_key_t trx_sys_mutex_key;
mysql_pfs_key_t srv_threads_mutex_key;
mysql_pfs_key_t thread_mutex_key;
mysql_pfs_key_t row_drop_list_mutex_key;
mysql_pfs_key_t rw_trx_hash_element_mutex_key;
mysql_pfs_key_t read_view_mutex_key;
/* all_innodb_mutexes array contains mutexes that are
performance schema instrumented if "UNIV_PFS_MUTEX"
is defined */
@ -551,6 +589,13 @@ static PSI_mutex_info all_innodb_mutexes[] = {
# endif /* UNIV_PFS_MUTEX */
# ifdef UNIV_PFS_RWLOCK
mysql_pfs_key_t dict_operation_lock_key;
mysql_pfs_key_t index_tree_rw_lock_key;
mysql_pfs_key_t index_online_log_key;
mysql_pfs_key_t fil_space_latch_key;
mysql_pfs_key_t trx_i_s_cache_lock_key;
mysql_pfs_key_t trx_purge_latch_key;
/* all_innodb_rwlocks array contains rwlocks that are
performance schema instrumented if "UNIV_PFS_RWLOCK"
is defined */
@ -1517,8 +1562,6 @@ const char*
thd_innodb_tmpdir(
THD* thd)
{
ut_ad(!sync_check_iterate(sync_check()));
const char* tmp_dir = THDVAR(thd, tmpdir);
if (tmp_dir != NULL && *tmp_dir == '\0') {
@ -2697,9 +2740,7 @@ read view to it if there is no read view yet.
Why a deadlock of threads is not possible: the query cache calls this function
at the start of a SELECT processing. Then the calling thread cannot be
holding any InnoDB semaphores. The calling thread is holding the
query cache mutex, and this function will reserve the InnoDB trx_sys.mutex.
Thus, the 'rank' in sync0mutex.h of the MySQL query cache mutex is above
the InnoDB trx_sys.mutex.
query cache mutex, and this function will reserve the trx_sys.mutex.
@return TRUE if permitted, FALSE if not; note that the value FALSE
does not mean we should invalidate the query cache: invalidation is
called explicitly */
@ -2771,9 +2812,8 @@ innobase_invalidate_query_cache(
NOTE that in Windows this is
always in LOWER CASE! */
{
/* Note that the sync0mutex.h rank of the query cache mutex is just
above the InnoDB trx_sys_t->lock. The caller of this function must
not have latches of a lower rank. */
/* Note that the query cache mutex is just above the trx_sys.mutex.
The caller of this function must not have latches of a lower rank. */
#ifdef HAVE_QUERY_CACHE
char qcache_key_name[2 * (NAME_LEN + 1)];
@ -4419,7 +4459,7 @@ static void innobase_kill_query(handlerton*, THD *thd, enum thd_kill_levels)
Also, BF thread should own trx mutex for the victim. */
DBUG_VOID_RETURN;
#endif /* WITH_WSREP */
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
trx_sys.trx_list.freeze();
trx->mutex.wr_lock();
/* It is possible that innobase_close_connection() is concurrently
@ -4440,7 +4480,7 @@ static void innobase_kill_query(handlerton*, THD *thd, enum thd_kill_levels)
if (!cancel);
else if (lock_t *lock= trx->lock.wait_lock)
lock_cancel_waiting_and_release(lock);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
trx->mutex.wr_unlock();
}
@ -5075,12 +5115,12 @@ innobase_build_v_templ(
ut_ad(n_v_col > 0);
if (!locked) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
if (s_templ->vtempl) {
if (!locked) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
DBUG_VOID_RETURN;
}
@ -5186,7 +5226,7 @@ innobase_build_v_templ(
}
if (!locked) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
s_templ->db_name = table->s->db.str;
@ -5485,7 +5525,7 @@ ha_innobase::open(const char* name, int, uint)
key_used_on_scan = m_primary_key;
if (ib_table->n_v_cols) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
if (ib_table->vc_templ == NULL) {
ib_table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t());
innobase_build_v_templ(
@ -5493,7 +5533,7 @@ ha_innobase::open(const char* name, int, uint)
true);
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
if (!check_index_consistency(table, ib_table)) {
@ -9405,7 +9445,7 @@ wsrep_append_foreign_key(
foreign->referenced_table : foreign->foreign_table)) {
WSREP_DEBUG("pulling %s table into cache",
(referenced) ? "referenced" : "foreign");
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
if (referenced) {
foreign->referenced_table =
@ -9435,7 +9475,7 @@ wsrep_append_foreign_key(
TRUE, FALSE);
}
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
if ( !((referenced) ?
@ -12572,9 +12612,9 @@ create_table_info_t::create_table_update_dict()
DBUG_RETURN(-1);
}
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
fts_optimize_add_table(innobase_table);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
if (const Field* ai = m_form->found_next_number_field) {
@ -12841,12 +12881,12 @@ ha_innobase::discard_or_import_tablespace(
btr_cur_instant_init(). */
table_id_t id = m_prebuilt->table->id;
ut_ad(id);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_table_close(m_prebuilt->table, TRUE, FALSE);
dict_sys.remove(m_prebuilt->table);
m_prebuilt->table = dict_table_open_on_id(id, TRUE,
DICT_TABLE_OP_NORMAL);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
if (!m_prebuilt->table) {
err = DB_TABLE_NOT_FOUND;
} else {
@ -13931,7 +13971,7 @@ ha_innobase::info_low(
DEBUG_SYNC_C("ha_innobase_info_low");
ut_ad(!mutex_own(&dict_sys.mutex));
dict_sys.assert_not_locked();
/* If we are forcing recovery at a high level, we will suppress
statistics calculation on tables, because that may crash the
@ -13991,7 +14031,7 @@ ha_innobase::info_low(
ulint stat_clustered_index_size;
ulint stat_sum_of_other_index_sizes;
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
ut_a(ib_table->stat_initialized);
@ -14003,7 +14043,7 @@ ha_innobase::info_low(
stat_sum_of_other_index_sizes
= ib_table->stat_sum_of_other_index_sizes;
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
/*
The MySQL optimizer seems to assume in a left join that n_rows
@ -14120,8 +14160,8 @@ ha_innobase::info_low(
}
struct Locking {
Locking() { mutex_enter(&dict_sys.mutex); }
~Locking() { mutex_exit(&dict_sys.mutex); }
Locking() { dict_sys.mutex_lock(); }
~Locking() { dict_sys.mutex_unlock(); }
} locking;
ut_a(ib_table->stat_initialized);
@ -14838,7 +14878,7 @@ get_foreign_key_info(
dict_table_t* ref_table;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ref_table = dict_table_open_on_name(
foreign->referenced_table_name_lookup,
TRUE, FALSE, DICT_ERR_IGNORE_NONE);
@ -14893,7 +14933,7 @@ ha_innobase::get_foreign_key_list(
m_prebuilt->trx->op_info = "getting list of foreign keys";
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
for (dict_foreign_set::iterator it
= m_prebuilt->table->foreign_set.begin();
@ -14910,7 +14950,7 @@ ha_innobase::get_foreign_key_list(
}
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
m_prebuilt->trx->op_info = "";
@ -14931,7 +14971,7 @@ ha_innobase::get_parent_foreign_key_list(
m_prebuilt->trx->op_info = "getting list of referencing foreign keys";
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
for (dict_foreign_set::iterator it
= m_prebuilt->table->referenced_set.begin();
@ -14948,7 +14988,7 @@ ha_innobase::get_parent_foreign_key_list(
}
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
m_prebuilt->trx->op_info = "";
@ -15543,7 +15583,7 @@ innodb_show_status(
char* str;
size_t flen;
mutex_enter(&srv_monitor_file_mutex);
mysql_mutex_lock(&srv_monitor_file_mutex);
rewind(srv_monitor_file);
srv_printf_innodb_monitor(srv_monitor_file, FALSE,
@ -15570,7 +15610,7 @@ innodb_show_status(
if (!(str = (char*) my_malloc(PSI_INSTRUMENT_ME,
usable_len + 1, MYF(0)))) {
mutex_exit(&srv_monitor_file_mutex);
mysql_mutex_unlock(&srv_monitor_file_mutex);
DBUG_RETURN(1);
}
@ -15598,7 +15638,7 @@ innodb_show_status(
flen = fread(str, 1, MAX_STATUS_SIZE - 1, srv_monitor_file);
}
mutex_exit(&srv_monitor_file_mutex);
mysql_mutex_unlock(&srv_monitor_file_mutex);
ret_val= stat_print(
thd, innobase_hton_name,
@ -15610,215 +15650,6 @@ innodb_show_status(
DBUG_RETURN(ret_val);
}
/** Callback for collecting mutex statistics */
struct ShowStatus {
/** For tracking the mutex metrics */
struct Value {
/** Constructor
@param[in] name Name of the mutex
@param[in] spins Number of spins
@param[in] os_waits OS waits so far
@param[in] calls Number of calls to enter() */
Value(const char* name,
ulint spins,
uint64_t waits,
uint64_t calls)
:
m_name(name),
m_spins(spins),
m_waits(waits),
m_calls(calls)
{
/* No op */
}
/** Mutex name */
std::string m_name;
/** Spins so far */
ulint m_spins;
/** Waits so far */
uint64_t m_waits;
/** Number of calls so far */
uint64_t m_calls;
};
/** Order by m_waits, in descending order. */
struct OrderByWaits: public std::binary_function<Value, Value, bool>
{
/** @return true if rhs < lhs */
bool operator()(
const Value& lhs,
const Value& rhs) const
UNIV_NOTHROW
{
return(rhs.m_waits < lhs.m_waits);
}
};
typedef std::vector<Value, ut_allocator<Value> > Values;
/** Collect the individual latch counts */
struct GetCount {
typedef latch_meta_t::CounterType::Count Count;
/** Constructor
@param[in] name Latch name
@param[in,out] values Put the values here */
GetCount(
const char* name,
Values* values)
UNIV_NOTHROW
:
m_name(name),
m_values(values)
{
/* No op */
}
/** Collect the latch metrics. Ignore entries where the
spins and waits are zero.
@param[in] count The latch metrics */
void operator()(Count* count) const UNIV_NOTHROW
{
if (count->m_spins > 0 || count->m_waits > 0) {
m_values->push_back(Value(
m_name,
count->m_spins,
count->m_waits,
count->m_calls));
}
}
/** The latch name */
const char* m_name;
/** For collecting the active mutex stats. */
Values* m_values;
};
/** Constructor */
ShowStatus() { }
/** Callback for collecting the stats
@param[in] latch_meta Latch meta data
@return always returns true */
bool operator()(latch_meta_t& latch_meta)
UNIV_NOTHROW
{
latch_meta.get_counter()->iterate(
GetCount(latch_meta.get_name(), &m_values));
return(true);
}
/** Implements the SHOW MUTEX STATUS command, for mutexes.
The table structure is like so: Engine | Mutex Name | Status
We store the metrics in the "Status" column as:
spins=N,waits=N,calls=N"
The user has to parse the dataunfortunately
@param[in,out] thd the MySQL query thread of the caller
@param[in,out] stat_print function for printing statistics
@return true on success. */
bool to_string(
THD* thd,
stat_print_fn* stat_print)
UNIV_NOTHROW;
/** For collecting the active mutex stats. */
Values m_values;
};
/** Implements the SHOW MUTEX STATUS command, for mutexes.
The table structure is like so: Engine | Mutex Name | Status
We store the metrics in the "Status" column as:
spins=N,waits=N,calls=N"
The user has to parse the dataunfortunately
@param[in,out] thd the MySQL query thread of the caller
@param[in,out] stat_print function for printing statistics
@return true on success. */
bool
ShowStatus::to_string(
THD* thd,
stat_print_fn* stat_print)
UNIV_NOTHROW
{
uint hton_name_len = (uint) strlen(innobase_hton_name);
std::sort(m_values.begin(), m_values.end(), OrderByWaits());
Values::iterator end = m_values.end();
for (Values::iterator it = m_values.begin(); it != end; ++it) {
int name_len;
char name_buf[IO_SIZE];
name_len = snprintf(
name_buf, sizeof(name_buf), "%s", it->m_name.c_str());
int status_len;
char status_buf[IO_SIZE];
status_len = snprintf(
status_buf, sizeof(status_buf),
"spins=%lu,waits=%lu,calls=%llu",
static_cast<ulong>(it->m_spins),
static_cast<long>(it->m_waits),
(ulonglong) it->m_calls);
if (stat_print(thd, innobase_hton_name,
hton_name_len,
name_buf, static_cast<uint>(name_len),
status_buf, static_cast<uint>(status_len))) {
return(false);
}
}
return(true);
}
/** Implements the SHOW MUTEX STATUS command, for mutexes.
@param[in,out] hton the innodb handlerton
@param[in,out] thd the MySQL query thread of the caller
@param[in,out] stat_print function for printing statistics
@return 0 on success. */
static
int
innodb_show_mutex_status(
handlerton*
#ifdef DBUG_ASSERT_EXISTS
hton
#endif
,
THD* thd,
stat_print_fn* stat_print)
{
DBUG_ENTER("innodb_show_mutex_status");
ShowStatus collector;
DBUG_ASSERT(hton == innodb_hton_ptr);
mutex_monitor.iterate(collector);
if (!collector.to_string(thd, stat_print)) {
DBUG_RETURN(1);
}
DBUG_RETURN(0);
}
/************************************************************************//**
Return 0 on success and non-zero on failure. Note: the bool return type
seems to be abused here, should be an int. */
@ -15840,8 +15671,6 @@ innobase_show_status(
return(innodb_show_status(hton, thd, stat_print) != 0);
case HA_ENGINE_MUTEX:
return(innodb_show_mutex_status(hton, thd, stat_print) != 0);
case HA_ENGINE_LOGS:
/* Not handled */
break;
@ -17128,11 +16957,6 @@ innodb_monitor_set_option(
srv_mon_process_existing_counter(
monitor_id, MONITOR_TURN_ON);
}
if (MONITOR_IS_ON(MONITOR_LATCHES)) {
mutex_monitor.enable();
}
break;
case MONITOR_TURN_OFF:
@ -17143,25 +16967,14 @@ innodb_monitor_set_option(
MONITOR_OFF(monitor_id);
MONITOR_SET_OFF(monitor_id);
if (!MONITOR_IS_ON(MONITOR_LATCHES)) {
mutex_monitor.disable();
}
break;
case MONITOR_RESET_VALUE:
srv_mon_reset(monitor_id);
if (monitor_id == (MONITOR_LATCHES)) {
mutex_monitor.reset();
}
break;
case MONITOR_RESET_ALL_VALUE:
srv_mon_reset_all(monitor_id);
mutex_monitor.reset();
break;
default:
@ -18174,7 +17987,7 @@ int wsrep_innobase_kill_one_trx(THD *bf_thd, trx_t *victim_trx, bool signal)
{
ut_ad(bf_thd);
ut_ad(victim_trx);
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
DBUG_ENTER("wsrep_innobase_kill_one_trx");
@ -18276,11 +18089,11 @@ wsrep_abort_transaction(
wsrep_thd_transaction_state_str(victim_thd));
if (victim_trx) {
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
victim_trx->mutex.wr_lock();
int rcode= wsrep_innobase_kill_one_trx(bf_thd,
victim_trx, signal);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
victim_trx->mutex.wr_unlock();
DBUG_RETURN(rcode);
} else {
@ -19180,10 +18993,12 @@ static MYSQL_SYSVAR_BOOL(trx_purge_view_update_only_debug,
" but the each purges were not done yet.",
NULL, NULL, FALSE);
# ifdef SAFE_MUTEX
static MYSQL_SYSVAR_BOOL(evict_tables_on_commit_debug,
innodb_evict_tables_on_commit_debug, PLUGIN_VAR_OPCMDARG,
"On transaction commit, try to evict tables from the data dictionary cache.",
NULL, NULL, FALSE);
# endif /* SAFE_MUTEX */
static MYSQL_SYSVAR_UINT(data_file_size_debug,
srv_sys_space_size_debug,
@ -19211,11 +19026,6 @@ static MYSQL_SYSVAR_BOOL(page_cleaner_disabled_debug,
"Disable page cleaner",
NULL, NULL, FALSE);
static MYSQL_SYSVAR_BOOL(sync_debug, srv_sync_debug,
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
"Enable the sync debug checks",
NULL, NULL, FALSE);
static MYSQL_SYSVAR_BOOL(dict_stats_disabled_debug,
innodb_dict_stats_disabled_debug,
PLUGIN_VAR_OPCMDARG,
@ -19471,7 +19281,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(trx_rseg_n_slots_debug),
MYSQL_SYSVAR(limit_optimistic_insert_debug),
MYSQL_SYSVAR(trx_purge_view_update_only_debug),
# ifdef SAFE_MUTEX
MYSQL_SYSVAR(evict_tables_on_commit_debug),
# endif /* SAFE_MUTEX */
MYSQL_SYSVAR(data_file_size_debug),
MYSQL_SYSVAR(fil_make_page_dirty_debug),
MYSQL_SYSVAR(saved_page_number_debug),
@ -19479,7 +19291,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(page_cleaner_disabled_debug),
MYSQL_SYSVAR(dict_stats_disabled_debug),
MYSQL_SYSVAR(master_thread_disabled_debug),
MYSQL_SYSVAR(sync_debug),
#endif /* UNIV_DEBUG */
MYSQL_SYSVAR(force_primary_key),
MYSQL_SYSVAR(fatal_semaphore_wait_threshold),
@ -19698,9 +19509,9 @@ TABLE* innobase_init_vc_templ(dict_table_t* table)
DBUG_RETURN(NULL);
}
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
innobase_build_v_templ(mysql_table, table, table->vc_templ, NULL, true);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
DBUG_RETURN(mysql_table);
}
@ -20764,13 +20575,13 @@ ib_foreign_warn(trx_t* trx, /*!< in: trx */
vsprintf(buf, format, args);
va_end(args);
mutex_enter(&dict_foreign_err_mutex);
mysql_mutex_lock(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
fprintf(ef, " Error in foreign key constraint of table %s:\n",
table_name);
fputs(buf, ef);
mutex_exit(&dict_foreign_err_mutex);
mysql_mutex_unlock(&dict_foreign_err_mutex);
if (trx && trx->mysql_thd) {
THD* thd = (THD*)trx->mysql_thd;

View file

@ -486,7 +486,7 @@ inline bool dict_table_t::instant_column(const dict_table_t& table,
DBUG_ASSERT(table.n_cols + table.n_dropped() >= n_cols + n_dropped());
DBUG_ASSERT(!table.persistent_autoinc
|| persistent_autoinc == table.persistent_autoinc);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
{
const char* end = table.col_names;
@ -2592,7 +2592,7 @@ innobase_init_foreign(
ulint referenced_num_field) /*!< in: number of referenced
columns */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
if (constraint_name) {
ulint db_len;
@ -2996,7 +2996,7 @@ innobase_get_foreign_key_info(
add_fk[num_fk] = dict_mem_foreign_create();
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
referenced_table_name = dict_get_referenced_table(
table->name.m_name,
@ -3012,7 +3012,7 @@ innobase_get_foreign_key_info(
referenced_table = NULL;);
if (!referenced_table && trx->check_foreigns) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
my_error(ER_FK_CANNOT_OPEN_PARENT,
MYF(0), fk_key->ref_table.str);
@ -3045,7 +3045,7 @@ innobase_get_foreign_key_info(
/* Check whether there exist such
index in the the index create clause */
if (!referenced_index) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
my_error(ER_FK_NO_INDEX_PARENT, MYF(0),
fk_key->name.str
? fk_key->name.str : "",
@ -3060,7 +3060,7 @@ innobase_get_foreign_key_info(
} else {
/* Not possible to add a foreign key without a
referenced column */
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
my_error(ER_CANNOT_ADD_FOREIGN, MYF(0),
fk_key->ref_table.str);
goto err_exit;
@ -3072,7 +3072,7 @@ innobase_get_foreign_key_info(
num_col, referenced_table_name,
referenced_table, referenced_index,
referenced_column_names, referenced_num_col)) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
my_error(
ER_DUP_CONSTRAINT_NAME,
MYF(0),
@ -3080,7 +3080,7 @@ innobase_get_foreign_key_info(
goto err_exit;
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
correct_option = innobase_set_foreign_key_option(
add_fk[num_fk], fk_key);
@ -4024,7 +4024,7 @@ online_retry_drop_indexes_low(
dict_table_t* table, /*!< in/out: table */
trx_t* trx) /*!< in/out: transaction */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
ut_ad(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
@ -4061,9 +4061,9 @@ online_retry_drop_indexes(
trx->free();
}
ut_d(mutex_enter(&dict_sys.mutex));
ut_d(dict_sys.mutex_lock());
ut_d(dict_table_check_for_dup_indexes(table, CHECK_ALL_COMPLETE));
ut_d(mutex_exit(&dict_sys.mutex));
ut_d(dict_sys.mutex_unlock());
ut_ad(!table->drop_aborted);
}
@ -4138,7 +4138,7 @@ innobase_check_foreigns_low(
bool drop)
{
dict_foreign_t* foreign;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
/* Check if any FOREIGN KEY constraints are defined on this
column. */
@ -6753,7 +6753,7 @@ new_clustered_failed:
table. The new_table must be in the data
dictionary cache, because we are still holding
the dict_sys.mutex. */
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
temp_table = dict_table_open_on_name(
ctx->new_table->name.m_name, TRUE, FALSE,
DICT_ERR_IGNORE_NONE);
@ -7078,10 +7078,10 @@ error_handling:
case DB_SUCCESS:
ut_a(!dict_locked);
ut_d(mutex_enter(&dict_sys.mutex));
ut_d(dict_sys.mutex_lock());
ut_d(dict_table_check_for_dup_indexes(
user_table, CHECK_PARTIAL_OK));
ut_d(mutex_exit(&dict_sys.mutex));
ut_d(dict_sys.mutex_unlock());
DBUG_RETURN(false);
case DB_TABLESPACE_EXISTS:
my_error(ER_TABLESPACE_EXISTS, MYF(0), "(unknown)");
@ -7505,10 +7505,10 @@ ha_innobase::prepare_inplace_alter_table(
}
#endif /* UNIV_DEBUG */
ut_d(mutex_enter(&dict_sys.mutex));
ut_d(dict_sys.mutex_lock());
ut_d(dict_table_check_for_dup_indexes(
m_prebuilt->table, CHECK_ABORTED_OK));
ut_d(mutex_exit(&dict_sys.mutex));
ut_d(dict_sys.mutex_unlock());
if (!(ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)) {
/* Nothing to do */
@ -8312,7 +8312,6 @@ ha_innobase::inplace_alter_table(
bool rebuild_templ = false;
DBUG_ENTER("inplace_alter_table");
DBUG_ASSERT(!srv_read_only_mode);
ut_ad(!sync_check_iterate(sync_check()));
DEBUG_SYNC(m_user_thd, "innodb_inplace_alter_table_enter");
@ -8459,10 +8458,10 @@ oom:
KEY* dup_key;
all_done:
case DB_SUCCESS:
ut_d(mutex_enter(&dict_sys.mutex));
ut_d(dict_sys.mutex_lock());
ut_d(dict_table_check_for_dup_indexes(
m_prebuilt->table, CHECK_PARTIAL_OK));
ut_d(mutex_exit(&dict_sys.mutex));
ut_d(dict_sys.mutex_unlock());
/* prebuilt->table->n_ref_count can be anything here,
given that we hold at most a shared lock on the table. */
goto ok_exit;
@ -8631,7 +8630,7 @@ operation.
static
ulint innobase_get_uncommitted_fts_indexes(const dict_table_t* table)
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
dict_index_t* index = dict_table_get_first_index(table);
ulint n_uncommitted_fts = 0;
@ -9598,7 +9597,7 @@ innobase_update_foreign_cache(
DBUG_ENTER("innobase_update_foreign_cache");
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
user_table = ctx->old_table;
@ -10294,7 +10293,7 @@ commit_cache_norebuild(
if (fil_space_t* space = ctx->new_table->space) {
bool update = !(space->flags
& FSP_FLAGS_MASK_PAGE_COMPRESSION);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
space->flags &= ~FSP_FLAGS_MASK_MEM_COMPRESSION_LEVEL;
space->flags |= ctx->page_compression_level
<< FSP_FLAGS_MEM_COMPRESSION_LEVEL;
@ -10306,7 +10305,7 @@ commit_cache_norebuild(
|= innodb_compression_algorithm
<< FSP_FLAGS_FCRC32_POS_COMPRESSED_ALGO;
}
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
if (update) {
/* Maybe we should introduce an undo

View file

@ -1335,11 +1335,11 @@ i_s_cmp_per_index_fill_low(
/* Create a snapshot of the stats so we do not bump into lock
order violations with dict_sys.mutex below. */
mutex_enter(&page_zip_stat_per_index_mutex);
mysql_mutex_lock(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index_t snap (page_zip_stat_per_index);
mutex_exit(&page_zip_stat_per_index_mutex);
mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
page_zip_stat_per_index_t::iterator iter;
ulint i;
@ -1397,13 +1397,13 @@ i_s_cmp_per_index_fill_low(
contents of INFORMATION_SCHEMA.innodb_cmp_per_index being
inconsistent, but it is an acceptable compromise. */
if (i == 1000) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
i = 0;
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
if (reset) {
page_zip_reset_stat_per_index();
@ -2973,9 +2973,7 @@ i_s_fts_index_table_fill_selected(
}
}
mutex_enter(&dict_sys.mutex);
que_graph_free(graph);
mutex_exit(&dict_sys.mutex);
fts_que_graph_free(graph);
trx->free();
@ -3996,7 +3994,7 @@ i_s_innodb_buffer_page_fill(
if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
bool ret = false;
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
const dict_index_t* index =
dict_index_get_if_in_cache_low(
@ -4021,7 +4019,7 @@ i_s_innodb_buffer_page_fill(
system_charset_info);
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
OK(ret);
@ -4500,7 +4498,7 @@ i_s_innodb_buf_page_lru_fill(
if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
bool ret = false;
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
const dict_index_t* index =
dict_index_get_if_in_cache_low(
@ -4525,7 +4523,7 @@ i_s_innodb_buf_page_lru_fill(
system_charset_info);
}
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
OK(ret);
@ -4846,7 +4844,7 @@ i_s_sys_tables_fill_table(
}
heap = mem_heap_create(1000);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
@ -4860,7 +4858,7 @@ i_s_sys_tables_fill_table(
err_msg = dict_process_sys_tables_rec_and_mtr_commit(
heap, rec, &table_rec, false, &mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
if (!err_msg) {
i_s_dict_fill_sys_tables(thd, table_rec,
@ -4878,13 +4876,13 @@ i_s_sys_tables_fill_table(
mem_heap_empty(heap);
/* Get the next record */
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
}
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
mem_heap_free(heap);
DBUG_RETURN(0);
@ -5025,8 +5023,8 @@ i_s_dict_fill_sys_tablestats(
{
struct Locking
{
Locking() { mutex_enter(&dict_sys.mutex); }
~Locking() { mutex_exit(&dict_sys.mutex); }
Locking() { dict_sys.mutex_lock(); }
~Locking() { dict_sys.mutex_unlock(); }
} locking;
OK(fields[SYS_TABLESTATS_INIT]->store(table->stat_initialized,
@ -5093,7 +5091,7 @@ i_s_sys_tables_fill_table_stats(
heap = mem_heap_create(1000);
dict_sys.freeze();
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
@ -5108,7 +5106,7 @@ i_s_sys_tables_fill_table_stats(
heap, rec, &table_rec, true, &mtr);
ulint ref_count = table_rec ? table_rec->get_ref_count() : 0;
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
DBUG_EXECUTE_IF("test_sys_tablestats", {
if (strcmp("test/t1", table_rec->name.m_name) == 0 ) {
@ -5131,14 +5129,14 @@ i_s_sys_tables_fill_table_stats(
/* Get the next record */
dict_sys.freeze();
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
}
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
dict_sys.unfreeze();
mem_heap_free(heap);
@ -5333,7 +5331,7 @@ i_s_sys_indexes_fill_table(
}
heap = mem_heap_create(1000);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
/* Start scan the SYS_INDEXES table */
@ -5355,7 +5353,7 @@ i_s_sys_indexes_fill_table(
space_id = space_id == 4 ? mach_read_from_4(field)
: ULINT_UNDEFINED;
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
if (!err_msg) {
if (int err = i_s_dict_fill_sys_indexes(
@ -5373,13 +5371,13 @@ i_s_sys_indexes_fill_table(
mem_heap_empty(heap);
/* Get the next record */
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
}
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
mem_heap_free(heap);
DBUG_RETURN(0);
@ -5552,7 +5550,7 @@ i_s_sys_columns_fill_table(
}
heap = mem_heap_create(1000);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_startscan_system(&pcur, &mtr, SYS_COLUMNS);
@ -5570,7 +5568,7 @@ i_s_sys_columns_fill_table(
&nth_v_col);
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
if (!err_msg) {
i_s_dict_fill_sys_columns(thd, table_id, col_name,
@ -5585,13 +5583,13 @@ i_s_sys_columns_fill_table(
mem_heap_empty(heap);
/* Get the next record */
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
}
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
mem_heap_free(heap);
DBUG_RETURN(0);
@ -5745,7 +5743,7 @@ i_s_sys_virtual_fill_table(
DBUG_RETURN(0);
}
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_startscan_system(&pcur, &mtr, SYS_VIRTUAL);
@ -5761,7 +5759,7 @@ i_s_sys_virtual_fill_table(
&base_pos);
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
if (!err_msg) {
i_s_dict_fill_sys_virtual(thd, table_id, pos, base_pos,
@ -5773,13 +5771,13 @@ i_s_sys_virtual_fill_table(
}
/* Get the next record */
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
}
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
DBUG_RETURN(0);
}
@ -5931,7 +5929,7 @@ i_s_sys_fields_fill_table(
}
heap = mem_heap_create(1000);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
/* will save last index id so that we know whether we move to
@ -5952,7 +5950,7 @@ i_s_sys_fields_fill_table(
&pos, &index_id, last_id);
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
if (!err_msg) {
i_s_dict_fill_sys_fields(thd, index_id, &field_rec,
@ -5967,13 +5965,13 @@ i_s_sys_fields_fill_table(
mem_heap_empty(heap);
/* Get the next record */
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
}
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
mem_heap_free(heap);
DBUG_RETURN(0);
@ -6135,7 +6133,7 @@ i_s_sys_foreign_fill_table(
}
heap = mem_heap_create(1000);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN);
@ -6149,7 +6147,7 @@ i_s_sys_foreign_fill_table(
err_msg = dict_process_sys_foreign_rec(heap, rec, &foreign_rec);
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
if (!err_msg) {
i_s_dict_fill_sys_foreign(thd, &foreign_rec,
@ -6164,12 +6162,12 @@ i_s_sys_foreign_fill_table(
/* Get the next record */
mtr_start(&mtr);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
rec = dict_getnext_system(&pcur, &mtr);
}
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
mem_heap_free(heap);
DBUG_RETURN(0);
@ -6327,7 +6325,7 @@ i_s_sys_foreign_cols_fill_table(
}
heap = mem_heap_create(1000);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN_COLS);
@ -6344,7 +6342,7 @@ i_s_sys_foreign_cols_fill_table(
heap, rec, &name, &for_col_name, &ref_col_name, &pos);
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
if (!err_msg) {
i_s_dict_fill_sys_foreign_cols(
@ -6359,13 +6357,13 @@ i_s_sys_foreign_cols_fill_table(
mem_heap_empty(heap);
/* Get the next record */
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
}
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
mem_heap_free(heap);
DBUG_RETURN(0);
@ -6552,7 +6550,7 @@ static int i_s_sys_tablespaces_fill_table(THD *thd, TABLE_LIST *tables, Item*)
int err= 0;
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
fil_system.freeze_space_list++;
for (fil_space_t *space= UT_LIST_GET_FIRST(fil_system.space_list);
@ -6562,9 +6560,9 @@ static int i_s_sys_tablespaces_fill_table(THD *thd, TABLE_LIST *tables, Item*)
space->chain.start)
{
space->reacquire();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
err= i_s_sys_tablespaces_fill(thd, *space, tables->table);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
space->release();
if (err)
break;
@ -6572,7 +6570,7 @@ static int i_s_sys_tablespaces_fill_table(THD *thd, TABLE_LIST *tables, Item*)
}
fil_system.freeze_space_list--;
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
DBUG_RETURN(err);
}
@ -6772,7 +6770,7 @@ i_s_tablespaces_encryption_fill_table(
}
int err = 0;
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
fil_system.freeze_space_list++;
for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system.space_list);
@ -6780,10 +6778,10 @@ i_s_tablespaces_encryption_fill_table(
if (space->purpose == FIL_TYPE_TABLESPACE
&& !space->is_stopping()) {
space->reacquire();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
err = i_s_dict_fill_tablespaces_encryption(
thd, space, tables->table);
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
space->release();
if (err) {
break;
@ -6792,7 +6790,7 @@ i_s_tablespaces_encryption_fill_table(
}
fil_system.freeze_space_list--;
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
DBUG_RETURN(err);
}
/*******************************************************************//**

View file

@ -25,7 +25,6 @@ Created 7/19/1997 Heikki Tuuri
*******************************************************/
#include "ibuf0ibuf.h"
#include "sync0sync.h"
#include "btr0sea.h"
/** Number of bits describing a single page */
@ -234,14 +233,15 @@ type, counter, and some flags. */
format or later */
/** The mutex used to block pessimistic inserts to ibuf trees */
static ib_mutex_t ibuf_pessimistic_insert_mutex;
/** The mutex protecting the insert buffer structs */
static ib_mutex_t ibuf_mutex;
/** The mutex protecting the insert buffer bitmaps */
static ib_mutex_t ibuf_bitmap_mutex;
#ifndef SAFE_MUTEX
static
#endif /* SAFE_MUTEX */
/** The mutex protecting the insert buffer */
mysql_mutex_t ibuf_mutex,
/** The mutex covering pessimistic inserts into the change buffer */
ibuf_pessimistic_insert_mutex,
/** mutex covering all change buffer bitmap pages */
ibuf_bitmap_mutex;
/** The area in pages from which contract looks for page numbers for merge */
const ulint IBUF_MERGE_AREA = 8;
@ -332,7 +332,7 @@ static buf_block_t *ibuf_tree_root_get(mtr_t *mtr)
buf_block_t* block;
ut_ad(ibuf_inside(mtr));
ut_ad(mutex_own(&ibuf_mutex));
mysql_mutex_assert_owner(&ibuf_mutex);
mtr_sx_lock_index(ibuf.index, mtr);
@ -358,11 +358,9 @@ ibuf_close(void)
return;
}
mutex_free(&ibuf_pessimistic_insert_mutex);
mutex_free(&ibuf_mutex);
mutex_free(&ibuf_bitmap_mutex);
mysql_mutex_destroy(&ibuf_pessimistic_insert_mutex);
mysql_mutex_destroy(&ibuf_mutex);
mysql_mutex_destroy(&ibuf_bitmap_mutex);
dict_table_t* ibuf_table = ibuf.index->table;
ibuf.index->lock.free();
@ -380,7 +378,7 @@ ibuf_size_update(
/*=============*/
const page_t* root) /*!< in: ibuf tree root */
{
ut_ad(mutex_own(&ibuf_mutex));
mysql_mutex_assert_owner(&ibuf_mutex);
ibuf.free_list_len = flst_get_len(root + PAGE_HEADER
+ PAGE_BTR_IBUF_FREE_LIST);
@ -425,14 +423,12 @@ ibuf_init_at_db_start(void)
ibuf.max_size = ((buf_pool_get_curr_size() >> srv_page_size_shift)
* CHANGE_BUFFER_DEFAULT_SIZE) / 100;
mutex_create(LATCH_ID_IBUF, &ibuf_mutex);
mysql_mutex_init(ibuf_mutex_key, &ibuf_mutex, nullptr);
mysql_mutex_init(ibuf_bitmap_mutex_key, &ibuf_bitmap_mutex, nullptr);
mysql_mutex_init(ibuf_pessimistic_insert_mutex_key,
&ibuf_pessimistic_insert_mutex, nullptr);
mutex_create(LATCH_ID_IBUF_BITMAP, &ibuf_bitmap_mutex);
mutex_create(LATCH_ID_IBUF_PESSIMISTIC_INSERT,
&ibuf_pessimistic_insert_mutex);
mutex_enter(&ibuf_mutex);
mysql_mutex_lock(&ibuf_mutex);
fseg_n_reserved_pages(*header_page,
IBUF_HEADER + IBUF_TREE_SEG_HEADER
@ -453,7 +449,7 @@ ibuf_init_at_db_start(void)
}
ibuf_size_update(root);
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
ibuf.empty = page_is_empty(root);
mtr.commit();
@ -503,9 +499,9 @@ ibuf_max_size_update(
{
ulint new_size = ((buf_pool_get_curr_size() >> srv_page_size_shift)
* new_val) / 100;
mutex_enter(&ibuf_mutex);
mysql_mutex_lock(&ibuf_mutex);
ibuf.max_size = new_size;
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
}
# ifdef UNIV_DEBUG
@ -876,7 +872,7 @@ ibuf_update_free_bits_for_two_pages_low(
the bitmap mutex to prevent a deadlock with a similar operation
performed by another OS thread. */
mutex_enter(&ibuf_bitmap_mutex);
mysql_mutex_lock(&ibuf_bitmap_mutex);
state = ibuf_index_page_calc_free(block1);
@ -886,7 +882,7 @@ ibuf_update_free_bits_for_two_pages_low(
ibuf_set_free_bits_low(block2, state, mtr);
mutex_exit(&ibuf_bitmap_mutex);
mysql_mutex_unlock(&ibuf_bitmap_mutex);
}
/** Returns TRUE if the page is one of the fixed address ibuf pages.
@ -1753,7 +1749,7 @@ dare to start a pessimistic insert to the insert buffer.
@return whether enough free pages in list */
static inline bool ibuf_data_enough_free_for_insert()
{
ut_ad(mutex_own(&ibuf_mutex));
mysql_mutex_assert_owner(&ibuf_mutex);
/* We want a big margin of free pages, because a B-tree can sometimes
grow in size also if records are deleted from it, as the node pointers
@ -1773,7 +1769,7 @@ ibool
ibuf_data_too_much_free(void)
/*=========================*/
{
ut_ad(mutex_own(&ibuf_mutex));
mysql_mutex_assert_owner(&ibuf_mutex);
return(ibuf.free_list_len >= 3 + (ibuf.size / 2) + 3 * ibuf.height);
}
@ -1814,7 +1810,7 @@ static bool ibuf_add_free_page()
ut_ad(block->lock.not_recursive());
ibuf_enter(&mtr);
mutex_enter(&ibuf_mutex);
mysql_mutex_lock(&ibuf_mutex);
mtr.write<2>(*block, block->frame + FIL_PAGE_TYPE,
FIL_PAGE_IBUF_FREE_LIST);
@ -1834,7 +1830,7 @@ static bool ibuf_add_free_page()
const page_id_t page_id(block->page.id());
buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(page_id, 0, &mtr);
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
ibuf_bitmap_page_set_bits<IBUF_BITMAP_IBUF>(bitmap_page, page_id,
srv_page_size, true,
@ -1867,13 +1863,13 @@ ibuf_remove_free_page(void)
/* Prevent pessimistic inserts to insert buffer trees for a while */
ibuf_enter(&mtr);
mutex_enter(&ibuf_pessimistic_insert_mutex);
mutex_enter(&ibuf_mutex);
mysql_mutex_lock(&ibuf_pessimistic_insert_mutex);
mysql_mutex_lock(&ibuf_mutex);
if (!ibuf_data_too_much_free()) {
mutex_exit(&ibuf_mutex);
mutex_exit(&ibuf_pessimistic_insert_mutex);
mysql_mutex_unlock(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_pessimistic_insert_mutex);
ibuf_mtr_commit(&mtr);
@ -1884,7 +1880,7 @@ ibuf_remove_free_page(void)
buf_block_t* root = ibuf_tree_root_get(&mtr2);
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
uint32_t page_no = flst_get_last(PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST
+ root->frame).page;
@ -1910,7 +1906,7 @@ ibuf_remove_free_page(void)
ibuf_enter(&mtr);
mutex_enter(&ibuf_mutex);
mysql_mutex_lock(&ibuf_mutex);
root = ibuf_tree_root_get(&mtr);
@ -1924,7 +1920,7 @@ ibuf_remove_free_page(void)
flst_remove(root, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
block, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
mutex_exit(&ibuf_pessimistic_insert_mutex);
mysql_mutex_unlock(&ibuf_pessimistic_insert_mutex);
ibuf.seg_size--;
ibuf.free_list_len--;
@ -1934,7 +1930,7 @@ ibuf_remove_free_page(void)
buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(page_id, 0, &mtr);
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
ibuf_bitmap_page_set_bits<IBUF_BITMAP_IBUF>(
bitmap_page, page_id, srv_page_size, false, &mtr);
@ -1959,9 +1955,9 @@ ibuf_free_excess_pages(void)
ibool too_much_free;
mutex_enter(&ibuf_mutex);
mysql_mutex_lock(&ibuf_mutex);
too_much_free = ibuf_data_too_much_free();
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
if (!too_much_free) {
return;
@ -3199,16 +3195,16 @@ ibuf_insert_low(
if (BTR_LATCH_MODE_WITHOUT_INTENTION(mode) == BTR_MODIFY_TREE) {
for (;;) {
mutex_enter(&ibuf_pessimistic_insert_mutex);
mutex_enter(&ibuf_mutex);
mysql_mutex_lock(&ibuf_pessimistic_insert_mutex);
mysql_mutex_lock(&ibuf_mutex);
if (UNIV_LIKELY(ibuf_data_enough_free_for_insert())) {
break;
}
mutex_exit(&ibuf_mutex);
mutex_exit(&ibuf_pessimistic_insert_mutex);
mysql_mutex_unlock(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_pessimistic_insert_mutex);
if (!ibuf_add_free_page()) {
@ -3256,8 +3252,8 @@ ibuf_insert_low(
fail_exit:
if (BTR_LATCH_MODE_WITHOUT_INTENTION(mode) == BTR_MODIFY_TREE) {
mutex_exit(&ibuf_mutex);
mutex_exit(&ibuf_pessimistic_insert_mutex);
mysql_mutex_unlock(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_pessimistic_insert_mutex);
}
err = DB_STRONG_FAIL;
@ -3284,9 +3280,9 @@ commit_exit:
ibuf_mtr_commit(&bitmap_mtr);
goto fail_exit;
} else {
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
const auto lock_exists = lock_sys.get_first(page_id);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
if (lock_exists) {
goto commit_exit;
}
@ -3390,9 +3386,9 @@ commit_exit:
&dummy_big_rec, 0, thr, &mtr);
}
mutex_exit(&ibuf_pessimistic_insert_mutex);
mysql_mutex_unlock(&ibuf_pessimistic_insert_mutex);
ibuf_size_update(root);
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
ibuf.empty = page_is_empty(root);
block = btr_cur_get_block(cursor);
@ -4054,13 +4050,13 @@ bool ibuf_delete_rec(const page_id_t page_id, btr_pcur_t* pcur,
ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
ibuf_mtr_start(mtr);
mutex_enter(&ibuf_mutex);
mysql_mutex_lock(&ibuf_mutex);
if (!ibuf_restore_pos(page_id, search_tuple,
BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE,
pcur, mtr)) {
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
ut_ad(mtr->has_committed());
goto func_exit;
}
@ -4072,7 +4068,7 @@ bool ibuf_delete_rec(const page_id_t page_id, btr_pcur_t* pcur,
ut_a(err == DB_SUCCESS);
ibuf_size_update(root);
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
ibuf.empty = page_is_empty(root);
ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
@ -4494,11 +4490,11 @@ ibuf_is_empty(void)
ibuf_mtr_start(&mtr);
ut_d(mutex_enter(&ibuf_mutex));
ut_d(mysql_mutex_lock(&ibuf_mutex));
const buf_block_t* root = ibuf_tree_root_get(&mtr);
bool is_empty = page_is_empty(root->frame);
ut_a(is_empty == ibuf.empty);
ut_d(mutex_exit(&ibuf_mutex));
ut_d(mysql_mutex_unlock(&ibuf_mutex));
ibuf_mtr_commit(&mtr);
return(is_empty);
@ -4511,7 +4507,7 @@ ibuf_print(
/*=======*/
FILE* file) /*!< in: file where to print */
{
mutex_enter(&ibuf_mutex);
mysql_mutex_lock(&ibuf_mutex);
fprintf(file,
"Ibuf: size " ULINTPF ", free list len " ULINTPF ","
@ -4527,7 +4523,7 @@ ibuf_print(
fputs("discarded operations:\n ", file);
ibuf_print_ops(ibuf.n_discarded_ops, file);
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
}
/** Check the insert buffer bitmaps on IMPORT TABLESPACE.
@ -4550,7 +4546,7 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
mtr_t mtr;
mutex_enter(&ibuf_mutex);
mysql_mutex_lock(&ibuf_mutex);
/* The two bitmap pages (allocation bitmap and ibuf bitmap) repeat
every page_size pages. For example if page_size is 16 KiB, then the
@ -4560,7 +4556,7 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
for (uint32_t page_no = 0; page_no < size; page_no += physical_size) {
if (trx_is_interrupted(trx)) {
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
return(DB_INTERRUPTED);
}
@ -4573,7 +4569,7 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(
page_id_t(space->id, page_no), zip_size, &mtr);
if (!bitmap_page) {
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
mtr.commit();
return DB_CORRUPTION;
}
@ -4610,7 +4606,7 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
bitmap_page->frame, cur_page_id, zip_size,
IBUF_BITMAP_IBUF, &mtr)) {
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
ibuf_exit(&mtr);
mtr_commit(&mtr);
@ -4648,7 +4644,7 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
mtr_commit(&mtr);
}
mutex_exit(&ibuf_mutex);
mysql_mutex_unlock(&ibuf_mutex);
return(DB_SUCCESS);
}

View file

@ -24,9 +24,7 @@ The database buffer pool global types for the directory
Created 11/17/1995 Heikki Tuuri
*******************************************************/
#ifndef buf0types_h
#define buf0types_h
#pragma once
#include "univ.i"
/** Buffer page (uncompressed or compressed) */
@ -228,5 +226,3 @@ public:
};
#endif /* !UNIV_INNOCHECKSUM */
#endif /* buf0types.h */

View file

@ -1312,9 +1312,6 @@ dict_index_calc_min_rec_len(
const dict_index_t* index) /*!< in: index */
MY_ATTRIBUTE((nonnull, warn_unused_result));
#define dict_mutex_enter_for_mysql() mutex_enter(&dict_sys.mutex)
#define dict_mutex_exit_for_mysql() mutex_exit(&dict_sys.mutex)
/********************************************************************//**
Checks if the database name in two table names is the same.
@return TRUE if same db name */
@ -1378,13 +1375,14 @@ constraint */
/* Buffers for storing detailed information about the latest foreign key
and unique key errors */
extern FILE* dict_foreign_err_file;
extern ib_mutex_t dict_foreign_err_mutex; /* mutex protecting the
foreign key error messages */
extern mysql_mutex_t dict_foreign_err_mutex;
/** InnoDB data dictionary cache */
class dict_sys_t
{
private:
/** The my_hrtime_coarse().val of the oldest mutex_lock_wait() start, or 0 */
std::atomic<ulonglong> mutex_wait_start;
/** @brief the data dictionary rw-latch protecting dict_sys
Table create, drop, etc. reserve this in X-mode (along with
@ -1399,14 +1397,11 @@ private:
/** whether latch is being held in exclusive mode (by any thread) */
bool latch_ex;
#endif
/** Mutex protecting dict_sys. Whenever latch is acquired
exclusively, also the mutex will be acquired.
FIXME: merge the mutex and the latch, once MDEV-23484 has been fixed */
mysql_mutex_t mutex;
public:
DictSysMutex mutex; /*!< mutex protecting the data
dictionary; protects also the
disk-based dictionary system tables;
this mutex serializes CREATE TABLE
and DROP TABLE, as well as reading
the dictionary data for a table from
system tables */
hash_table_t table_hash; /*!< hash table of the tables, based
on name */
/** hash table of persistent table IDs */
@ -1437,6 +1432,9 @@ private:
/** The synchronization interval of row_id */
static constexpr size_t ROW_ID_WRITE_MARGIN= 256;
public:
/** Diagnostic message for exceeding the mutex_lock_wait() timeout */
static const char fatal_msg[];
/** @return A new value for GEN_CLUST_INDEX(DB_ROW_ID) */
inline row_id_t get_new_row_id();
@ -1461,7 +1459,7 @@ public:
(should only happen during the rollback of CREATE...SELECT) */
dict_table_t* get_temporary_table(table_id_t id)
{
ut_ad(mutex_own(&mutex));
mysql_mutex_assert_owner(&mutex);
dict_table_t* table;
ulint fold = ut_fold_ull(id);
HASH_SEARCH(id_hash, &temp_id_hash, fold, dict_table_t*, table,
@ -1480,7 +1478,7 @@ public:
@retval NULL if not cached */
dict_table_t* get_table(table_id_t id)
{
ut_ad(mutex_own(&mutex));
mysql_mutex_assert_owner(&mutex);
dict_table_t* table;
ulint fold = ut_fold_ull(id);
HASH_SEARCH(id_hash, &table_id_hash, fold, dict_table_t*,
@ -1515,7 +1513,7 @@ public:
{
ut_ad(table);
ut_ad(table->can_be_evicted == in_lru);
ut_ad(mutex_own(&mutex));
mysql_mutex_assert_owner(&mutex);
for (const dict_table_t* t = UT_LIST_GET_FIRST(in_lru
? table_LRU : table_non_LRU);
t; t = UT_LIST_GET_NEXT(table_LRU, t))
@ -1546,25 +1544,44 @@ public:
/** Acquire a reference to a cached table. */
inline void acquire(dict_table_t* table);
#ifdef UNIV_DEBUG
/** Assert that the data dictionary is locked */
void assert_locked() { ut_ad(mutex_own(&mutex)); }
/** Assert that the mutex is locked */
void assert_locked() const { mysql_mutex_assert_owner(&mutex); }
/** Assert that the mutex is not locked */
void assert_not_locked() const { mysql_mutex_assert_not_owner(&mutex); }
#ifdef SAFE_MUTEX
bool mutex_is_locked() const { return mysql_mutex_is_owner(&mutex); }
#endif
private:
/** Acquire the mutex */
ATTRIBUTE_NOINLINE void mutex_lock_wait();
public:
/** @return the my_hrtime_coarse().val of the oldest mutex_lock_wait() start,
assuming that requests are served on a FIFO basis */
ulonglong oldest_wait() const
{ return mutex_wait_start.load(std::memory_order_relaxed); }
#ifdef HAVE_PSI_MUTEX_INTERFACE
/** Acquire the mutex */
ATTRIBUTE_NOINLINE void mutex_lock();
/** Release the mutex */
ATTRIBUTE_NOINLINE void mutex_unlock();
#else
/** Acquire the mutex */
void mutex_lock() { if (mysql_mutex_trylock(&mutex)) mutex_lock_wait(); }
/** Release the mutex */
void mutex_unlock() { mysql_mutex_unlock(&mutex); }
#endif
/** Lock the data dictionary cache. */
void lock(const char* file, unsigned line)
{
latch.wr_lock(SRW_LOCK_ARGS(file, line));
ut_ad(!latch_ex);
ut_d(latch_ex= true);
mutex_enter_loc(&mutex, file, line);
}
void lock(SRW_LOCK_ARGS(const char *file, unsigned line));
/** Unlock the data dictionary cache. */
void unlock()
{
ut_ad(latch_ex);
ut_d(latch_ex= false);
mutex_exit(&mutex);
mutex_unlock();
latch.wr_unlock();
}
@ -1595,7 +1612,7 @@ public:
extern dict_sys_t dict_sys;
#define dict_table_prevent_eviction(table) dict_sys.prevent_eviction(table)
#define dict_sys_lock() dict_sys.lock(__FILE__, __LINE__)
#define dict_sys_lock() dict_sys.lock(SRW_LOCK_CALL)
#define dict_sys_unlock() dict_sys.unlock()
/* Auxiliary structs for checking a table definition @{ */

View file

@ -1139,12 +1139,10 @@ dict_table_is_file_per_table(
}
/** Acquire the table handle. */
inline
void
dict_table_t::acquire()
inline void dict_table_t::acquire()
{
ut_ad(mutex_own(&dict_sys.mutex));
n_ref_count++;
dict_sys.assert_locked();
n_ref_count++;
}
/** Release the table handle.

View file

@ -39,7 +39,7 @@ dict_table_get_low(
dict_table_t* table;
ut_ad(table_name);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
table = dict_table_check_if_in_cache_low(table_name);
@ -79,7 +79,7 @@ dict_table_check_if_in_cache_low(
("table: '%s'", table_name));
ut_ad(table_name);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
/* Look for the table name in the hash table */
table_fold = ut_fold_string(table_name);

View file

@ -148,7 +148,7 @@ dict_stats_init(
/*============*/
dict_table_t* table) /*!< in/out: table */
{
ut_ad(!mutex_own(&dict_sys.mutex));
dict_sys.assert_not_locked();
if (table->stat_initialized) {
return;
@ -174,7 +174,7 @@ dict_stats_deinit(
/*==============*/
dict_table_t* table) /*!< in/out: table */
{
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
ut_a(table->get_ref_count() == 0);

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation.
Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -31,7 +31,7 @@ Created Apr 26, 2012 Vasil Dimov
#include "os0thread.h"
#ifdef HAVE_PSI_INTERFACE
extern mysql_pfs_key_t dict_stats_recalc_pool_mutex_key;
extern mysql_pfs_key_t recalc_pool_mutex_key;
#endif /* HAVE_PSI_INTERFACE */
#ifdef UNIV_DEBUG
@ -67,7 +67,7 @@ dict_stats_stop_bg(
dict_table_t* table) /*!< in/out: table */
{
ut_ad(!srv_read_only_mode);
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
if (!(table->stats_bg_flag & BG_STAT_IN_PROGRESS)) {
return(true);

View file

@ -27,7 +27,7 @@ Created 1/8/1996 Heikki Tuuri
#ifndef dict0types_h
#define dict0types_h
#include <ut0mutex.h>
#include "univ.i"
#include <rem0types.h>
struct dict_col_t;
@ -90,10 +90,6 @@ enum ib_quiesce_t {
QUIESCE_COMPLETE /*!< All done */
};
#ifndef UNIV_INNOCHECKSUM
typedef ib_mutex_t DictSysMutex;
#endif /* !UNIV_INNOCHECKSUM */
/** Prefix for tmp tables, adopted from sql/table.h */
#define TEMP_FILE_PREFIX "#sql"
#define TEMP_FILE_PREFIX_LENGTH 4

View file

@ -1415,7 +1415,8 @@ public:
std::vector<pfs_os_file_t> detach(fil_space_t *space,
bool detach_handle= false);
ib_mutex_t mutex; /*!< The mutex protecting the cache */
/** the mutex protecting most data fields, and some fields of fil_space_t */
mysql_mutex_t mutex;
fil_space_t* sys_space; /*!< The innodb_system tablespace */
fil_space_t* temp_space; /*!< The innodb_temporary tablespace */
/** Map of fil_space_t::id to fil_space_t* */
@ -1467,14 +1468,18 @@ extern fil_system_t fil_system;
inline void fil_space_t::reacquire()
{
ut_d(uint32_t n=) n_pending.fetch_add(1, std::memory_order_relaxed);
ut_d(if (mutex_own(&fil_system.mutex)) return);
#ifdef SAFE_MUTEX
if (mysql_mutex_is_owner(&fil_system.mutex)) return;
ut_ad(n & PENDING);
ut_ad(UT_LIST_GET_FIRST(chain)->is_open());
#endif /* SAFE_MUTEX */
}
inline bool fil_space_t::acquire_if_not_stopped(bool have_mutex)
{
ut_ad(mutex_own(&fil_system.mutex) == have_mutex);
#ifdef SAFE_MUTEX
ut_ad(mysql_mutex_is_owner(&fil_system.mutex) == have_mutex);
#endif
const uint32_t n= acquire_low();
if (UNIV_LIKELY(!(n & (STOPPING | CLOSING))))
return true;
@ -1484,7 +1489,7 @@ inline bool fil_space_t::acquire_if_not_stopped(bool have_mutex)
/** Note that operations on the tablespace must stop or can resume */
inline void fil_space_t::set_stopping(bool stopping)
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
ut_d(auto n=) n_pending.fetch_xor(STOPPING, std::memory_order_relaxed);
ut_ad(!(n & STOPPING) == stopping);
}
@ -1492,7 +1497,7 @@ inline void fil_space_t::set_stopping(bool stopping)
/** Flush pending writes from the file system cache to the file. */
template<bool have_reference> inline void fil_space_t::flush()
{
ut_ad(!mutex_own(&fil_system.mutex));
mysql_mutex_assert_not_owner(&fil_system.mutex);
ut_ad(!have_reference || (pending() & PENDING));
ut_ad(purpose == FIL_TYPE_TABLESPACE || purpose == FIL_TYPE_IMPORT);
if (srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)
@ -1514,9 +1519,9 @@ inline uint32_t fil_space_t::get_size()
{
if (!size)
{
mutex_enter(&fil_system.mutex);
mysql_mutex_lock(&fil_system.mutex);
read_page0();
mutex_exit(&fil_system.mutex);
mysql_mutex_unlock(&fil_system.mutex);
}
return size;
}
@ -1789,11 +1794,6 @@ char*
fil_path_to_space_name(
const char* filename);
/** Acquire the fil_system mutex. */
#define fil_system_enter() mutex_enter(&fil_system.mutex)
/** Release the fil_system mutex. */
#define fil_system_exit() mutex_exit(&fil_system.mutex)
/*******************************************************************//**
Returns the table space by a given id, NULL if not found. */
fil_space_t*

View file

@ -377,12 +377,8 @@ extern ulong fts_min_token_size;
need a sync to free some memory */
extern bool fts_need_sync;
#define fts_que_graph_free(graph) \
do { \
mutex_enter(&dict_sys.mutex); \
que_graph_free(graph); \
mutex_exit(&dict_sys.mutex); \
} while (0)
/** Free a query graph */
void fts_que_graph_free(que_t *graph);
/******************************************************************//**
Create a FTS cache. */

View file

@ -175,12 +175,12 @@ rtr_get_parent_node(
return(NULL);
}
mutex_enter(&btr_cur->rtr_info->rtr_path_mutex);
mysql_mutex_lock(&btr_cur->rtr_info->rtr_path_mutex);
num = btr_cur->rtr_info->parent_path->size();
if (!num) {
mutex_exit(&btr_cur->rtr_info->rtr_path_mutex);
mysql_mutex_unlock(&btr_cur->rtr_info->rtr_path_mutex);
return(NULL);
}
@ -203,7 +203,7 @@ rtr_get_parent_node(
}
}
mutex_exit(&btr_cur->rtr_info->rtr_path_mutex);
mysql_mutex_unlock(&btr_cur->rtr_info->rtr_path_mutex);
return(found_node);
}

View file

@ -72,7 +72,7 @@ typedef struct matched_rec {
buf_block_t block; /*!< the shadow buffer block */
ulint used; /*!< memory used */
rtr_rec_vector* matched_recs; /*!< vector holding the matching rec */
ib_mutex_t rtr_match_mutex;/*!< mutex protect the match_recs
mysql_mutex_t rtr_match_mutex;/*!< mutex protect the match_recs
vector */
bool valid; /*!< whether result in matched_recs
or this search is valid (page not
@ -103,7 +103,7 @@ typedef struct rtr_info{
/*!< vector holding parent pages during
search */
matched_rec_t* matches;/*!< struct holding matching leaf records */
ib_mutex_t rtr_path_mutex;
mysql_mutex_t rtr_path_mutex;
/*!< mutex protect the "path" vector */
buf_block_t* tree_blocks[RTR_MAX_LEVELS + RTR_LEAF_LATCH_NUM];
/*!< tracking pages that would be locked
@ -137,7 +137,7 @@ typedef struct rtr_info{
struct rtr_info_track_t {
/** Active search info */
std::forward_list<rtr_info_t*, ut_allocator<rtr_info_t*> > rtr_active;
ib_mutex_t rtr_active_mutex;
mysql_mutex_t rtr_active_mutex;
/*!< mutex to protect
rtr_active */
};

View file

@ -26,6 +26,7 @@ Created 5/20/1997 Heikki Tuuri
#pragma once
#include "ut0rnd.h"
#include "ut0new.h"
struct hash_table_t;
struct hash_cell_t{

View file

@ -1,610 +0,0 @@
/*****************************************************************************
Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/******************************************************************//**
@file include/ib0mutex.h
Policy based mutexes.
Created 2013-03-26 Sunny Bains.
***********************************************************************/
#ifndef UNIV_INNOCHECKSUM
#ifndef ib0mutex_h
#define ib0mutex_h
#include "my_cpu.h"
/** OS mutex for tracking lock/unlock for debugging */
template <template <typename> class Policy>
struct OSTrackMutex {
typedef Policy<OSTrackMutex> MutexPolicy;
explicit OSTrackMutex(bool destroy_mutex_at_exit = true)
UNIV_NOTHROW
{
ut_d(m_freed = true);
ut_d(m_locked = false);
ut_d(m_destroy_at_exit = destroy_mutex_at_exit);
}
~OSTrackMutex() UNIV_NOTHROW
{
ut_ad(!m_destroy_at_exit || !m_locked);
}
/** Initialise the mutex. */
void init(latch_id_t, const char*, uint32_t) UNIV_NOTHROW
{
ut_ad(m_freed);
ut_ad(!m_locked);
m_mutex.init();
ut_d(m_freed = false);
}
/** Destroy the mutex */
void destroy() UNIV_NOTHROW
{
ut_ad(!m_locked);
ut_ad(!m_freed);
m_mutex.destroy();
ut_d(m_freed = true);
}
/** Release the mutex. */
void exit() UNIV_NOTHROW
{
ut_ad(m_locked);
ut_d(m_locked = false);
ut_ad(!m_freed);
m_mutex.exit();
}
/** Acquire the mutex. */
void enter(uint32_t, uint32_t, const char*, uint32_t)
UNIV_NOTHROW
{
ut_ad(!m_freed);
m_mutex.enter();
ut_ad(!m_locked);
ut_d(m_locked = true);
}
/** @return true if locking succeeded */
bool try_lock() UNIV_NOTHROW
{
ut_ad(!m_freed);
bool locked = m_mutex.try_lock();
if (locked) {
ut_ad(!m_locked);
ut_d(m_locked = locked);
}
return(locked);
}
/** @return non-const version of the policy */
MutexPolicy& policy()
UNIV_NOTHROW
{
return(m_policy);
}
/** @return the const version of the policy */
const MutexPolicy& policy() const
UNIV_NOTHROW
{
return(m_policy);
}
private:
#ifdef UNIV_DEBUG
/** true if the mutex has not be initialized */
bool m_freed;
/** true if the mutex has been locked. */
bool m_locked;
/** Do/Dont destroy mutex at exit */
bool m_destroy_at_exit;
#endif /* UNIV_DEBUG */
/** OS Mutex instance */
OSMutex m_mutex;
/** Policy data */
MutexPolicy m_policy;
};
#ifdef __linux__
#include <linux/futex.h>
#include <sys/syscall.h>
/** Mutex implementation that used the Linux futex. */
template <template <typename> class Policy>
struct TTASFutexMutex {
typedef Policy<TTASFutexMutex> MutexPolicy;
TTASFutexMutex() UNIV_NOTHROW
:
m_lock_word(MUTEX_STATE_UNLOCKED)
{
/* Check that lock_word is aligned. */
ut_ad(!((ulint) &m_lock_word % sizeof(ulint)));
}
~TTASFutexMutex()
{
ut_ad(m_lock_word.load(std::memory_order_relaxed)
== MUTEX_STATE_UNLOCKED);
}
/** Called when the mutex is "created". Note: Not from the constructor
but when the mutex is initialised. */
void init(latch_id_t, const char*, uint32_t) UNIV_NOTHROW
{
ut_ad(m_lock_word.load(std::memory_order_relaxed)
== MUTEX_STATE_UNLOCKED);
}
/** Destroy the mutex. */
void destroy() UNIV_NOTHROW
{
/* The destructor can be called at shutdown. */
ut_ad(m_lock_word.load(std::memory_order_relaxed)
== MUTEX_STATE_UNLOCKED);
}
/** Acquire the mutex.
@param[in] max_spins max number of spins
@param[in] max_delay max delay per spin */
void enter(uint32_t max_spins, uint32_t max_delay,
const char*, uint32_t) UNIV_NOTHROW
{
uint32_t n_spins, n_waits;
for (n_spins= 0; n_spins < max_spins; n_spins++) {
if (try_lock()) {
m_policy.add(n_spins, 0);
return;
}
ut_delay(max_delay);
}
for (n_waits= 0;; n_waits++) {
if (m_lock_word.exchange(MUTEX_STATE_WAITERS,
std::memory_order_acquire)
== MUTEX_STATE_UNLOCKED) {
break;
}
syscall(SYS_futex, &m_lock_word,
FUTEX_WAIT_PRIVATE, MUTEX_STATE_WAITERS,
0, 0, 0);
}
m_policy.add(n_spins, n_waits);
}
/** Release the mutex. */
void exit() UNIV_NOTHROW
{
if (m_lock_word.exchange(MUTEX_STATE_UNLOCKED,
std::memory_order_release)
== MUTEX_STATE_WAITERS) {
syscall(SYS_futex, &m_lock_word, FUTEX_WAKE_PRIVATE,
1, 0, 0, 0);
}
}
/** Try and lock the mutex.
@return true if successful */
bool try_lock() UNIV_NOTHROW
{
int32 oldval = MUTEX_STATE_UNLOCKED;
return m_lock_word.compare_exchange_strong(
oldval,
MUTEX_STATE_LOCKED,
std::memory_order_acquire,
std::memory_order_relaxed);
}
/** @return non-const version of the policy */
MutexPolicy& policy() UNIV_NOTHROW
{
return(m_policy);
}
/** @return const version of the policy */
const MutexPolicy& policy() const UNIV_NOTHROW
{
return(m_policy);
}
private:
/** Policy data */
MutexPolicy m_policy;
/** lock_word is the target of the atomic test-and-set instruction
when atomic operations are enabled. */
std::atomic<int32> m_lock_word;
};
#endif /* __linux__ */
template <template <typename> class Policy>
struct TTASMutex {
typedef Policy<TTASMutex> MutexPolicy;
TTASMutex() UNIV_NOTHROW
:
m_lock_word(MUTEX_STATE_UNLOCKED)
{
/* Check that lock_word is aligned. */
ut_ad(!((ulint) &m_lock_word % sizeof(ulint)));
}
~TTASMutex()
{
ut_ad(m_lock_word.load(std::memory_order_relaxed)
== MUTEX_STATE_UNLOCKED);
}
/** Called when the mutex is "created". Note: Not from the constructor
but when the mutex is initialised. */
void init(latch_id_t) UNIV_NOTHROW
{
ut_ad(m_lock_word.load(std::memory_order_relaxed)
== MUTEX_STATE_UNLOCKED);
}
/** Destroy the mutex. */
void destroy() UNIV_NOTHROW
{
/* The destructor can be called at shutdown. */
ut_ad(m_lock_word.load(std::memory_order_relaxed)
== MUTEX_STATE_UNLOCKED);
}
/** Try and lock the mutex.
@return true on success */
bool try_lock() UNIV_NOTHROW
{
uint32_t oldval = MUTEX_STATE_UNLOCKED;
return m_lock_word.compare_exchange_strong(
oldval,
MUTEX_STATE_LOCKED,
std::memory_order_acquire,
std::memory_order_relaxed);
}
/** Release the mutex. */
void exit() UNIV_NOTHROW
{
ut_ad(m_lock_word.load(std::memory_order_relaxed)
== MUTEX_STATE_LOCKED);
m_lock_word.store(MUTEX_STATE_UNLOCKED,
std::memory_order_release);
}
/** Acquire the mutex.
@param max_spins max number of spins
@param max_delay max delay per spin */
void enter(uint32_t max_spins, uint32_t max_delay,
const char*, uint32_t) UNIV_NOTHROW
{
const uint32_t step = max_spins;
uint32_t n_spins = 0;
while (!try_lock()) {
ut_delay(max_delay);
if (++n_spins == max_spins) {
os_thread_yield();
max_spins+= step;
}
}
m_policy.add(n_spins, 0);
}
/** @return non-const version of the policy */
MutexPolicy& policy() UNIV_NOTHROW
{
return(m_policy);
}
/** @return const version of the policy */
const MutexPolicy& policy() const UNIV_NOTHROW
{
return(m_policy);
}
private:
// Disable copying
TTASMutex(const TTASMutex&);
TTASMutex& operator=(const TTASMutex&);
/** Policy data */
MutexPolicy m_policy;
/** mutex state */
std::atomic<uint32_t> m_lock_word;
};
/** Mutex interface for all policy mutexes. This class handles the interfacing
with the Performance Schema instrumentation. */
template <typename MutexImpl>
struct PolicyMutex
{
typedef typename MutexImpl::MutexPolicy Policy;
PolicyMutex() UNIV_NOTHROW : m_impl()
{
#ifdef UNIV_PFS_MUTEX
m_ptr = 0;
#endif /* UNIV_PFS_MUTEX */
}
~PolicyMutex() { }
/** @return non-const version of the policy */
Policy& policy() UNIV_NOTHROW
{
return(m_impl.policy());
}
/** @return const version of the policy */
const Policy& policy() const UNIV_NOTHROW
{
return(m_impl.policy());
}
/** Release the mutex. */
void exit() UNIV_NOTHROW
{
#ifdef UNIV_PFS_MUTEX
pfs_exit();
#endif /* UNIV_PFS_MUTEX */
ut_d(policy().context.release(m_impl));
m_impl.exit();
}
/** Acquire the mutex.
@param n_spins max number of spins
@param n_delay max delay per spin
@param name filename where locked
@param line line number where locked */
void enter(
uint32_t n_spins,
uint32_t n_delay,
const char* name,
uint32_t line) UNIV_NOTHROW
{
#ifdef UNIV_PFS_MUTEX
/* Note: locker is really an alias for state. That's why
it has to be in the same scope during pfs_end(). */
PSI_mutex_locker_state state;
PSI_mutex_locker* locker;
locker = pfs_begin_lock(&state, name, line);
#endif /* UNIV_PFS_MUTEX */
ut_d(policy().context.enter(m_impl, name, line));
m_impl.enter(n_spins, n_delay, name, line);
ut_d(policy().context.locked(m_impl, name, line));
#ifdef UNIV_PFS_MUTEX
pfs_end(locker, 0);
#endif /* UNIV_PFS_MUTEX */
}
/** Try and lock the mutex, return 0 on SUCCESS and 1 otherwise.
@param name filename where locked
@param line line number where locked */
int trylock(const char* name, uint32_t line) UNIV_NOTHROW
{
#ifdef UNIV_PFS_MUTEX
/* Note: locker is really an alias for state. That's why
it has to be in the same scope during pfs_end(). */
PSI_mutex_locker_state state;
PSI_mutex_locker* locker;
locker = pfs_begin_trylock(&state, name, line);
#endif /* UNIV_PFS_MUTEX */
/* There is a subtlety here, we check the mutex ordering
after locking here. This is only done to avoid add and
then remove if the trylock was unsuccesful. */
int ret = m_impl.try_lock() ? 0 : 1;
if (ret == 0) {
ut_d(policy().context.enter(m_impl, name, line));
ut_d(policy().context.locked(m_impl, name, line));
}
#ifdef UNIV_PFS_MUTEX
pfs_end(locker, 0);
#endif /* UNIV_PFS_MUTEX */
return(ret);
}
#ifdef UNIV_DEBUG
/** @return true if the thread owns the mutex. */
bool is_owned() const UNIV_NOTHROW
{
return(policy().context.is_owned());
}
#endif /* UNIV_DEBUG */
/**
Initialise the mutex.
@param[in] id Mutex ID
@param[in] filename file where created
@param[in] line line number in file where created */
void init(
latch_id_t id,
const char* filename,
uint32_t line)
UNIV_NOTHROW
{
#ifdef UNIV_PFS_MUTEX
pfs_add(sync_latch_get_pfs_key(id));
#endif /* UNIV_PFS_MUTEX */
m_impl.init(id, filename, line);
policy().init(m_impl, id, filename, line);
ut_d(policy().context.init(id));
}
/** Free resources (if any) */
void destroy() UNIV_NOTHROW
{
#ifdef UNIV_PFS_MUTEX
pfs_del();
#endif /* UNIV_PFS_MUTEX */
m_impl.destroy();
policy().destroy();
ut_d(policy().context.destroy());
}
/** Required for os_event_t */
operator sys_mutex_t*() UNIV_NOTHROW
{
return(m_impl.operator sys_mutex_t*());
}
#ifdef UNIV_PFS_MUTEX
/** Performance schema monitoring - register mutex with PFS.
Note: This is public only because we want to get around an issue
with registering a subset of buffer pool pages with PFS when
PFS_GROUP_BUFFER_SYNC is defined. Therefore this has to then
be called by external code (see buf0buf.cc).
@param key - Performance Schema key. */
void pfs_add(mysql_pfs_key_t key) UNIV_NOTHROW
{
ut_ad(m_ptr == 0);
m_ptr = PSI_MUTEX_CALL(init_mutex)(key, this);
}
private:
/** Performance schema monitoring.
@param state - PFS locker state
@param name - file name where locked
@param line - line number in file where locked */
PSI_mutex_locker* pfs_begin_lock(
PSI_mutex_locker_state* state,
const char* name,
uint32_t line) UNIV_NOTHROW
{
if (m_ptr != 0) {
return(PSI_MUTEX_CALL(start_mutex_wait)(
state, m_ptr,
PSI_MUTEX_LOCK, name, (uint) line));
}
return(0);
}
/** Performance schema monitoring.
@param state - PFS locker state
@param name - file name where locked
@param line - line number in file where locked */
PSI_mutex_locker* pfs_begin_trylock(
PSI_mutex_locker_state* state,
const char* name,
uint32_t line) UNIV_NOTHROW
{
if (m_ptr != 0) {
return(PSI_MUTEX_CALL(start_mutex_wait)(
state, m_ptr,
PSI_MUTEX_TRYLOCK, name, (uint) line));
}
return(0);
}
/** Performance schema monitoring
@param locker - PFS identifier
@param ret - 0 for success and 1 for failure */
void pfs_end(PSI_mutex_locker* locker, int ret) UNIV_NOTHROW
{
if (locker != 0) {
PSI_MUTEX_CALL(end_mutex_wait)(locker, ret);
}
}
/** Performance schema monitoring - register mutex release */
void pfs_exit()
{
if (m_ptr != 0) {
PSI_MUTEX_CALL(unlock_mutex)(m_ptr);
}
}
/** Performance schema monitoring - deregister */
void pfs_del()
{
if (m_ptr != 0) {
PSI_MUTEX_CALL(destroy_mutex)(m_ptr);
m_ptr = 0;
}
}
#endif /* UNIV_PFS_MUTEX */
private:
/** The mutex implementation */
MutexImpl m_impl;
#ifdef UNIV_PFS_MUTEX
/** The performance schema instrumentation hook. */
PSI_mutex* m_ptr;
#endif /* UNIV_PFS_MUTEX */
};
#endif /* ib0mutex_h */
#endif /* !UNIV_INNOCHECKSUM */

View file

@ -706,9 +706,15 @@ class lock_sys_t
{
bool m_initialised;
public:
/** The my_hrtime_coarse().val of the oldest mutex_lock_wait() start, or 0 */
std::atomic<ulonglong> mutex_wait_start;
/** mutex proteting the locks */
MY_ALIGNED(CACHE_LINE_SIZE) mysql_mutex_t mutex;
public:
/** Diagnostic message for exceeding the mutex_lock_wait() timeout */
static const char fatal_msg[];
/** record locks */
hash_table_t rec_hash;
/** predicate locks for SPATIAL INDEX */
@ -741,6 +747,38 @@ public:
bool is_initialised() { return m_initialised; }
private:
/** Acquire lock_sys.mutex */
ATTRIBUTE_NOINLINE void mutex_lock_wait();
public:
#ifdef HAVE_PSI_MUTEX_INTERFACE
/** Try to acquire lock_sys.mutex */
ATTRIBUTE_NOINLINE int mutex_trylock();
/** Acquire lock_sys.mutex */
ATTRIBUTE_NOINLINE void mutex_lock();
/** Release lock_sys.mutex */
ATTRIBUTE_NOINLINE void mutex_unlock();
#else
/** Try to acquire lock_sys.mutex */
int mutex_trylock() { return mysql_mutex_trylock(&mutex); }
/** Aqcuire lock_sys.mutex */
void mutex_lock() { if (mutex_trylock()) mutex_lock_wait(); }
/** Release lock_sys.mutex */
void mutex_unlock() { mysql_mutex_unlock(&mutex); }
#endif
/** Assert that mutex_lock() has been invoked */
void mutex_assert_locked() const { mysql_mutex_assert_owner(&mutex); }
/** Assert that mutex_lock() has not been invoked */
void mutex_assert_unlocked() const { mysql_mutex_assert_not_owner(&mutex); }
/** @return the my_hrtime_coarse().val of the oldest mutex_lock_wait() start,
assuming that requests are served on a FIFO basis */
ulonglong oldest_wait() const
{ return mutex_wait_start.load(std::memory_order_relaxed); }
/** Wait for a lock to be granted */
void wait_lock(lock_t **lock, mysql_cond_t *cond)
{ while (*lock) mysql_cond_wait(cond, &mutex); }
/**
Creates the lock system at database start.

View file

@ -629,7 +629,7 @@ inline void lock_set_lock_and_trx_wait(lock_t* lock, trx_t* trx)
ut_ad(lock);
ut_ad(lock->trx == trx);
ut_ad(trx->lock.wait_lock == NULL);
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
trx->lock.wait_lock = lock;
lock->type_mode |= LOCK_WAIT;
@ -640,7 +640,7 @@ inline void lock_set_lock_and_trx_wait(lock_t* lock, trx_t* trx)
inline void lock_reset_lock_and_trx_wait(lock_t* lock)
{
ut_ad(lock_get_wait(lock));
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
ut_ad(lock->trx->lock.wait_lock == NULL
|| lock->trx->lock.wait_lock == lock);
lock->trx->lock.wait_lock = NULL;

View file

@ -131,7 +131,7 @@ lock_rec_get_next(
ulint heap_no,/*!< in: heap number of the record */
lock_t* lock) /*!< in: lock */
{
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
do {
ut_ad(lock_get_type_low(lock) == LOCK_REC);
@ -206,7 +206,7 @@ lock_rec_get_next_on_page_const(
/*============================*/
const lock_t* lock) /*!< in: a record lock */
{
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
ut_ad(lock_get_type_low(lock) == LOCK_REC);
const page_id_t page_id(lock->un_member.rec_lock.page_id);

View file

@ -27,7 +27,6 @@ Created 12/9/1995 Heikki Tuuri
#include "mach0data.h"
#include "assume_aligned.h"
#include "ut0crc32.h"
#include "sync0debug.h"
extern ulong srv_log_buffer_size;
@ -305,17 +304,6 @@ log_free_check(void)
are holding some latches. This is OK, as long as we are not holding
any latches on buffer blocks. */
#ifdef UNIV_DEBUG
static const latch_level_t latches[] = {
SYNC_DICT, /* dict_sys.mutex during
commit_try_rebuild() */
};
#endif /* UNIV_DEBUG */
ut_ad(!sync_check_iterate(
sync_allowed_latches(latches,
latches + UT_ARR_SIZE(latches))));
if (log_sys.check_flush_or_checkpoint()) {
log_check_margins();

View file

@ -26,11 +26,10 @@ Created 9/20/1997 Heikki Tuuri
#pragma once
#include "ut0byte.h"
#include "ut0new.h"
#include "buf0types.h"
#include "log0log.h"
#include "mtr0types.h"
#include "ut0mutex.h"
#include <deque>

View file

@ -24,6 +24,8 @@ The memory management
Created 6/8/1994 Heikki Tuuri
*************************************************************************/
#include "ut0new.h"
#ifdef UNIV_DEBUG
# define mem_heap_create_block(heap, n, type, file_name, line) \
mem_heap_create_block_func(heap, n, file_name, line, type)

View file

@ -24,14 +24,11 @@ Mini-transaction buffer global types
Created 11/26/1995 Heikki Tuuri
*******************************************************/
#ifndef mtr0types_h
#define mtr0types_h
#pragma once
#ifndef UNIV_INNOCHECKSUM
#include "buf0types.h"
#else
#include "univ.i"
#endif /* UNIV_INNOCHECKSUM */
#include "ut0byte.h"
struct mtr_t;
@ -344,6 +341,4 @@ enum mtr_memo_type_t {
/** wr_lock() on fil_space_t::latch */
MTR_MEMO_SPACE_S_LOCK = MTR_MEMO_SX_LOCK << 2
};
#endif /* !UNIV_CHECKSUM */
#endif /* mtr0types_h */
#endif /* !UNIV_INNOCHECKSUM */

View file

@ -59,11 +59,6 @@ extern "C" { typedef void* (*os_thread_func_t)(void*); }
/* Define a function pointer type to use in a typecast */
typedef void* (*os_posix_f_t) (void*);
#ifdef HAVE_PSI_INTERFACE
/* Define for performance schema registration key */
typedef unsigned int mysql_pfs_key_t;
#endif /* HAVE_PSI_INTERFACE */
#define os_thread_eq(a,b) IF_WIN(a == b, pthread_equal(a, b))
#define os_thread_yield() IF_WIN(SwitchToThread(), sched_yield())
#define os_thread_get_curr_id() IF_WIN(GetCurrentThreadId(), pthread_self())

View file

@ -30,6 +30,7 @@ Created 2/2/1994 Heikki Tuuri
#include "dict0types.h"
#include "mtr0types.h"
#include "rem0types.h"
#include "ut0new.h"
#include <map>

View file

@ -324,11 +324,7 @@ void
page_zip_reset_stat_per_index()
/*===========================*/
{
mutex_enter(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index.erase(
page_zip_stat_per_index.begin(),
page_zip_stat_per_index.end());
mutex_exit(&page_zip_stat_per_index_mutex);
mysql_mutex_lock(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index.clear();
mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
}

View file

@ -24,13 +24,15 @@ Cursor read
Created 2/16/1997 Heikki Tuuri
*******************************************************/
#ifndef read0types_h
#define read0types_h
#pragma once
#include "dict0mem.h"
#include "trx0types.h"
#include <algorithm>
#ifdef UNIV_PFS_MUTEX
extern mysql_pfs_key_t read_view_mutex_key;
#endif
/**
Read view lists the trx ids of those transactions for which a consistent read
@ -190,7 +192,7 @@ class ReadView: public ReadViewBase
std::atomic<bool> m_open;
/** For synchronisation with purge coordinator. */
mutable ib_mutex_t m_mutex;
mutable mysql_mutex_t m_mutex;
/**
trx id of creating transaction.
@ -199,8 +201,9 @@ class ReadView: public ReadViewBase
trx_id_t m_creator_trx_id;
public:
ReadView(): m_open(false) { mutex_create(LATCH_ID_READ_VIEW, &m_mutex); }
~ReadView() { mutex_free(&m_mutex); }
ReadView(): m_open(false)
{ mysql_mutex_init(read_view_mutex_key, &m_mutex, nullptr); }
~ReadView() { mysql_mutex_destroy(&m_mutex); }
/**
@ -248,12 +251,12 @@ public:
*/
void print_limits(FILE *file) const
{
mutex_enter(&m_mutex);
mysql_mutex_lock(&m_mutex);
if (is_open())
fprintf(file, "Trx read view will not see trx with"
" id >= " TRX_ID_FMT ", sees < " TRX_ID_FMT "\n",
low_limit_id(), up_limit_id());
mutex_exit(&m_mutex);
mysql_mutex_unlock(&m_mutex);
}
@ -271,23 +274,19 @@ public:
*/
void append_to(ReadViewBase *to) const
{
mutex_enter(&m_mutex);
mysql_mutex_lock(&m_mutex);
if (is_open())
to->append(*this);
mutex_exit(&m_mutex);
mysql_mutex_unlock(&m_mutex);
}
/**
Declare the object mostly unaccessible.
innodb_monitor_set_option is operating also on freed transaction objects.
*/
void mem_noaccess() const
{
MEM_NOACCESS(&m_open, sizeof m_open);
/* m_mutex is accessed by innodb_show_mutex_status()
and innodb_monitor_update() even after trx_t::free() */
/* m_mutex is accessed via trx_sys.rw_trx_hash */
MEM_NOACCESS(&m_creator_trx_id, sizeof m_creator_trx_id);
}
};
#endif

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation.
Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -316,11 +316,18 @@ data dictionary modification operation. */
void
row_mysql_lock_data_dictionary_func(
/*================================*/
trx_t* trx, /*!< in/out: transaction */
#ifdef UNIV_PFS_RWLOCK
const char* file, /*!< in: file name */
unsigned line); /*!< in: line number */
unsigned line, /*!< in: line number */
#endif
trx_t* trx); /*!< in/out: transaction */
#ifdef UNIV_PFS_RWLOCK
#define row_mysql_lock_data_dictionary(trx) \
row_mysql_lock_data_dictionary_func(trx, __FILE__, __LINE__)
row_mysql_lock_data_dictionary_func(__FILE__, __LINE__, trx)
#else
#define row_mysql_lock_data_dictionary row_mysql_lock_data_dictionary_func
#endif
/*********************************************************************//**
Unlocks the data dictionary exclusive lock. */
void

View file

@ -38,7 +38,6 @@ Created 12/15/2009 Jimmy Yang
#include <stdint.h>
#include "my_atomic.h"
#include "my_atomic_wrapper.h"
/** Possible status values for "mon_status" in "struct monitor_value" */
enum monitor_running_status {
@ -419,10 +418,6 @@ enum monitor_id_t {
MONITOR_ICP_OUT_OF_RANGE,
MONITOR_ICP_MATCH,
/* Mutex/RW-Lock related counters */
MONITOR_MODULE_LATCHES,
MONITOR_LATCHES,
/* This is used only for control system to turn
on/off and reset all monitor counters */
MONITOR_ALL_COUNTER,

View file

@ -52,6 +52,29 @@ Created 10/10/1995 Heikki Tuuri
#include <tpool.h>
#include <memory>
/** Simple non-atomic counter
@tparam Type the integer type of the counter */
template <typename Type>
struct MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE) simple_counter
{
/** Increment the counter */
Type inc() { return add(1); }
/** Decrement the counter */
Type dec() { return add(Type(~0)); }
/** Add to the counter
@param i amount to be added
@return the value of the counter after adding */
Type add(Type i) { return m_counter += i; }
/** @return the value of the counter */
operator Type() const { return m_counter; }
private:
/** The counter */
Type m_counter;
};
/** Global counters used inside InnoDB. */
struct srv_stats_t
{
@ -210,15 +233,13 @@ at a time */
#define SRV_AUTO_EXTEND_INCREMENT (srv_sys_space.get_autoextend_increment())
/** Mutex protecting page_zip_stat_per_index */
extern ib_mutex_t page_zip_stat_per_index_mutex;
/* Mutex for locking srv_monitor_file. Not created if srv_read_only_mode */
extern ib_mutex_t srv_monitor_file_mutex;
extern mysql_mutex_t page_zip_stat_per_index_mutex;
/** Mutex for locking srv_monitor_file */
extern mysql_mutex_t srv_monitor_file_mutex;
/* Temporary file for innodb monitor output */
extern FILE* srv_monitor_file;
/* Mutex for locking srv_misc_tmpfile. Only created if !srv_read_only_mode.
This mutex has a very low rank; threads reserving it should not
acquire any further latches or sleep before releasing this one. */
extern ib_mutex_t srv_misc_tmpfile_mutex;
/** Mutex for locking srv_misc_tmpfile */
extern mysql_mutex_t srv_misc_tmpfile_mutex;
/* Temporary file for miscellanous diagnostic output */
extern FILE* srv_misc_tmpfile;
@ -454,7 +475,6 @@ extern ulint srv_log_writes_and_flush;
#ifdef UNIV_DEBUG
extern my_bool innodb_evict_tables_on_commit_debug;
extern my_bool srv_sync_debug;
extern my_bool srv_purge_view_update_only_debug;
/** Value of MySQL global used to disable master thread. */
@ -480,9 +500,6 @@ extern uint srv_n_purge_threads;
/* the number of pages to purge in one batch */
extern ulong srv_purge_batch_size;
/* the number of sync wait arrays */
extern ulong srv_sync_array_size;
/* print all user-level transactions deadlocks to mysqld stderr */
extern my_bool srv_print_all_deadlocks;

View file

@ -1,78 +0,0 @@
/*****************************************************************************
Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
briefly in the InnoDB documentation. The contributions by Google are
incorporated with their permission, and subject to the conditions contained in
the file COPYING.Google.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/sync0debug.h
Debug checks for latches, header file
Created 2012-08-21 Sunny Bains
*******************************************************/
#ifndef sync0debug_h
#define sync0debug_h
#include "univ.i"
/** Initializes the synchronization data structures. */
void
sync_check_init();
/** Free the InnoDB synchronization data structures. */
void
sync_check_close();
#ifdef UNIV_DEBUG
/** Check if it is OK to acquire the latch.
@param[in] latch latch type */
void
sync_check_lock_validate(const latch_t* latch);
/** Note that the lock has been granted
@param[in] latch latch type */
void
sync_check_lock_granted(const latch_t* latch);
/** Removes a latch from the thread level array if it is found there.
@param[in] latch to unlock */
void
sync_check_unlock(const latch_t* latch);
/** Checks if the level array for the current thread contains a
mutex or rw-latch at the specified level.
@param[in] level to find
@return a matching latch, or NULL if not found */
const latch_t*
sync_check_find(latch_level_t level);
/** Checks that the level array for the current thread is empty.
Terminate iteration if the functor returns true.
@param[in] functor called for each element.
@return true if the functor returns true for any element */
bool
sync_check_iterate(const sync_check_functor_t& functor);
#endif /* UNIV_DEBUG */
#endif /* !sync0debug_h */

View file

@ -1,296 +0,0 @@
/*****************************************************************************
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/******************************************************************//**
@file include/sync0policy.h
Policies for mutexes.
Created 2012-08-21 Sunny Bains.
***********************************************************************/
#ifndef sync0policy_h
#define sync0policy_h
#include "ut0rnd.h"
#include "os0thread.h"
#include "srv0mon.h"
#include "sync0debug.h"
#ifdef UNIV_DEBUG
template <typename Mutex> class MutexDebug: public latch_t
{
/** Mutex to check for lock order violation */
const Mutex *m_mutex;
/** Filename from where enter was called */
const char *m_filename;
/** Line mumber in filename */
unsigned m_line;
/** Thread ID of the thread that owns the mutex */
os_thread_id_t m_thread_id;
/** Mutex protecting the above members */
mutable OSMutex m_debug_mutex;
void set(const Mutex *mutex, const char *filename, unsigned line,
os_thread_id_t thread_id)
{
m_debug_mutex.enter();
m_mutex= mutex;
m_filename= filename;
m_line= line;
m_thread_id= thread_id;
m_debug_mutex.exit();
}
const MutexDebug get() const
{
MutexDebug ret;
m_debug_mutex.enter();
ret.m_mutex= m_mutex;
ret.m_filename= m_filename;
ret.m_line= m_line;
ret.m_thread_id= m_thread_id;
m_debug_mutex.exit();
return ret;
}
/**
Called either when mutex is locked or destroyed. Thus members are protected
from concurrent modification.
*/
void assert_clean_context()
{
ut_ad(!m_mutex);
ut_ad(!m_filename);
ut_ad(!m_line);
ut_ad(m_thread_id == os_thread_id_t(ULINT_UNDEFINED));
}
public:
/**
Called when the mutex is "created". Note: Not from the constructor
but when the mutex is initialised.
@param[in] id Mutex ID
*/
void init(latch_id_t id)
{
ut_ad(id != LATCH_ID_NONE);
m_id= id;
m_debug_mutex.init();
set(0, 0, 0, os_thread_id_t(ULINT_UNDEFINED));
}
/** Mutex is being destroyed. */
void destroy()
{
assert_clean_context();
m_debug_mutex.destroy();
}
/**
Called when an attempt is made to lock the mutex
@param[in] mutex Mutex instance to be locked
@param[in] filename Filename from where it was called
@param[in] line Line number from where it was called
*/
void enter(const Mutex &mutex, const char *filename, unsigned line)
{
MutexDebug context;
ut_ad(!is_owned());
context.init(m_id);
context.set(&mutex, filename, line, os_thread_get_curr_id());
/* Check for latch order violation. */
sync_check_lock_validate(&context);
context.set(0, 0, 0, os_thread_id_t(ULINT_UNDEFINED));
context.destroy();
}
/**
Called when the mutex is locked
@param[in] mutex Mutex instance that was locked
@param[in] filename Filename from where it was called
@param[in] line Line number from where it was called
*/
void locked(const Mutex &mutex, const char *filename, unsigned line)
{
assert_clean_context();
set(&mutex, filename, line, os_thread_get_curr_id());
sync_check_lock_granted(this);
}
/**
Called when the mutex is released
@param[in] mutex Mutex that was released
*/
void release(const Mutex &mutex)
{
ut_ad(is_owned());
set(0, 0, 0, os_thread_id_t(ULINT_UNDEFINED));
sync_check_unlock(this);
}
/** @return true if thread owns the mutex */
bool is_owned() const
{
return os_thread_eq(get_thread_id(), os_thread_get_curr_id());
}
/** @return the name of the file from the mutex was acquired */
const char* get_enter_filename() const { return get().m_filename; }
/** @return the name of the file from the mutex was acquired */
unsigned get_enter_line() const { return get().m_line; }
/** @return id of the thread that was trying to acquire the mutex */
os_thread_id_t get_thread_id() const { return get().m_thread_id; }
/**
Print information about the latch
@return the string representation
*/
virtual std::string to_string() const
{
std::ostringstream msg;
const MutexDebug ctx= get();
msg << m_mutex->policy().to_string();
if (ctx.m_mutex)
msg << " addr: " << ctx.m_mutex << " acquired: "
<< sync_basename(ctx.get_enter_filename()) << ":"
<< ctx.get_enter_line();
else
msg << "Not locked";
return(msg.str());
}
};
#endif /* UNIV_DEBUG */
/** Collect the metrics per mutex instance, no aggregation. */
template <typename Mutex>
struct GenericPolicy
{
public:
/** Called when the mutex is "created". Note: Not from the constructor
but when the mutex is initialised.
@param[in] id Mutex ID
@param[in] filename File where mutex was created
@param[in] line Line in filename */
void init(
const Mutex&,
latch_id_t id,
const char* filename,
uint32_t line)
UNIV_NOTHROW
{
m_id = id;
latch_meta_t& meta = sync_latch_get_meta(id);
ut_ad(meta.get_id() == id);
meta.get_counter()->single_register(&m_count);
m_filename = filename;
m_line = line;
}
/** Called when the mutex is destroyed. */
void destroy()
UNIV_NOTHROW
{
latch_meta_t& meta = sync_latch_get_meta(m_id);
meta.get_counter()->single_deregister(&m_count);
}
/** Called after a successful mutex acquire.
@param[in] n_spins Number of times the thread did
spins while trying to acquire the mutex
@param[in] n_waits Number of times the thread waited
in some type of OS queue */
void add(
uint32_t n_spins,
uint32_t n_waits)
UNIV_NOTHROW
{
/* Currently global on/off. Keeps things simple and fast */
if (!m_count.m_enabled) {
return;
}
m_count.m_spins += n_spins;
m_count.m_waits += n_waits;
++m_count.m_calls;
}
/** Print the information about the latch
@return the string representation */
std::string print() const
UNIV_NOTHROW;
/** @return the latch ID */
latch_id_t get_id() const
UNIV_NOTHROW
{
return(m_id);
}
/** @return the string representation */
std::string to_string() const
{
return sync_mutex_to_string(get_id(),
std::string(m_filename)
.append(":")
.append(std::to_string(m_line)));
}
#ifdef UNIV_DEBUG
MutexDebug<Mutex> context;
#endif
private:
const char *m_filename;
uint32_t m_line;
/** The user visible counters, registered with the meta-data. */
latch_meta_t::CounterType::Count m_count;
/** Latch meta data ID */
latch_id_t m_id;
};
#endif /* sync0policy_h */

View file

@ -1,96 +0,0 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
briefly in the InnoDB documentation. The contributions by Google are
incorporated with their permission, and subject to the conditions contained in
the file COPYING.Google.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/sync0sync.h
Mutex, the basic synchronization primitive
Created 9/5/1995 Heikki Tuuri
*******************************************************/
#ifndef sync0sync_h
#define sync0sync_h
#include "univ.i"
#ifdef UNIV_PFS_MUTEX
/* Key defines to register InnoDB mutexes with performance schema */
extern mysql_pfs_key_t buf_pool_mutex_key;
extern mysql_pfs_key_t dict_foreign_err_mutex_key;
extern mysql_pfs_key_t dict_sys_mutex_key;
extern mysql_pfs_key_t fil_system_mutex_key;
extern mysql_pfs_key_t flush_list_mutex_key;
extern mysql_pfs_key_t fts_cache_mutex_key;
extern mysql_pfs_key_t fts_cache_init_mutex_key;
extern mysql_pfs_key_t fts_delete_mutex_key;
extern mysql_pfs_key_t fts_doc_id_mutex_key;
extern mysql_pfs_key_t fts_pll_tokenize_mutex_key;
extern mysql_pfs_key_t ibuf_bitmap_mutex_key;
extern mysql_pfs_key_t ibuf_mutex_key;
extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
extern mysql_pfs_key_t log_sys_mutex_key;
extern mysql_pfs_key_t log_cmdq_mutex_key;
extern mysql_pfs_key_t log_flush_order_mutex_key;
extern mysql_pfs_key_t recalc_pool_mutex_key;
extern mysql_pfs_key_t purge_sys_pq_mutex_key;
extern mysql_pfs_key_t recv_sys_mutex_key;
extern mysql_pfs_key_t rtr_active_mutex_key;
extern mysql_pfs_key_t rtr_match_mutex_key;
extern mysql_pfs_key_t rtr_path_mutex_key;
extern mysql_pfs_key_t redo_rseg_mutex_key;
extern mysql_pfs_key_t noredo_rseg_mutex_key;
extern mysql_pfs_key_t page_zip_stat_per_index_mutex_key;
extern mysql_pfs_key_t srv_innodb_monitor_mutex_key;
extern mysql_pfs_key_t srv_misc_tmpfile_mutex_key;
extern mysql_pfs_key_t srv_monitor_file_mutex_key;
extern mysql_pfs_key_t buf_dblwr_mutex_key;
extern mysql_pfs_key_t trx_pool_mutex_key;
extern mysql_pfs_key_t trx_pool_manager_mutex_key;
extern mysql_pfs_key_t lock_mutex_key;
extern mysql_pfs_key_t lock_wait_mutex_key;
extern mysql_pfs_key_t trx_sys_mutex_key;
extern mysql_pfs_key_t srv_threads_mutex_key;
extern mysql_pfs_key_t sync_array_mutex_key;
extern mysql_pfs_key_t thread_mutex_key;
extern mysql_pfs_key_t row_drop_list_mutex_key;
extern mysql_pfs_key_t rw_trx_hash_element_mutex_key;
extern mysql_pfs_key_t read_view_mutex_key;
#endif /* UNIV_PFS_MUTEX */
#ifdef UNIV_PFS_RWLOCK
/* Following are rwlock keys used to register with MySQL
performance schema */
extern mysql_pfs_key_t dict_operation_lock_key;
extern mysql_pfs_key_t fil_space_latch_key;
extern mysql_pfs_key_t trx_i_s_cache_lock_key;
extern mysql_pfs_key_t trx_purge_latch_key;
extern mysql_pfs_key_t index_tree_rw_lock_key;
extern mysql_pfs_key_t index_online_log_key;
extern mysql_pfs_key_t trx_sys_rw_lock_key;
#endif /* UNIV_PFS_RWLOCK */
#endif /* !sync0sync_h */

View file

@ -1,967 +0,0 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/sync0types.h
Global types for sync
Created 9/5/1995 Heikki Tuuri
*******************************************************/
#ifndef sync0types_h
#define sync0types_h
#include <vector>
#include "ut0new.h"
#ifdef _WIN32
/** Native mutex */
typedef CRITICAL_SECTION sys_mutex_t;
#else
/** Native mutex */
typedef pthread_mutex_t sys_mutex_t;
#endif /* _WIN32 */
/** Mutex states. */
enum mutex_state_t {
/** Mutex is free */
MUTEX_STATE_UNLOCKED = 0,
/** Mutex is acquired by some thread. */
MUTEX_STATE_LOCKED = 1,
/** Mutex is contended and there are threads waiting on the lock. */
MUTEX_STATE_WAITERS = 2
};
/*
LATCHING ORDER WITHIN THE DATABASE
==================================
The mutex or latch in the central memory object, for instance, a rollback
segment object, must be acquired before acquiring the latch or latches to
the corresponding file data structure. In the latching order below, these
file page object latches are placed immediately below the corresponding
central memory object latch or mutex.
Synchronization object Notes
---------------------- -----
Dictionary mutex If we have a pointer to a dictionary
| object, e.g., a table, it can be
| accessed without reserving the
| dictionary mutex. We must have a
| reservation, a memoryfix, to the
| appropriate table object in this case,
| and the table must be explicitly
| released later.
V
Dictionary header
|
V
Secondary index tree latch The tree latch protects also all
| the B-tree non-leaf pages. These
V can be read with the page only
Secondary index non-leaf bufferfixed to save CPU time,
| no s-latch is needed on the page.
| Modification of a page requires an
| x-latch on the page, however. If a
| thread owns an x-latch to the tree,
| it is allowed to latch non-leaf pages
| even after it has acquired the fsp
| latch.
V
Secondary index leaf The latch on the secondary index leaf
| can be kept while accessing the
| clustered index, to save CPU time.
V
Clustered index tree latch To increase concurrency, the tree
| latch is usually released when the
| leaf page latch has been acquired.
V
Clustered index non-leaf
|
V
Clustered index leaf
|
V
Transaction system header
|
V
Rollback segment mutex The rollback segment mutex must be
| reserved, if, e.g., a new page must
| be added to an undo log. The rollback
| segment and the undo logs in its
| history list can be seen as an
| analogue of a B-tree, and the latches
| reserved similarly, using a version of
| lock-coupling. If an undo log must be
| extended by a page when inserting an
| undo log record, this corresponds to
| a pessimistic insert in a B-tree.
V
Rollback segment header
|
V
Purge system latch
|
V
Undo log pages If a thread owns the trx undo mutex,
| or for a log in the history list, the
| rseg mutex, it is allowed to latch
| undo log pages in any order, and even
| after it has acquired the fsp latch.
| If a thread does not have the
| appropriate mutex, it is allowed to
| latch only a single undo log page in
| a mini-transaction.
V
File space management latch If a mini-transaction must allocate
| several file pages, it can do that,
| because it keeps the x-latch to the
| file space management in its memo.
V
File system pages
|
V
lock_sys.wait_mutex Mutex protecting lock timeout data
|
V
lock_sys.mutex Mutex protecting lock_sys_t
|
V
trx_sys.mutex Mutex protecting trx_sys.trx_list
|
V
Threads mutex Background thread scheduling mutex
|
V
query_thr_mutex Mutex protecting query threads
|
V
trx_mutex Mutex protecting trx_t fields
|
V
Search system mutex
|
V
Buffer pool mutex
|
V
Log mutex
|
Any other latch
|
V
Memory pool mutex */
/** Latching order levels. If you modify these, you have to also update
LatchDebug internals in sync0debug.cc */
enum latch_level_t {
SYNC_UNKNOWN = 0,
RW_LOCK_SX,
RW_LOCK_X_WAIT,
RW_LOCK_S,
RW_LOCK_X,
RW_LOCK_NOT_LOCKED,
SYNC_ANY_LATCH,
SYNC_POOL,
SYNC_POOL_MANAGER,
SYNC_PURGE_QUEUE,
SYNC_RW_TRX_HASH_ELEMENT,
SYNC_READ_VIEW,
SYNC_TRX_SYS,
SYNC_INDEX_ONLINE_LOG,
SYNC_IBUF_BITMAP_MUTEX,
SYNC_IBUF_MUTEX,
SYNC_NOREDO_RSEG,
SYNC_REDO_RSEG,
SYNC_IBUF_PESS_INSERT_MUTEX,
SYNC_STATS_AUTO_RECALC,
SYNC_DICT,
/** This can be used to suppress order checking. */
SYNC_NO_ORDER_CHECK,
/** Maximum level value */
SYNC_LEVEL_MAX = SYNC_NO_ORDER_CHECK
};
/** Each latch has an ID. This id is used for creating the latch and to look
up its meta-data. See sync0debug.cc. */
enum latch_id_t {
LATCH_ID_NONE = 0,
LATCH_ID_DICT_FOREIGN_ERR,
LATCH_ID_DICT_SYS,
LATCH_ID_FIL_SYSTEM,
LATCH_ID_IBUF_BITMAP,
LATCH_ID_IBUF,
LATCH_ID_IBUF_PESSIMISTIC_INSERT,
LATCH_ID_PURGE_SYS_PQ,
LATCH_ID_RECALC_POOL,
LATCH_ID_REDO_RSEG,
LATCH_ID_NOREDO_RSEG,
LATCH_ID_RTR_ACTIVE_MUTEX,
LATCH_ID_RTR_MATCH_MUTEX,
LATCH_ID_RTR_PATH_MUTEX,
LATCH_ID_SRV_INNODB_MONITOR,
LATCH_ID_SRV_MISC_TMPFILE,
LATCH_ID_SRV_MONITOR_FILE,
LATCH_ID_TRX_POOL,
LATCH_ID_TRX_POOL_MANAGER,
LATCH_ID_TRX_SYS,
LATCH_ID_SRV_SYS_TASKS,
LATCH_ID_PAGE_ZIP_STAT_PER_INDEX,
LATCH_ID_SYNC_ARRAY_MUTEX,
LATCH_ID_ROW_DROP_LIST,
LATCH_ID_INDEX_ONLINE_LOG,
LATCH_ID_DICT_TABLE_STATS,
LATCH_ID_DEFRAGMENT_MUTEX,
LATCH_ID_RW_TRX_HASH_ELEMENT,
LATCH_ID_READ_VIEW,
LATCH_ID_MAX = LATCH_ID_READ_VIEW
};
#ifndef UNIV_INNOCHECKSUM
/** OS mutex, without any policy. It is a thin wrapper around the
system mutexes. The interface is different from the policy mutexes,
to ensure that it is called directly and not confused with the
policy mutexes. */
struct OSMutex {
/** Constructor */
OSMutex()
UNIV_NOTHROW
{
ut_d(m_freed = true);
}
/** Create the mutex by calling the system functions. */
void init()
UNIV_NOTHROW
{
ut_ad(m_freed);
#ifdef _WIN32
InitializeCriticalSection((LPCRITICAL_SECTION) &m_mutex);
#else
{
int ret = pthread_mutex_init(&m_mutex, NULL);
ut_a(ret == 0);
}
#endif /* _WIN32 */
ut_d(m_freed = false);
}
/** Destructor */
~OSMutex() { }
/** Destroy the mutex */
void destroy()
UNIV_NOTHROW
{
ut_ad(!m_freed);
#ifdef _WIN32
DeleteCriticalSection((LPCRITICAL_SECTION) &m_mutex);
#else
int ret;
ret = pthread_mutex_destroy(&m_mutex);
if (ret != 0) {
ib::error()
<< "Return value " << ret << " when calling "
<< "pthread_mutex_destroy().";
}
#endif /* _WIN32 */
ut_d(m_freed = true);
}
/** Release the mutex. */
void exit()
UNIV_NOTHROW
{
ut_ad(!m_freed);
#ifdef _WIN32
LeaveCriticalSection(&m_mutex);
#else
int ret = pthread_mutex_unlock(&m_mutex);
ut_a(ret == 0);
#endif /* _WIN32 */
}
/** Acquire the mutex. */
void enter()
UNIV_NOTHROW
{
ut_ad(!m_freed);
#ifdef _WIN32
EnterCriticalSection((LPCRITICAL_SECTION) &m_mutex);
#else
int ret = pthread_mutex_lock(&m_mutex);
ut_a(ret == 0);
#endif /* _WIN32 */
}
/** @return true if locking succeeded */
bool try_lock()
UNIV_NOTHROW
{
ut_ad(!m_freed);
#ifdef _WIN32
return(TryEnterCriticalSection(&m_mutex) != 0);
#else
return(pthread_mutex_trylock(&m_mutex) == 0);
#endif /* _WIN32 */
}
/** Required for os_event_t */
operator sys_mutex_t*()
UNIV_NOTHROW
{
return(&m_mutex);
}
private:
#ifdef DBUG_ASSERT_EXISTS
/** true if the mutex has been freed/destroyed. */
bool m_freed;
#endif /* DBUG_ASSERT_EXISTS */
sys_mutex_t m_mutex;
};
#ifdef UNIV_PFS_MUTEX
/** Latch element.
Used for mutexes which have PFS keys defined under UNIV_PFS_MUTEX.
@param[in] id Latch id
@param[in] level Latch level
@param[in] key PFS key */
# define LATCH_ADD_MUTEX(id, level, key) latch_meta[LATCH_ID_ ## id] =\
UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level, key))
#ifdef UNIV_PFS_RWLOCK
/** Latch element.
Used for rwlocks which have PFS keys defined under UNIV_PFS_RWLOCK.
@param[in] id Latch id
@param[in] level Latch level
@param[in] key PFS key */
# define LATCH_ADD_RWLOCK(id, level, key) latch_meta[LATCH_ID_ ## id] =\
UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level, key))
#else
# define LATCH_ADD_RWLOCK(id, level, key) latch_meta[LATCH_ID_ ## id] =\
UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level, \
PSI_NOT_INSTRUMENTED))
#endif /* UNIV_PFS_RWLOCK */
#else
# define LATCH_ADD_MUTEX(id, level, key) latch_meta[LATCH_ID_ ## id] =\
UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level))
# define LATCH_ADD_RWLOCK(id, level, key) latch_meta[LATCH_ID_ ## id] =\
UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level))
#endif /* UNIV_PFS_MUTEX */
/** Default latch counter */
class LatchCounter {
public:
/** The counts we collect for a mutex */
struct Count {
/** Constructor */
Count()
UNIV_NOTHROW
:
m_spins(),
m_waits(),
m_calls(),
m_enabled()
{
/* No op */
}
/** Rest the values to zero */
void reset()
UNIV_NOTHROW
{
m_spins = 0;
m_waits = 0;
m_calls = 0;
}
/** Number of spins trying to acquire the latch. */
uint32_t m_spins;
/** Number of waits trying to acquire the latch */
uint32_t m_waits;
/** Number of times it was called */
uint32_t m_calls;
/** true if enabled */
bool m_enabled;
};
/** Constructor */
LatchCounter()
UNIV_NOTHROW
:
m_active(false)
{
m_mutex.init();
}
/** Destructor */
~LatchCounter()
UNIV_NOTHROW
{
m_mutex.destroy();
for (Counters::iterator it = m_counters.begin();
it != m_counters.end();
++it) {
Count* count = *it;
UT_DELETE(count);
}
}
/** Reset all counters to zero. It is not protected by any
mutex and we don't care about atomicity. Unless it is a
demonstrated problem. The information collected is not
required for the correct functioning of the server. */
void reset()
UNIV_NOTHROW
{
m_mutex.enter();
Counters::iterator end = m_counters.end();
for (Counters::iterator it = m_counters.begin();
it != end;
++it) {
(*it)->reset();
}
m_mutex.exit();
}
/** @return the aggregate counter */
Count* sum_register()
UNIV_NOTHROW
{
m_mutex.enter();
Count* count;
if (m_counters.empty()) {
count = UT_NEW_NOKEY(Count());
m_counters.push_back(count);
} else {
ut_a(m_counters.size() == 1);
count = m_counters[0];
}
m_mutex.exit();
return(count);
}
/** Register a single instance counter */
void single_register(Count* count)
UNIV_NOTHROW
{
m_mutex.enter();
m_counters.push_back(count);
m_mutex.exit();
}
/** Deregister a single instance counter
@param[in] count The count instance to deregister */
void single_deregister(Count* count)
UNIV_NOTHROW
{
m_mutex.enter();
m_counters.erase(
std::remove(
m_counters.begin(),
m_counters.end(), count),
m_counters.end());
m_mutex.exit();
}
/** Iterate over the counters */
template<typename C> void iterate(const C& callback) UNIV_NOTHROW
{
m_mutex.enter();
Counters::const_iterator end = m_counters.end();
for (Counters::const_iterator it = m_counters.begin();
it != end;
++it) {
callback(*it);
}
m_mutex.exit();
}
/** Disable the monitoring */
void enable()
UNIV_NOTHROW
{
m_mutex.enter();
Counters::const_iterator end = m_counters.end();
for (Counters::const_iterator it = m_counters.begin();
it != end;
++it) {
(*it)->m_enabled = true;
}
m_active = true;
m_mutex.exit();
}
/** Disable the monitoring */
void disable()
UNIV_NOTHROW
{
m_mutex.enter();
Counters::const_iterator end = m_counters.end();
for (Counters::const_iterator it = m_counters.begin();
it != end;
++it) {
(*it)->m_enabled = false;
}
m_active = false;
m_mutex.exit();
}
/** @return if monitoring is active */
bool is_enabled() const
UNIV_NOTHROW
{
return(m_active);
}
private:
/* Disable copying */
LatchCounter(const LatchCounter&);
LatchCounter& operator=(const LatchCounter&);
private:
typedef OSMutex Mutex;
typedef std::vector<Count*> Counters;
/** Mutex protecting m_counters */
Mutex m_mutex;
/** Counters for the latches */
Counters m_counters;
/** if true then we collect the data */
bool m_active;
};
/** Latch meta data */
template <typename Counter = LatchCounter>
class LatchMeta {
public:
typedef Counter CounterType;
#ifdef UNIV_PFS_MUTEX
typedef mysql_pfs_key_t pfs_key_t;
#endif /* UNIV_PFS_MUTEX */
/** Constructor */
LatchMeta()
:
m_id(LATCH_ID_NONE),
m_name(),
m_level(SYNC_UNKNOWN),
m_level_name()
#ifdef UNIV_PFS_MUTEX
,m_pfs_key()
#endif /* UNIV_PFS_MUTEX */
{
}
/** Destructor */
~LatchMeta() { }
/** Constructor
@param[in] id Latch id
@param[in] name Latch name
@param[in] level Latch level
@param[in] level_name Latch level text representation
@param[in] key PFS key */
LatchMeta(
latch_id_t id,
const char* name,
latch_level_t level,
const char* level_name
#ifdef UNIV_PFS_MUTEX
,pfs_key_t key
#endif /* UNIV_PFS_MUTEX */
)
:
m_id(id),
m_name(name),
m_level(level),
m_level_name(level_name)
#ifdef UNIV_PFS_MUTEX
,m_pfs_key(key)
#endif /* UNIV_PFS_MUTEX */
{
/* No op */
}
/* Less than operator.
@param[in] rhs Instance to compare against
@return true if this.get_id() < rhs.get_id() */
bool operator<(const LatchMeta& rhs) const
{
return(get_id() < rhs.get_id());
}
/** @return the latch id */
latch_id_t get_id() const
{
return(m_id);
}
/** @return the latch name */
const char* get_name() const
{
return(m_name);
}
/** @return the latch level */
latch_level_t get_level() const
{
return(m_level);
}
/** @return the latch level name */
const char* get_level_name() const
{
return(m_level_name);
}
#ifdef UNIV_PFS_MUTEX
/** @return the PFS key for the latch */
pfs_key_t get_pfs_key() const
{
return(m_pfs_key);
}
#endif /* UNIV_PFS_MUTEX */
/** @return the counter instance */
Counter* get_counter()
{
return(&m_counter);
}
private:
/** Latch id */
latch_id_t m_id;
/** Latch name */
const char* m_name;
/** Latch level in the ordering */
latch_level_t m_level;
/** Latch level text representation */
const char* m_level_name;
#ifdef UNIV_PFS_MUTEX
/** PFS key */
pfs_key_t m_pfs_key;
#endif /* UNIV_PFS_MUTEX */
/** For gathering latch statistics */
Counter m_counter;
};
typedef LatchMeta<LatchCounter> latch_meta_t;
typedef std::vector<latch_meta_t*, ut_allocator<latch_meta_t*> > LatchMetaData;
/** Note: This is accessed without any mutex protection. It is initialised
at startup and elements should not be added to or removed from it after
that. See sync_latch_meta_init() */
extern LatchMetaData latch_meta;
/** Get the latch meta-data from the latch ID
@param[in] id Latch ID
@return the latch meta data */
inline
latch_meta_t&
sync_latch_get_meta(latch_id_t id)
{
ut_ad(static_cast<size_t>(id) < latch_meta.size());
ut_ad(id == latch_meta[id]->get_id());
return(*latch_meta[id]);
}
/** Fetch the counter for the latch
@param[in] id Latch ID
@return the latch counter */
inline
latch_meta_t::CounterType*
sync_latch_get_counter(latch_id_t id)
{
latch_meta_t& meta = sync_latch_get_meta(id);
return(meta.get_counter());
}
/** Get the latch name from the latch ID
@param[in] id Latch ID
@return the name, will assert if not found */
inline
const char*
sync_latch_get_name(latch_id_t id)
{
const latch_meta_t& meta = sync_latch_get_meta(id);
return(meta.get_name());
}
/** Get the latch ordering level
@param[in] id Latch id to lookup
@return the latch level */
inline
latch_level_t
sync_latch_get_level(latch_id_t id)
{
const latch_meta_t& meta = sync_latch_get_meta(id);
return(meta.get_level());
}
#ifdef UNIV_PFS_MUTEX
/** Get the latch PFS key from the latch ID
@param[in] id Latch ID
@return the PFS key */
inline
mysql_pfs_key_t
sync_latch_get_pfs_key(latch_id_t id)
{
const latch_meta_t& meta = sync_latch_get_meta(id);
return(meta.get_pfs_key());
}
#endif
/** String representation of the filename and line number where the
latch was created
@param[in] id Latch ID
@param[in] created Filename and line number where it was crated
@return the string representation */
std::string
sync_mutex_to_string(
latch_id_t id,
const std::string& created);
/** Get the latch name from a sync level
@param[in] level Latch level to lookup
@return 0 if not found. */
const char*
sync_latch_get_name(latch_level_t level);
/** Print the filename "basename"
@return the basename */
const char*
sync_basename(const char* filename);
#ifdef UNIV_DEBUG
/** All (ordered) latches, used in debugging, must derive from this class. */
struct latch_t {
/** Constructor
@param[in] id The latch ID */
explicit latch_t(latch_id_t id = LATCH_ID_NONE)
UNIV_NOTHROW
: m_id(id) {}
/** Destructor */
virtual ~latch_t() UNIV_NOTHROW { }
/** @return the latch ID */
latch_id_t get_id() const
{
return(m_id);
}
/** Print the latch context
@return the string representation */
virtual std::string to_string() const = 0;
/** @return the latch level */
latch_level_t get_level() const
UNIV_NOTHROW
{
ut_a(m_id != LATCH_ID_NONE);
return(sync_latch_get_level(m_id));
}
/** @return the latch name, m_id must be set */
const char* get_name() const
UNIV_NOTHROW
{
ut_a(m_id != LATCH_ID_NONE);
return(sync_latch_get_name(m_id));
}
/** Latch ID */
latch_id_t m_id;
};
/** Subclass this to iterate over a thread's acquired latch levels. */
struct sync_check_functor_t {
virtual ~sync_check_functor_t() { }
virtual bool operator()(const latch_level_t) const = 0;
};
/** Check that no latch is being held.
@tparam some_allowed whether some latches are allowed to be held */
template<bool some_allowed = false>
struct sync_checker : public sync_check_functor_t
{
/** Check the latching constraints
@param[in] level The level held by the thread
@return whether a latch violation was detected */
bool operator()(const latch_level_t level) const override
{
if (some_allowed) {
switch (level) {
case SYNC_DICT:
case SYNC_NO_ORDER_CHECK:
return(false);
default:
return(true);
}
}
return(true);
}
};
/** The strict latch checker (no InnoDB latches may be held) */
typedef struct sync_checker<false> sync_check;
/** The sloppy latch checker (can hold InnoDB dictionary or SQL latches) */
typedef struct sync_checker<true> dict_sync_check;
/** Functor to check for given latching constraints. */
struct sync_allowed_latches : public sync_check_functor_t {
/** Constructor
@param[in] from first element in an array of latch_level_t
@param[in] to last element in an array of latch_level_t */
sync_allowed_latches(
const latch_level_t* from,
const latch_level_t* to)
: begin(from), end(to) { }
/** Checks whether the given latch_t violates the latch constraint.
This object maintains a list of allowed latch levels, and if the given
latch belongs to a latch level that is not there in the allowed list,
then it is a violation.
@param[in] latch The latch level to check
@return true if there is a latch violation */
bool operator()(const latch_level_t level) const override
{
return(std::find(begin, end, level) == end);
}
private:
/** First element in an array of allowed latch levels */
const latch_level_t* const begin;
/** First element after the end of the array of allowed latch levels */
const latch_level_t* const end;
};
/** Get the latch id from a latch name.
@param[in] id Latch name
@return LATCH_ID_NONE. */
latch_id_t
sync_latch_get_id(const char* name);
#endif /* UNIV_DBEUG */
#endif /* UNIV_INNOCHECKSUM */
/** Simple non-atomic counter aligned to CACHE_LINE_SIZE
@tparam Type the integer type of the counter */
template <typename Type>
struct MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE) simple_counter
{
/** Increment the counter */
Type inc() { return add(1); }
/** Decrement the counter */
Type dec() { return add(Type(~0)); }
/** Add to the counter
@param[in] i amount to be added
@return the value of the counter after adding */
Type add(Type i) { return m_counter += i; }
/** @return the value of the counter */
operator Type() const { return m_counter; }
private:
/** The counter */
Type m_counter;
};
#endif /* sync0types_h */

View file

@ -190,7 +190,7 @@ public:
purge_pq_t purge_queue; /*!< Binary min-heap, ordered on
TrxUndoRsegs::trx_no. It is protected
by the pq_mutex */
PQMutex pq_mutex; /*!< Mutex protecting purge_queue */
mysql_mutex_t pq_mutex; /*!< Mutex protecting purge_queue */
/** Undo tablespace file truncation (only accessed by the
srv_purge_coordinator_thread) */

View file

@ -30,6 +30,11 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0sys.h"
#include "fut0lst.h"
#ifdef UNIV_PFS_MUTEX
extern mysql_pfs_key_t redo_rseg_mutex_key;
extern mysql_pfs_key_t noredo_rseg_mutex_key;
#endif /* UNIV_PFS_MUTEX */
/** Gets a rollback segment header.
@param[in] space space where placed
@param[in] page_no page number of the header
@ -100,7 +105,7 @@ struct trx_rseg_t {
/** mutex protecting the fields in this struct except id,space,page_no
which are constant */
RsegMutex mutex;
mysql_mutex_t mutex;
/** space where the rollback segment header is placed */
fil_space_t* space;

View file

@ -24,9 +24,7 @@ Transaction system
Created 3/26/1996 Heikki Tuuri
*******************************************************/
#ifndef trx0sys_h
#define trx0sys_h
#pragma once
#include "buf0buf.h"
#include "fil0fil.h"
#include "trx0types.h"
@ -36,12 +34,17 @@ Created 3/26/1996 Heikki Tuuri
#include "ut0lst.h"
#include "read0types.h"
#include "page0types.h"
#include "ut0mutex.h"
#include "trx0trx.h"
#ifdef WITH_WSREP
#include "trx0xa.h"
#endif /* WITH_WSREP */
#include "ilist.h"
#include "my_cpu.h"
#ifdef UNIV_PFS_MUTEX
extern mysql_pfs_key_t trx_sys_mutex_key;
extern mysql_pfs_key_t rw_trx_hash_element_mutex_key;
#endif
/** Checks if a page address is the trx sys header page.
@param[in] page_id page id
@ -345,13 +348,13 @@ struct rw_trx_hash_element_t
{
rw_trx_hash_element_t(): trx(0)
{
mutex_create(LATCH_ID_RW_TRX_HASH_ELEMENT, &mutex);
mysql_mutex_init(rw_trx_hash_element_mutex_key, &mutex, nullptr);
}
~rw_trx_hash_element_t()
{
mutex_free(&mutex);
mysql_mutex_destroy(&mutex);
}
@ -365,7 +368,7 @@ struct rw_trx_hash_element_t
*/
Atomic_counter<trx_id_t> no;
trx_t *trx;
ib_mutex_t mutex;
mysql_mutex_t mutex;
};
@ -534,10 +537,10 @@ class rw_trx_hash_t
static my_bool debug_iterator(rw_trx_hash_element_t *element,
debug_iterator_arg<T> *arg)
{
mutex_enter(&element->mutex);
mysql_mutex_lock(&element->mutex);
if (element->trx)
validate_element(element->trx);
mutex_exit(&element->mutex);
mysql_mutex_unlock(&element->mutex);
return arg->action(element, arg->argument);
}
#endif
@ -639,7 +642,7 @@ public:
sizeof(trx_id_t)));
if (element)
{
mutex_enter(&element->mutex);
mysql_mutex_lock(&element->mutex);
lf_hash_search_unpin(pins);
if ((trx= element->trx)) {
DBUG_ASSERT(trx_id == trx->id);
@ -660,7 +663,7 @@ public:
trx->reference();
}
}
mutex_exit(&element->mutex);
mysql_mutex_unlock(&element->mutex);
}
if (!caller_trx)
lf_hash_put_pins(pins);
@ -694,9 +697,9 @@ public:
void erase(trx_t *trx)
{
ut_d(validate_element(trx));
mutex_enter(&trx->rw_trx_hash_element->mutex);
mysql_mutex_lock(&trx->rw_trx_hash_element->mutex);
trx->rw_trx_hash_element->trx= 0;
mutex_exit(&trx->rw_trx_hash_element->mutex);
mysql_mutex_unlock(&trx->rw_trx_hash_element->mutex);
int res= lf_hash_delete(&hash, get_pins(trx),
reinterpret_cast<const void*>(&trx->id),
sizeof(trx_id_t));
@ -730,12 +733,12 @@ public:
May return element with committed transaction. If caller doesn't like to
see committed transactions, it has to skip those under element mutex:
mutex_enter(&element->mutex);
mysql_mutex_lock(&element->mutex);
if (trx_t trx= element->trx)
{
// trx is protected against commit in this branch
}
mutex_exit(&element->mutex);
mysql_mutex_unlock(&element->mutex);
May miss concurrently inserted transactions.
@ -796,44 +799,44 @@ public:
class thread_safe_trx_ilist_t
{
public:
void create() { mutex_create(LATCH_ID_TRX_SYS, &mutex); }
void close() { mutex_free(&mutex); }
void create() { mysql_mutex_init(trx_sys_mutex_key, &mutex, nullptr); }
void close() { mysql_mutex_destroy(&mutex); }
bool empty() const
{
mutex_enter(&mutex);
mysql_mutex_lock(&mutex);
auto result= trx_list.empty();
mutex_exit(&mutex);
mysql_mutex_unlock(&mutex);
return result;
}
void push_front(trx_t &trx)
{
mutex_enter(&mutex);
mysql_mutex_lock(&mutex);
trx_list.push_front(trx);
mutex_exit(&mutex);
mysql_mutex_unlock(&mutex);
}
void remove(trx_t &trx)
{
mutex_enter(&mutex);
mysql_mutex_lock(&mutex);
trx_list.remove(trx);
mutex_exit(&mutex);
mysql_mutex_unlock(&mutex);
}
template <typename Callable> void for_each(Callable &&callback) const
{
mutex_enter(&mutex);
mysql_mutex_lock(&mutex);
for (const auto &trx : trx_list)
callback(trx);
mutex_exit(&mutex);
mysql_mutex_unlock(&mutex);
}
void freeze() const { mutex_enter(&mutex); }
void unfreeze() const { mutex_exit(&mutex); }
void freeze() const { mysql_mutex_lock(&mutex); }
void unfreeze() const { mysql_mutex_unlock(&mutex); }
private:
alignas(CACHE_LINE_SIZE) mutable TrxSysMutex mutex;
alignas(CACHE_LINE_SIZE) mutable mysql_mutex_t mutex;
alignas(CACHE_LINE_SIZE) ilist<trx_t> trx_list;
};
@ -1148,11 +1151,11 @@ private:
{
if (element->id < *id)
{
mutex_enter(&element->mutex);
mysql_mutex_lock(&element->mutex);
/* We don't care about read-only transactions here. */
if (element->trx && element->trx->rsegs.m_redo.rseg)
*id= element->id;
mutex_exit(&element->mutex);
mysql_mutex_unlock(&element->mutex);
}
return 0;
}
@ -1217,5 +1220,3 @@ private:
/** The transaction system */
extern trx_sys_t trx_sys;
#endif

View file

@ -24,11 +24,9 @@ Transaction system global type definitions
Created 3/26/1996 Heikki Tuuri
*******************************************************/
#ifndef trx0types_h
#define trx0types_h
#include "ut0byte.h"
#include "ut0mutex.h"
#pragma once
#include "univ.i"
#include "ut0new.h"
#include <vector>
@ -135,9 +133,4 @@ typedef byte trx_undo_rec_t;
/* @} */
typedef ib_mutex_t RsegMutex;
typedef ib_mutex_t PQMutex;
typedef ib_mutex_t TrxSysMutex;
typedef std::vector<trx_id_t, ut_allocator<trx_id_t> > trx_ids_t;
#endif /* trx0types_h */

View file

@ -31,8 +31,7 @@ Version control for database, common definitions, and include files
Created 1/20/1994 Heikki Tuuri
****************************************************************************/
#ifndef univ_i
#define univ_i
#pragma once
/* aux macros to convert M into "123" (string) if M is defined like
#define M 123 */
@ -194,8 +193,6 @@ using the call command. */
related stuff. */
#define UNIV_SEARCH_PERF_STAT /* statistics for the
adaptive hash index */
#define UNIV_SRV_PRINT_LATCH_WAITS /* enable diagnostic output
in sync0sync.cc */
#define UNIV_BTR_PRINT /* enable functions for
printing B-trees */
#define UNIV_ZIP_DEBUG /* extensive consistency checks
@ -563,7 +560,6 @@ typedef void* os_thread_ret_t;
#include "ut0dbg.h"
#include "ut0lst.h"
#include "ut0ut.h"
#include "sync0types.h"
extern ulong srv_page_size_shift;
extern ulong srv_page_size;
@ -572,4 +568,53 @@ extern ulong srv_page_size;
myisam/sp_defs.h. We only support 2 dimension data */
#define SPDIMS 2
#endif
#ifdef HAVE_PSI_INTERFACE
typedef unsigned int mysql_pfs_key_t;
# ifdef UNIV_PFS_MUTEX
extern mysql_pfs_key_t buf_pool_mutex_key;
extern mysql_pfs_key_t dict_foreign_err_mutex_key;
extern mysql_pfs_key_t dict_sys_mutex_key;
extern mysql_pfs_key_t fil_system_mutex_key;
extern mysql_pfs_key_t flush_list_mutex_key;
extern mysql_pfs_key_t fts_cache_mutex_key;
extern mysql_pfs_key_t fts_cache_init_mutex_key;
extern mysql_pfs_key_t fts_delete_mutex_key;
extern mysql_pfs_key_t fts_doc_id_mutex_key;
extern mysql_pfs_key_t fts_pll_tokenize_mutex_key;
extern mysql_pfs_key_t ibuf_bitmap_mutex_key;
extern mysql_pfs_key_t ibuf_mutex_key;
extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
extern mysql_pfs_key_t log_sys_mutex_key;
extern mysql_pfs_key_t log_cmdq_mutex_key;
extern mysql_pfs_key_t log_flush_order_mutex_key;
extern mysql_pfs_key_t recalc_pool_mutex_key;
extern mysql_pfs_key_t purge_sys_pq_mutex_key;
extern mysql_pfs_key_t recv_sys_mutex_key;
extern mysql_pfs_key_t rtr_active_mutex_key;
extern mysql_pfs_key_t rtr_match_mutex_key;
extern mysql_pfs_key_t rtr_path_mutex_key;
extern mysql_pfs_key_t page_zip_stat_per_index_mutex_key;
extern mysql_pfs_key_t srv_innodb_monitor_mutex_key;
extern mysql_pfs_key_t srv_misc_tmpfile_mutex_key;
extern mysql_pfs_key_t srv_monitor_file_mutex_key;
extern mysql_pfs_key_t buf_dblwr_mutex_key;
extern mysql_pfs_key_t trx_pool_mutex_key;
extern mysql_pfs_key_t trx_pool_manager_mutex_key;
extern mysql_pfs_key_t lock_mutex_key;
extern mysql_pfs_key_t lock_wait_mutex_key;
extern mysql_pfs_key_t srv_threads_mutex_key;
extern mysql_pfs_key_t thread_mutex_key;
extern mysql_pfs_key_t row_drop_list_mutex_key;
# endif /* UNIV_PFS_MUTEX */
# ifdef UNIV_PFS_RWLOCK
extern mysql_pfs_key_t dict_operation_lock_key;
extern mysql_pfs_key_t fil_space_latch_key;
extern mysql_pfs_key_t trx_i_s_cache_lock_key;
extern mysql_pfs_key_t trx_purge_latch_key;
extern mysql_pfs_key_t index_tree_rw_lock_key;
extern mysql_pfs_key_t index_online_log_key;
extern mysql_pfs_key_t trx_sys_rw_lock_key;
# endif /* UNIV_PFS_RWLOCK */
#endif /* HAVE_PSI_INTERFACE */

View file

@ -1,174 +0,0 @@
/*****************************************************************************
Copyright (c) 2012, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/******************************************************************//**
@file include/ut0mutex.h
Policy based mutexes.
Created 2012-03-24 Sunny Bains.
***********************************************************************/
#pragma once
#ifndef UNIV_INNOCHECKSUM
#include "sync0policy.h"
#include "ib0mutex.h"
/** Create a typedef using the MutexType<PolicyType>
@param[in] M Mutex type
@param[in[ P Policy type
@param[in] T The resulting typedef alias */
#define UT_MUTEX_TYPE(M, P, T) typedef PolicyMutex<M<P> > T;
# ifdef __linux__
UT_MUTEX_TYPE(TTASFutexMutex, GenericPolicy, FutexMutex);
# endif /* __linux__ */
UT_MUTEX_TYPE(TTASMutex, GenericPolicy, SpinMutex);
UT_MUTEX_TYPE(OSTrackMutex, GenericPolicy, SysMutex);
#ifdef MUTEX_FUTEX
/** The default mutex type. */
typedef FutexMutex ib_mutex_t;
#define MUTEX_TYPE "Uses futexes"
#elif defined(MUTEX_SYS)
typedef SysMutex ib_mutex_t;
#define MUTEX_TYPE "Uses system mutexes"
#else
#error "ib_mutex_t type is unknown"
#endif /* MUTEX_FUTEX */
extern uint srv_spin_wait_delay;
extern ulong srv_n_spin_wait_rounds;
#define mutex_create(I, M) mutex_init((M), (I), \
__FILE__, __LINE__)
#define mutex_enter_loc(M,file,line) (M)->enter( \
uint32_t(srv_n_spin_wait_rounds), \
uint32_t(srv_spin_wait_delay), \
file, line)
#define mutex_enter(M) mutex_enter_loc(M, __FILE__, __LINE__)
#define mutex_enter_nospin(M) (M)->enter( \
0, \
0, \
__FILE__, uint32_t(__LINE__))
#define mutex_enter_nowait(M) (M)->trylock(__FILE__, \
uint32_t(__LINE__))
#define mutex_exit(M) (M)->exit()
#define mutex_free(M) mutex_destroy(M)
#ifdef UNIV_DEBUG
/**
Checks that the mutex has been initialized. */
#define mutex_validate(M) (M)->validate()
/**
Checks that the current thread owns the mutex. Works only
in the debug version. */
#define mutex_own(M) (M)->is_owned()
#else
#define mutex_own(M) /* No op */
#define mutex_validate(M) /* No op */
#endif /* UNIV_DEBUG */
/** Iterate over the mutex meta data */
class MutexMonitor {
public:
/** Constructor */
MutexMonitor() { }
/** Destructor */
~MutexMonitor() { }
/** Enable the mutex monitoring */
void enable();
/** Disable the mutex monitoring */
void disable();
/** Reset the mutex monitoring values */
void reset();
/** Invoke the callback for each active mutex collection
@param[in,out] callback Functor to call
@return false if callback returned false */
template<typename Callback>
bool iterate(Callback& callback) const
UNIV_NOTHROW
{
LatchMetaData::iterator end = latch_meta.end();
for (LatchMetaData::iterator it = latch_meta.begin();
it != end;
++it) {
/* Some of the slots will be null in non-debug mode */
if (latch_meta_t* l= *it) {
if (!callback(*l)) {
return false;
}
}
}
return(true);
}
};
/** Defined in sync0sync.cc */
extern MutexMonitor mutex_monitor;
/**
Creates, or rather, initializes a mutex object in a specified memory
location (which must be appropriately aligned). The mutex is initialized
in the reset state. Explicit freeing of the mutex with mutex_free is
necessary only if the memory block containing it is freed.
Add the mutex instance to the global mutex list.
@param[in,out] mutex mutex to initialise
@param[in] id The mutex ID (Latch ID)
@param[in] filename Filename from where it was called
@param[in] line Line number in filename from where called */
template <typename Mutex>
void mutex_init(
Mutex* mutex,
latch_id_t id,
const char* file_name,
uint32_t line)
{
new(mutex) Mutex();
mutex->init(id, file_name, line);
}
/**
Removes a mutex instance from the mutex list. The mutex is checked to
be in the reset state.
@param[in,out] mutex mutex instance to destroy */
template <typename Mutex>
void mutex_destroy(
Mutex* mutex)
{
mutex->destroy();
}
#endif /* UNIV_INNOCHECKSUM */

View file

@ -878,9 +878,6 @@ constexpr const char* const auto_event_names[] =
"row0mysql",
"row0sel",
"srv0start",
"sync0debug",
"sync0start",
"sync0types",
"trx0i_s",
"trx0i_s",
"trx0roll",

View file

@ -33,7 +33,6 @@ processing.
#pragma once
#include "ut0list.h"
#include "ut0mutex.h"
#include "mem0mem.h"
// Forward declaration

View file

@ -137,14 +137,6 @@ IF(HAVE_C99_INITIALIZERS)
ADD_DEFINITIONS(-DHAVE_C99_INITIALIZERS)
ENDIF()
SET(MUTEXTYPE "sys" CACHE STRING "Mutex type: sys or futex")
IF(MUTEXTYPE MATCHES "futex" AND DEFINED HAVE_IB_LINUX_FUTEX)
ADD_DEFINITIONS(-DMUTEX_FUTEX)
ELSE()
ADD_DEFINITIONS(-DMUTEX_SYS)
ENDIF()
OPTION(WITH_INNODB_DISALLOW_WRITES "InnoDB freeze writes patch from Google" ${WITH_WSREP})
IF (WITH_INNODB_DISALLOW_WRITES)
ADD_DEFINITIONS(-DWITH_INNODB_DISALLOW_WRITES)

View file

@ -49,7 +49,7 @@ lock_queue_iterator_reset(
ulint bit_no) /*!< in: record number in the
heap */
{
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
iter->current_lock = lock;
@ -84,7 +84,7 @@ lock_queue_iterator_get_prev(
{
const lock_t* prev_lock;
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
switch (lock_get_type_low(iter->current_lock)) {
case LOCK_REC:

File diff suppressed because it is too large Load diff

View file

@ -237,7 +237,7 @@ lock_prdt_has_lock(
{
lock_t* lock;
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
ut_ad((precise_mode & LOCK_MODE_MASK) == LOCK_S
|| (precise_mode & LOCK_MODE_MASK) == LOCK_X);
ut_ad(!(precise_mode & LOCK_INSERT_INTENTION));
@ -295,7 +295,7 @@ lock_prdt_other_has_conflicting(
the new lock will be on */
const trx_t* trx) /*!< in: our transaction */
{
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
for (lock_t* lock = lock_rec_get_first(
lock_hash_get(mode), block, PRDT_HEAPNO);
@ -392,7 +392,7 @@ lock_prdt_find_on_page(
{
lock_t* lock;
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
for (lock = lock_sys.get_first(*lock_hash_get(type_mode),
block->page.id());
@ -437,7 +437,7 @@ lock_prdt_add_to_queue(
/*!< in: TRUE if caller owns the
transaction mutex */
{
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
ut_ad(!dict_index_is_clust(index) && !dict_index_is_online_ddl(index));
ut_ad(type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE));
@ -531,7 +531,7 @@ lock_prdt_insert_check_and_lock(
trx_t* trx = thr_get_trx(thr);
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
/* Because this code is invoked for a running transaction by
the thread that is serving the transaction, it is not necessary
@ -545,7 +545,7 @@ lock_prdt_insert_check_and_lock(
lock = lock_rec_get_first(&lock_sys.prdt_hash, block, PRDT_HEAPNO);
if (lock == NULL) {
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
/* Update the page max trx id field */
page_update_max_trx_id(block, buf_block_get_page_zip(block),
@ -591,7 +591,7 @@ lock_prdt_insert_check_and_lock(
err = DB_SUCCESS;
}
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
switch (err) {
case DB_SUCCESS_LOCKED_REC:
@ -622,7 +622,7 @@ lock_prdt_update_parent(
lock_prdt_t* right_prdt, /*!< in: MBR on the new page */
const page_id_t page_id) /*!< in: parent page */
{
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
/* Get all locks in parent */
for (lock_t *lock = lock_sys.get_first_prdt(page_id);
@ -660,7 +660,7 @@ lock_prdt_update_parent(
}
}
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
}
/**************************************************************//**
@ -728,7 +728,7 @@ lock_prdt_update_split(
lock_prdt_t* new_prdt, /*!< in: MBR on the new page */
const page_id_t page_id) /*!< in: page number */
{
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
lock_prdt_update_split_low(new_block, prdt, new_prdt,
page_id, LOCK_PREDICATE);
@ -736,7 +736,7 @@ lock_prdt_update_split(
lock_prdt_update_split_low(new_block, NULL, NULL,
page_id, LOCK_PRDT_PAGE);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
}
/*********************************************************************//**
@ -801,7 +801,7 @@ lock_prdt_lock(
index record, and this would not have been possible if another active
transaction had modified this secondary index record. */
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
const unsigned prdt_mode = type_mode | mode;
lock_t* lock = lock_sys.get_first(hash, block->page.id());
@ -867,7 +867,7 @@ lock_prdt_lock(
}
}
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
if (status == LOCK_REC_SUCCESS_CREATED && type_mode == LOCK_PREDICATE) {
/* Append the predicate in the lock record */
@ -897,7 +897,7 @@ lock_place_prdt_page_lock(
index record, and this would not have been possible if another active
transaction had modified this secondary index record. */
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
const lock_t* lock = lock_sys.get_first_prdt_page(page_id);
const ulint mode = LOCK_S | LOCK_PRDT_PAGE;
@ -927,7 +927,7 @@ lock_place_prdt_page_lock(
#endif /* PRDT_DIAG */
}
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
return(DB_SUCCESS);
}
@ -940,11 +940,11 @@ bool lock_test_prdt_page_lock(const trx_t *trx, const page_id_t page_id)
{
lock_t* lock;
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
lock = lock_sys.get_first_prdt_page(page_id);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
return(!lock || trx == lock->trx);
}
@ -960,7 +960,7 @@ lock_prdt_rec_move(
const buf_block_t* donator) /*!< in: buffer block containing
the donating record */
{
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
for (lock_t *lock = lock_rec_get_first(&lock_sys.prdt_hash,
donator, PRDT_HEAPNO);
@ -978,7 +978,7 @@ lock_prdt_rec_move(
lock_prdt, FALSE);
}
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
}
/** Removes predicate lock objects set on an index page which is discarded.
@ -992,7 +992,7 @@ lock_prdt_page_free_from_discard(
lock_t* lock;
lock_t* next_lock;
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
lock = lock_sys.get_first(*lock_hash, block->page.id());

View file

@ -92,13 +92,13 @@ lock_wait_table_release_slot(
trx_t::mutex. To reduce contention on the lock mutex when reserving the
slot we avoid acquiring the lock mutex. */
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
slot->thr->slot = NULL;
slot->thr = NULL;
slot->in_use = FALSE;
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
/* Scan backwards and adjust the last free slot pointer. */
for (slot = lock_sys.last_slot;
@ -190,15 +190,15 @@ wsrep_is_BF_lock_timeout(
ib::info() << "WSREP: BF lock wait long for trx:" << ib::hex(trx->id)
<< " query: " << wsrep_thd_query(trx->mysql_thd);
if (!locked) {
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
}
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
trx_print_latched(stderr, trx, 3000);
if (!locked) {
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
}
srv_print_innodb_monitor = TRUE;
@ -284,12 +284,12 @@ lock_wait_suspend_thread(
current thread which owns the transaction. Only acquire the
mutex if the wait_lock is still active. */
if (const lock_t* wait_lock = trx->lock.wait_lock) {
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
wait_lock = trx->lock.wait_lock;
if (wait_lock) {
lock_type = lock_get_type_low(wait_lock);
}
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
}
ulint had_dict_lock = trx->dict_operation_lock_mode;
@ -325,11 +325,9 @@ lock_wait_suspend_thread(
thd_wait_begin(trx->mysql_thd, THD_WAIT_TABLE_LOCK);
}
mysql_mutex_lock(&lock_sys.mutex);
while (trx->lock.wait_lock) {
mysql_cond_wait(&slot->cond, &lock_sys.mutex);
}
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_lock();
lock_sys.wait_lock(&trx->lock.wait_lock, &slot->cond);
lock_sys.mutex_unlock();
thd_wait_end(trx->mysql_thd);
@ -403,7 +401,7 @@ lock_wait_release_thread_if_suspended(
que_thr_t* thr) /*!< in: query thread associated with the
user OS thread */
{
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
/* We own both the lock mutex and the trx_t::mutex but not the
lock wait mutex. This is OK because other threads will see the state
@ -451,7 +449,7 @@ lock_wait_check_and_cancel(
possible that the lock has already been
granted: in that case do nothing */
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
if (trx->lock.wait_lock != NULL) {
ut_a(trx->lock.que_state == TRX_QUE_LOCK_WAIT);
@ -467,7 +465,7 @@ lock_wait_check_and_cancel(
#endif /* WITH_WSREP */
}
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
}
}

View file

@ -50,7 +50,6 @@ Created 12/9/1995 Heikki Tuuri
#include "trx0trx.h"
#include "trx0roll.h"
#include "srv0mon.h"
#include "sync0sync.h"
#include "buf0dump.h"
#include "log0sync.h"

View file

@ -54,7 +54,6 @@ Created 9/20/1997 Heikki Tuuri
#include "buf0rea.h"
#include "srv0srv.h"
#include "srv0start.h"
#include "sync0sync.h"
#include "fil0pagecompress.h"
/** Read-ahead area in applying log records to file pages */

View file

@ -42,6 +42,7 @@ Created 10/21/1995 Heikki Tuuri
# include <sys/stat.h>
#endif
#include "srv0mon.h"
#include "srv0srv.h"
#include "srv0start.h"
#include "fil0fil.h"
@ -4477,7 +4478,7 @@ void fil_node_t::find_metadata(os_file_t file
@return whether the page was found valid */
bool fil_node_t::read_page0()
{
ut_ad(mutex_own(&fil_system.mutex));
mysql_mutex_assert_owner(&fil_system.mutex);
const unsigned psize = space->physical_size();
#ifndef _WIN32
struct stat statbuf;

View file

@ -1358,9 +1358,9 @@ page_zip_compress(
#endif /* PAGE_ZIP_COMPRESS_DBG */
page_zip_stat[page_zip->ssize - 1].compressed++;
if (cmp_per_index_enabled) {
mutex_enter(&page_zip_stat_per_index_mutex);
mysql_mutex_lock(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index[ind_id].compressed++;
mutex_exit(&page_zip_stat_per_index_mutex);
mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
}
if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE
@ -1538,10 +1538,10 @@ err_exit:
page_zip_stat[page_zip->ssize - 1].compressed_usec
+= time_diff;
if (cmp_per_index_enabled) {
mutex_enter(&page_zip_stat_per_index_mutex);
mysql_mutex_lock(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index[ind_id].compressed_usec
+= time_diff;
mutex_exit(&page_zip_stat_per_index_mutex);
mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
}
return false;
}
@ -1605,10 +1605,10 @@ err_exit:
page_zip_stat[page_zip->ssize - 1].compressed_ok++;
page_zip_stat[page_zip->ssize - 1].compressed_usec += time_diff;
if (cmp_per_index_enabled) {
mutex_enter(&page_zip_stat_per_index_mutex);
mysql_mutex_lock(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index[ind_id].compressed_ok++;
page_zip_stat_per_index[ind_id].compressed_usec += time_diff;
mutex_exit(&page_zip_stat_per_index_mutex);
mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
}
if (page_is_leaf(page)) {
@ -3244,10 +3244,10 @@ page_zip_decompress(
index_id_t index_id = btr_page_get_index_id(page);
if (srv_cmp_per_index_enabled) {
mutex_enter(&page_zip_stat_per_index_mutex);
mysql_mutex_lock(&page_zip_stat_per_index_mutex);
page_zip_stat_per_index[index_id].decompressed++;
page_zip_stat_per_index[index_id].decompressed_usec += time_diff;
mutex_exit(&page_zip_stat_per_index_mutex);
mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
}
/* Update the stat counter for LRU policy. */

View file

@ -1987,7 +1987,7 @@ pars_sql(
heap = mem_heap_create(16000);
/* Currently, the parser is not reentrant: */
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
pars_sym_tab_global = sym_tab_create(heap);

View file

@ -67,7 +67,7 @@ sym_tab_free_private(
sym_node_t* sym;
func_node_t* func;
ut_ad(mutex_own(&dict_sys.mutex));
dict_sys.assert_locked();
for (sym = UT_LIST_GET_FIRST(sym_tab->sym_list);
sym != NULL;

View file

@ -182,7 +182,7 @@ que_thr_end_lock_wait(
{
que_thr_t* thr;
mysql_mutex_assert_owner(&lock_sys.mutex);
lock_sys.mutex_assert_locked();
thr = trx->lock.wait_thr;
@ -1085,13 +1085,13 @@ que_eval_sql(
ut_a(trx->error_state == DB_SUCCESS);
if (reserve_dict_mutex) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
graph = pars_sql(info, sql);
if (reserve_dict_mutex) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
graph->trx = trx;
@ -1104,13 +1104,13 @@ que_eval_sql(
que_run_threads(thr);
if (reserve_dict_mutex) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
que_graph_free(graph);
if (reserve_dict_mutex) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
DBUG_RETURN(trx->error_state);

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, 2019, MariaDB Corporation.
Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -226,10 +226,10 @@ void ReadView::open(trx_t *trx)
m_open.store(true, std::memory_order_relaxed);
else
{
mutex_enter(&m_mutex);
mysql_mutex_lock(&m_mutex);
snapshot(trx);
m_open.store(true, std::memory_order_relaxed);
mutex_exit(&m_mutex);
mysql_mutex_unlock(&m_mutex);
}
}
}

View file

@ -31,7 +31,6 @@ Created 10/13/2010 Jimmy Yang
#include "btr0cur.h"
#include "fts0plugin.h"
#include "log0crypt.h"
#include "sync0sync.h"
/** Read the next record to buffer N.
@param N index into array of merge info structure */

View file

@ -1411,7 +1411,7 @@ row_import::set_root_by_heuristic() UNIV_NOTHROW
" the tablespace has " << m_n_indexes << " indexes";
}
dict_mutex_enter_for_mysql();
dict_sys.mutex_lock();
ulint i = 0;
dberr_t err = DB_SUCCESS;
@ -1452,7 +1452,7 @@ row_import::set_root_by_heuristic() UNIV_NOTHROW
}
}
dict_mutex_exit_for_mysql();
dict_sys.mutex_unlock();
return(err);
}

View file

@ -671,7 +671,7 @@ row_ins_set_detailed(
{
ut_ad(!srv_read_only_mode);
mutex_enter(&srv_misc_tmpfile_mutex);
mysql_mutex_lock(&srv_misc_tmpfile_mutex);
rewind(srv_misc_tmpfile);
if (os_file_set_eof(srv_misc_tmpfile)) {
@ -685,7 +685,7 @@ row_ins_set_detailed(
trx_set_detailed_error(trx, "temp file operation failed");
}
mutex_exit(&srv_misc_tmpfile_mutex);
mysql_mutex_unlock(&srv_misc_tmpfile_mutex);
}
/*********************************************************************//**
@ -704,13 +704,13 @@ row_ins_foreign_trx_print(
ut_ad(!srv_read_only_mode);
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
n_rec_locks = lock_number_of_rows_locked(&trx->lock);
n_trx_locks = UT_LIST_GET_LEN(trx->lock.trx_locks);
heap_size = mem_heap_get_size(trx->lock.lock_heap);
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
mutex_enter(&dict_foreign_err_mutex);
mysql_mutex_lock(&dict_foreign_err_mutex);
rewind(dict_foreign_err_file);
ut_print_timestamp(dict_foreign_err_file);
fputs(" Transaction:\n", dict_foreign_err_file);
@ -718,7 +718,7 @@ row_ins_foreign_trx_print(
trx_print_low(dict_foreign_err_file, trx, 600,
n_rec_locks, n_trx_locks, heap_size);
ut_ad(mutex_own(&dict_foreign_err_mutex));
mysql_mutex_assert_owner(&dict_foreign_err_mutex);
}
/*********************************************************************//**
@ -776,7 +776,7 @@ row_ins_foreign_report_err(
}
putc('\n', ef);
mutex_exit(&dict_foreign_err_mutex);
mysql_mutex_unlock(&dict_foreign_err_mutex);
}
/*********************************************************************//**
@ -842,7 +842,7 @@ row_ins_foreign_report_add_err(
}
putc('\n', ef);
mutex_exit(&dict_foreign_err_mutex);
mysql_mutex_unlock(&dict_foreign_err_mutex);
}
/*********************************************************************//**
@ -1598,7 +1598,7 @@ row_ins_check_foreign_constraint(
err = DB_ROW_IS_REFERENCED;
}
mutex_exit(&dict_foreign_err_mutex);
mysql_mutex_unlock(&dict_foreign_err_mutex);
goto exit_func;
}
@ -3009,9 +3009,9 @@ row_ins_sec_index_entry_low(
if (!index->is_committed()) {
ut_ad(!thr_get_trx(thr)
->dict_operation_lock_mode);
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_set_corrupted_index_cache_only(index);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
/* Do not return any error to the
caller. The duplicate will be reported
by ALTER TABLE or CREATE UNIQUE INDEX.

View file

@ -172,7 +172,7 @@ directly. When also head.bytes == tail.bytes, both counts will be
reset to 0 and the file will be truncated. */
struct row_log_t {
pfs_os_file_t fd; /*!< file descriptor */
ib_mutex_t mutex; /*!< mutex protecting error,
mysql_mutex_t mutex; /*!< mutex protecting error,
max_trx and tail */
page_no_map* blobs; /*!< map of page numbers of off-page columns
that have been freed during table-rebuilding
@ -363,7 +363,7 @@ row_log_online_op(
+ (trx_id ? DATA_TRX_ID_LEN : 0);
log = index->online_log;
mutex_enter(&log->mutex);
mysql_mutex_lock(&log->mutex);
if (trx_id > log->max_trx) {
log->max_trx = trx_id;
@ -471,7 +471,7 @@ write_failed:
MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
err_exit:
mutex_exit(&log->mutex);
mysql_mutex_unlock(&log->mutex);
}
/******************************************************//**
@ -499,13 +499,13 @@ row_log_table_open(
ulint size, /*!< in: size of log record */
ulint* avail) /*!< out: available size for log record */
{
mutex_enter(&log->mutex);
mysql_mutex_lock(&log->mutex);
MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
if (log->error != DB_SUCCESS) {
err_exit:
mutex_exit(&log->mutex);
mysql_mutex_unlock(&log->mutex);
return(NULL);
}
@ -541,7 +541,7 @@ row_log_table_close_func(
{
row_log_t* log = index->online_log;
ut_ad(mutex_own(&log->mutex));
mysql_mutex_assert_owner(&log->mutex);
if (size >= avail) {
const os_offset_t byte_offset
@ -605,7 +605,7 @@ write_failed:
log->tail.total += size;
MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
err_exit:
mutex_exit(&log->mutex);
mysql_mutex_unlock(&log->mutex);
onlineddl_rowlog_rows++;
/* 10000 means 100.00%, 4525 means 45.25% */
@ -1272,7 +1272,7 @@ row_log_table_get_pk(
return(NULL);
}
mutex_enter(&log->mutex);
mysql_mutex_lock(&log->mutex);
/* log->error is protected by log->mutex. */
if (log->error == DB_SUCCESS) {
@ -1411,7 +1411,7 @@ err_exit:
}
func_exit:
mutex_exit(&log->mutex);
mysql_mutex_unlock(&log->mutex);
return(tuple);
}
@ -3187,7 +3187,7 @@ row_log_allocate(
}
log->fd = OS_FILE_CLOSED;
mutex_create(LATCH_ID_INDEX_ONLINE_LOG, &log->mutex);
mysql_mutex_init(index_online_log_key, &log->mutex, nullptr);
log->blobs = NULL;
log->table = table;
@ -3270,7 +3270,7 @@ row_log_free(
my_large_free(log->crypt_tail, log->crypt_tail_size);
}
mutex_free(&log->mutex);
mysql_mutex_destroy(&log->mutex);
ut_free(log);
}
@ -3284,9 +3284,11 @@ row_log_get_max_trx(
dict_index_t* index) /*!< in: index, must be locked */
{
ut_ad(dict_index_get_online_status(index) == ONLINE_INDEX_CREATION);
#ifdef SAFE_MUTEX
ut_ad(index->lock.have_x()
|| (index->lock.have_s()
&& mutex_own(&index->online_log->mutex)));
&& mysql_mutex_is_owner(&index->online_log->mutex)));
#endif
return(index->online_log->max_trx);
}

View file

@ -51,6 +51,7 @@ Completed by Sunny Bains and Marko Makela
#endif /* BTR_CUR_ADAPT */
#include "ut0stage.h"
#include "fil0crypt.h"
#include "srv0mon.h"
/* Ignore posix_fadvise() on those platforms where it does not exist */
#if defined _WIN32
@ -3602,7 +3603,6 @@ row_merge_insert_index_tuples(
}
ut_ad(dtuple_validate(dtuple));
ut_ad(!sync_check_iterate(sync_check()));
error = btr_bulk->insert(dtuple);
if (error != DB_SUCCESS) {

View file

@ -61,8 +61,7 @@ Created 9/17/2000 Heikki Tuuri
#include "trx0rec.h"
#include "trx0roll.h"
#include "trx0undo.h"
#include "srv0start.h"
#include "row0ext.h"
#include "srv0mon.h"
#include "srv0start.h"
#include <algorithm>
@ -94,7 +93,7 @@ more. Protected by row_drop_list_mutex. */
static UT_LIST_BASE_NODE_T(row_mysql_drop_t) row_mysql_drop_list;
/** Mutex protecting the background table drop list. */
static ib_mutex_t row_drop_list_mutex;
static mysql_mutex_t row_drop_list_mutex;
/** Flag: has row_mysql_drop_list been initialized? */
static bool row_mysql_drop_list_inited;
@ -125,9 +124,9 @@ row_wait_for_background_drop_list_empty()
{
bool empty = false;
while (!empty) {
mutex_enter(&row_drop_list_mutex);
mysql_mutex_lock(&row_drop_list_mutex);
empty = (UT_LIST_GET_LEN(row_mysql_drop_list) == 0);
mutex_exit(&row_drop_list_mutex);
mysql_mutex_unlock(&row_drop_list_mutex);
os_thread_sleep(100000);
}
}
@ -2259,12 +2258,14 @@ data dictionary modification operation. */
void
row_mysql_lock_data_dictionary_func(
/*================================*/
trx_t* trx, /*!< in/out: transaction */
#ifdef UNIV_PFS_RWLOCK
const char* file, /*!< in: file name */
unsigned line) /*!< in: line number */
unsigned line, /*!< in: line number */
#endif
trx_t* trx) /*!< in/out: transaction */
{
ut_ad(trx->dict_operation_lock_mode == 0);
dict_sys.lock(file, line);
dict_sys.lock(SRW_LOCK_ARGS(file, line));
trx->dict_operation_lock_mode = RW_X_LATCH;
}
@ -2560,7 +2561,7 @@ row_drop_tables_for_mysql_in_background(void)
ulint n_tables;
ulint n_tables_dropped = 0;
loop:
mutex_enter(&row_drop_list_mutex);
mysql_mutex_lock(&row_drop_list_mutex);
ut_a(row_mysql_drop_list_inited);
next:
@ -2568,7 +2569,7 @@ next:
n_tables = UT_LIST_GET_LEN(row_mysql_drop_list);
mutex_exit(&row_drop_list_mutex);
mysql_mutex_unlock(&row_drop_list_mutex);
if (drop == NULL) {
/* All tables dropped */
@ -2584,7 +2585,7 @@ next:
if (!table) {
n_tables_dropped++;
mutex_enter(&row_drop_list_mutex);
mysql_mutex_lock(&row_drop_list_mutex);
UT_LIST_REMOVE(row_mysql_drop_list, drop);
MONITOR_DEC(MONITOR_BACKGROUND_DROP_TABLE);
ut_free(drop);
@ -2599,7 +2600,7 @@ next:
skip:
dict_table_close(table, FALSE, FALSE);
mutex_enter(&row_drop_list_mutex);
mysql_mutex_lock(&row_drop_list_mutex);
UT_LIST_REMOVE(row_mysql_drop_list, drop);
if (!skip) {
UT_LIST_ADD_LAST(row_mysql_drop_list, drop);
@ -2610,9 +2611,9 @@ skip:
}
if (!srv_fast_shutdown && !trx_sys.any_active_transactions()) {
mysql_mutex_lock(&lock_sys.mutex);
lock_sys.mutex_lock();
skip = UT_LIST_GET_LEN(table->locks) != 0;
mysql_mutex_unlock(&lock_sys.mutex);
lock_sys.mutex_unlock();
if (skip) {
/* We cannot drop tables that are locked by XA
PREPARE transactions. */
@ -2647,13 +2648,13 @@ row_get_background_drop_list_len_low(void)
{
ulint len;
mutex_enter(&row_drop_list_mutex);
mysql_mutex_lock(&row_drop_list_mutex);
ut_a(row_mysql_drop_list_inited);
len = UT_LIST_GET_LEN(row_mysql_drop_list);
mutex_exit(&row_drop_list_mutex);
mysql_mutex_unlock(&row_drop_list_mutex);
return(len);
}
@ -2743,7 +2744,7 @@ row_add_table_to_background_drop_list(table_id_t table_id)
row_mysql_drop_t* drop;
bool added = true;
mutex_enter(&row_drop_list_mutex);
mysql_mutex_lock(&row_drop_list_mutex);
ut_a(row_mysql_drop_list_inited);
@ -2765,7 +2766,7 @@ row_add_table_to_background_drop_list(table_id_t table_id)
MONITOR_INC(MONITOR_BACKGROUND_DROP_TABLE);
func_exit:
mutex_exit(&row_drop_list_mutex);
mysql_mutex_unlock(&row_drop_list_mutex);
return added;
}
@ -2881,7 +2882,7 @@ row_discard_tablespace_foreign_key_checks(
/* We only allow discarding a referenced table if
FOREIGN_KEY_CHECKS is set to 0 */
mutex_enter(&dict_foreign_err_mutex);
mysql_mutex_lock(&dict_foreign_err_mutex);
rewind(ef);
@ -2894,7 +2895,7 @@ row_discard_tablespace_foreign_key_checks(
ut_print_name(ef, trx, foreign->foreign_table_name);
putc('\n', ef);
mutex_exit(&dict_foreign_err_mutex);
mysql_mutex_unlock(&dict_foreign_err_mutex);
return(DB_CANNOT_DROP_CONSTRAINT);
}
@ -3416,7 +3417,7 @@ row_drop_table_for_mysql(
err = DB_CANNOT_DROP_CONSTRAINT;
mutex_enter(&dict_foreign_err_mutex);
mysql_mutex_lock(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
@ -3427,7 +3428,7 @@ row_drop_table_for_mysql(
ut_print_name(ef, trx,
foreign->foreign_table_name);
putc('\n', ef);
mutex_exit(&dict_foreign_err_mutex);
mysql_mutex_unlock(&dict_foreign_err_mutex);
goto funct_exit;
}
@ -3938,9 +3939,9 @@ loop:
dict_table_close(table, TRUE, FALSE);
/* The dict_table_t object must not be accessed before
dict_table_open() or after dict_table_close(). But this is OK
if we are holding, the dict_sys.mutex. */
ut_ad(mutex_own(&dict_sys.mutex));
dict_table_open() or after dict_table_close() while
not holding dict_sys.mutex. */
dict_sys.assert_locked();
/* Disable statistics on the found table. */
if (!dict_stats_stop_bg(table)) {
@ -4737,19 +4738,12 @@ not_ok:
goto loop;
}
/*********************************************************************//**
Initialize this module */
void
row_mysql_init(void)
/*================*/
/** Initialize this module */
void row_mysql_init()
{
mutex_create(LATCH_ID_ROW_DROP_LIST, &row_drop_list_mutex);
UT_LIST_INIT(
row_mysql_drop_list,
&row_mysql_drop_t::row_mysql_drop_list);
row_mysql_drop_list_inited = true;
mysql_mutex_init(row_drop_list_mutex_key, &row_drop_list_mutex, nullptr);
UT_LIST_INIT(row_mysql_drop_list, &row_mysql_drop_t::row_mysql_drop_list);
row_mysql_drop_list_inited= true;
}
void row_mysql_close()
@ -4759,7 +4753,7 @@ void row_mysql_close()
if (row_mysql_drop_list_inited)
{
row_mysql_drop_list_inited= false;
mutex_free(&row_drop_list_mutex);
mysql_mutex_destroy(&row_drop_list_mutex);
while (row_mysql_drop_t *drop= UT_LIST_GET_FIRST(row_mysql_drop_list))
{

View file

@ -486,7 +486,7 @@ row_quiesce_table_has_fts_index(
{
bool exists = false;
dict_mutex_enter_for_mysql();
dict_sys.mutex_lock();
for (const dict_index_t* index = UT_LIST_GET_FIRST(table->indexes);
index != 0;
@ -498,7 +498,7 @@ row_quiesce_table_has_fts_index(
}
}
dict_mutex_exit_for_mysql();
dict_sys.mutex_unlock();
return(exists);
}

View file

@ -1098,13 +1098,13 @@ re_scan:
thr->lock_state = QUE_THR_LOCK_NOLOCK;
mtr->start();
mutex_enter(&match->rtr_match_mutex);
mysql_mutex_lock(&match->rtr_match_mutex);
if (!match->valid && match->matched_recs->empty()) {
mutex_exit(&match->rtr_match_mutex);
mysql_mutex_unlock(&match->rtr_match_mutex);
err = DB_RECORD_NOT_FOUND;
goto func_end;
}
mutex_exit(&match->rtr_match_mutex);
mysql_mutex_unlock(&match->rtr_match_mutex);
/* MDEV-14059 FIXME: why re-latch the block?
pcur is already positioned on it! */
@ -2164,7 +2164,6 @@ stop_for_a_while:
btr_pcur_store_position(&(plan->pcur), &mtr);
mtr.commit();
ut_ad(!sync_check_iterate(sync_check()));
err = DB_SUCCESS;
goto func_exit;
@ -2181,7 +2180,6 @@ commit_mtr_for_a_while:
mtr.commit();
mtr_has_extra_clust_latch = FALSE;
ut_ad(!sync_check_iterate(dict_sync_check()));
goto table_loop;
@ -2196,8 +2194,6 @@ lock_wait_or_error:
mtr.commit();
func_exit:
ut_ad(!sync_check_iterate(dict_sync_check()));
if (heap != NULL) {
mem_heap_free(heap);
}
@ -3292,16 +3288,16 @@ Row_sel_get_clust_rec_for_mysql::operator()(
|| rec != btr_pcur_get_rec(prebuilt->pcur))) {
#ifdef UNIV_DEBUG
rtr_info_t* rtr_info = btr_cur->rtr_info;
mutex_enter(&rtr_info->matches->rtr_match_mutex);
mysql_mutex_lock(&rtr_info->matches->rtr_match_mutex);
/* The page could be deallocated (by rollback etc.) */
if (!rtr_info->matches->valid) {
mutex_exit(&rtr_info->matches->rtr_match_mutex);
mysql_mutex_unlock(&rtr_info->matches->rtr_match_mutex);
clust_rec = NULL;
err = DB_SUCCESS;
goto func_exit;
}
mutex_exit(&rtr_info->matches->rtr_match_mutex);
mysql_mutex_unlock(&rtr_info->matches->rtr_match_mutex);
if (rec_get_deleted_flag(rec,
dict_table_is_comp(sec_index->table))
@ -4263,8 +4259,6 @@ row_search_mvcc(
DBUG_RETURN(DB_END_OF_INDEX);
}
ut_ad(!sync_check_iterate(sync_check()));
if (!prebuilt->table->space) {
DBUG_RETURN(DB_TABLESPACE_DELETED);
} else if (!prebuilt->table->is_readable()) {
@ -4496,7 +4490,6 @@ aborted:
/* NOTE that we do NOT store the cursor
position */
trx->op_info = "";
ut_ad(!sync_check_iterate(sync_check()));
ut_ad(!did_semi_consistent_read);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
@ -5786,8 +5779,6 @@ func_exit:
}
}
ut_ad(!sync_check_iterate(sync_check()));
DEBUG_SYNC_C("innodb_row_search_for_mysql_exit");
DBUG_RETURN(err);

View file

@ -367,9 +367,9 @@ static bool row_undo_ins_parse_undo_rec(undo_node_t* node, bool dict_locked)
node->table = dict_table_open_on_id(table_id, dict_locked,
DICT_TABLE_OP_NORMAL);
} else if (!dict_locked) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
node->table = dict_sys.get_temporary_table(table_id);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
} else {
node->table = dict_sys.get_temporary_table(table_id);
}
@ -563,11 +563,11 @@ row_undo_ins(
if (node->table->id == DICT_INDEXES_ID) {
ut_ad(!node->table->is_temporary());
if (!dict_locked) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
}
err = row_undo_ins_remove_clust_rec(node);
if (!dict_locked) {
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
}
} else {
err = row_undo_ins_remove_clust_rec(node);

View file

@ -912,9 +912,9 @@ row_undo_mod_sec_flag_corrupted(
on the data dictionary during normal rollback,
we can only mark the index corrupted in the
data dictionary cache. TODO: fix this somehow.*/
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
dict_set_corrupted_index_cache_only(index);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
break;
default:
ut_ad(0);
@ -1230,9 +1230,9 @@ static bool row_undo_mod_parse_undo_rec(undo_node_t* node, bool dict_locked)
node->table = dict_table_open_on_id(table_id, dict_locked,
DICT_TABLE_OP_NORMAL);
} else if (!dict_locked) {
mutex_enter(&dict_sys.mutex);
dict_sys.mutex_lock();
node->table = dict_sys.get_temporary_table(table_id);
mutex_exit(&dict_sys.mutex);
dict_sys.mutex_unlock();
} else {
node->table = dict_sys.get_temporary_table(table_id);
}

Some files were not shown because too many files have changed in this diff Show more