diff options
Diffstat (limited to 'storage/innobase/dict/dict0dict.cc')
-rw-r--r-- | storage/innobase/dict/dict0dict.cc | 224 |
1 files changed, 85 insertions, 139 deletions
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 6a594855674..4ea5a5b30e9 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -2,7 +2,7 @@ Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 2019, 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 @@ -60,7 +60,6 @@ ib_warn_row_too_big(const dict_table_t* table); #include "dict0mem.h" #include "dict0priv.h" #include "dict0stats.h" -#include "fsp0sysspace.h" #include "fts0fts.h" #include "fts0types.h" #include "lock0lock.h" @@ -81,7 +80,6 @@ ib_warn_row_too_big(const dict_table_t* table); #include "srv0start.h" #include "sync0sync.h" #include "trx0undo.h" -#include "ut0new.h" #include <vector> #include <algorithm> @@ -408,6 +406,27 @@ dict_table_stats_unlock( } } + +/** Open a persistent table. +@param[in] table_id persistent table identifier +@param[in] ignore_err errors to ignore +@param[in] cached_only whether to skip loading +@return persistent table +@retval NULL if not found */ +static dict_table_t* dict_table_open_on_id_low( + table_id_t table_id, + dict_err_ignore_t ignore_err, + bool cached_only) +{ + dict_table_t* table = dict_sys->get_table(table_id); + + if (!table && !cached_only) { + table = dict_load_table_on_id(table_id, ignore_err); + } + + return table; +} + /**********************************************************************//** Try to drop any indexes after an aborted index creation. This can also be after a server kill during DROP INDEX. */ @@ -418,7 +437,7 @@ dict_table_try_drop_aborted( dict_table_t* table, /*!< in: table, or NULL if it needs to be looked up again */ table_id_t table_id, /*!< in: table identifier */ - int32 ref_count) /*!< in: expected table->n_ref_count */ + uint32_t ref_count) /*!< in: expected table->n_ref_count */ { trx_t* trx; @@ -886,47 +905,29 @@ dict_index_get_nth_col_or_prefix_pos( return(ULINT_UNDEFINED); } -/** Returns TRUE if the index contains a column or a prefix of that column. -@param[in] index index +/** Check if the index contains a column or a prefix of that column. @param[in] n column number @param[in] is_virtual whether it is a virtual col -@return TRUE if contains the column or its prefix */ -bool -dict_index_contains_col_or_prefix( - const dict_index_t* index, - ulint n, - bool is_virtual) +@return whether the index contains the column or its prefix */ +bool dict_index_t::contains_col_or_prefix(ulint n, bool is_virtual) const { - const dict_field_t* field; - const dict_col_t* col; - ulint pos; - ulint n_fields; + ut_ad(magic_n == DICT_INDEX_MAGIC_N); - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - if (dict_index_is_clust(index)) { + if (is_primary()) { return(!is_virtual); } - if (is_virtual) { - col = &dict_table_get_nth_v_col(index->table, n)->m_col; - } else { - col = dict_table_get_nth_col(index->table, n); - } - - n_fields = dict_index_get_n_fields(index); - - for (pos = 0; pos < n_fields; pos++) { - field = dict_index_get_nth_field(index, pos); + const dict_col_t* col = is_virtual + ? &dict_table_get_nth_v_col(table, n)->m_col + : dict_table_get_nth_col(table, n); - if (col == field->col) { - - return(true); + for (ulint pos = 0; pos < n_fields; pos++) { + if (col == fields[pos].col) { + return true; } } - return(false); + return false; } /********************************************************************//** @@ -1086,20 +1087,19 @@ dict_init(void) dict_operation_lock = static_cast<rw_lock_t*>( ut_zalloc_nokey(sizeof(*dict_operation_lock))); - dict_sys = static_cast<dict_sys_t*>(ut_zalloc_nokey(sizeof(*dict_sys))); + dict_sys = new (ut_zalloc_nokey(sizeof(*dict_sys))) dict_sys_t(); UT_LIST_INIT(dict_sys->table_LRU, &dict_table_t::table_LRU); UT_LIST_INIT(dict_sys->table_non_LRU, &dict_table_t::table_LRU); mutex_create(LATCH_ID_DICT_SYS, &dict_sys->mutex); - dict_sys->table_hash = hash_create( - buf_pool_get_curr_size() - / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE)); + const ulint hash_size = buf_pool_get_curr_size() + / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE); - dict_sys->table_id_hash = hash_create( - buf_pool_get_curr_size() - / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE)); + dict_sys->table_hash = hash_create(hash_size); + dict_sys->table_id_hash = hash_create(hash_size); + dict_sys->temp_id_hash = hash_create(hash_size); rw_lock_create(dict_operation_lock_key, dict_operation_lock, SYNC_DICT_OPERATION); @@ -1259,8 +1259,7 @@ dict_table_add_system_columns( } /** Add the table definition to the data dictionary cache */ -void -dict_table_t::add_to_cache() +void dict_table_t::add_to_cache() { ut_ad(dict_lru_validate()); ut_ad(mutex_own(&dict_sys->mutex)); @@ -1268,7 +1267,6 @@ dict_table_t::add_to_cache() cached = TRUE; ulint fold = ut_fold_string(name.m_name); - ulint id_fold = ut_fold_ull(id); /* Look for a table with the same name: error if such exists */ { @@ -1286,31 +1284,30 @@ dict_table_t::add_to_cache() ut_ad(table2 == NULL); #endif /* UNIV_DEBUG */ } + HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, + this); /* Look for a table with the same id: error if such exists */ + hash_table_t* id_hash = is_temporary() + ? dict_sys->temp_id_hash : dict_sys->table_id_hash; + const ulint id_fold = ut_fold_ull(id); { dict_table_t* table2; - HASH_SEARCH(id_hash, dict_sys->table_id_hash, id_fold, + HASH_SEARCH(id_hash, id_hash, id_fold, dict_table_t*, table2, ut_ad(table2->cached), table2->id == id); ut_a(table2 == NULL); #ifdef UNIV_DEBUG /* Look for the same table pointer with a different id */ - HASH_SEARCH_ALL(id_hash, dict_sys->table_id_hash, + HASH_SEARCH_ALL(id_hash, id_hash, dict_table_t*, table2, ut_ad(table2->cached), table2 == this); ut_ad(table2 == NULL); #endif /* UNIV_DEBUG */ - } - - /* Add table to hash table of tables */ - HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, - this); - /* Add table to hash table of tables based on table id */ - HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash, id_fold, - this); + HASH_INSERT(dict_table_t, id_hash, id_hash, id_fold, this); + } if (can_be_evicted) { UT_LIST_ADD_FIRST(dict_sys->table_LRU, this); @@ -1957,6 +1954,7 @@ dict_table_change_id_in_cache( ut_ad(table); ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); + ut_ad(!table->is_temporary()); /* Remove the table from the hash table of id's */ @@ -2014,8 +2012,10 @@ void dict_table_remove_from_cache(dict_table_t* table, bool lru, bool keep) HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash, ut_fold_string(table->name.m_name), table); - HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash, - ut_fold_ull(table->id), table); + hash_table_t* id_hash = table->is_temporary() + ? dict_sys->temp_id_hash : dict_sys->table_id_hash; + const ulint id_fold = ut_fold_ull(table->id); + HASH_DELETE(dict_table_t, id_hash, id_hash, id_fold, table); /* Remove table from LRU or non-LRU list. */ if (table->can_be_evicted) { @@ -5444,46 +5444,6 @@ dict_index_build_node_ptr( return(tuple); } -/**********************************************************************//** -Copies an initial segment of a physical record, long enough to specify an -index entry uniquely. -@return pointer to the prefix record */ -rec_t* -dict_index_copy_rec_order_prefix( -/*=============================*/ - const dict_index_t* index, /*!< in: index */ - const rec_t* rec, /*!< in: record for which to - copy prefix */ - ulint* n_fields,/*!< out: number of fields copied */ - byte** buf, /*!< in/out: memory buffer for the - copied prefix, or NULL */ - ulint* buf_size)/*!< in/out: buffer size */ -{ - ulint n; - - UNIV_PREFETCH_R(rec); - - if (dict_index_is_ibuf(index)) { - ut_ad(!dict_table_is_comp(index->table)); - n = rec_get_n_fields_old(rec); - } else { - if (page_rec_is_leaf(rec)) { - n = dict_index_get_n_unique_in_tree(index); - } else if (dict_index_is_spatial(index)) { - ut_ad(dict_index_get_n_unique_in_tree_nonleaf(index) - == DICT_INDEX_SPATIAL_NODEPTR_SIZE); - /* For R-tree, we have to compare - the child page numbers as well. */ - n = DICT_INDEX_SPATIAL_NODEPTR_SIZE + 1; - } else { - n = dict_index_get_n_unique_in_tree(index); - } - } - - *n_fields = n; - return(rec_copy_prefix_to_buf(rec, index, n, buf, buf_size)); -} - /** Convert a physical record into a search tuple. @param[in] rec index record (not necessarily in an index page) @param[in] index index @@ -6537,17 +6497,17 @@ dict_resize() /* all table entries are in table_LRU and table_non_LRU lists */ hash_table_free(dict_sys->table_hash); hash_table_free(dict_sys->table_id_hash); + hash_table_free(dict_sys->temp_id_hash); - dict_sys->table_hash = hash_create( - buf_pool_get_curr_size() - / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE)); - - dict_sys->table_id_hash = hash_create( - buf_pool_get_curr_size() - / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE)); + const ulint hash_size = buf_pool_get_curr_size() + / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE); + dict_sys->table_hash = hash_create(hash_size); + dict_sys->table_id_hash = hash_create(hash_size); + dict_sys->temp_id_hash = hash_create(hash_size); for (table = UT_LIST_GET_FIRST(dict_sys->table_LRU); table; table = UT_LIST_GET_NEXT(table_LRU, table)) { + ut_ad(!table->is_temporary()); ulint fold = ut_fold_string(table->name.m_name); ulint id_fold = ut_fold_ull(table->id); @@ -6566,8 +6526,10 @@ dict_resize() HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); - HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash, - id_fold, table); + hash_table_t* id_hash = table->is_temporary() + ? dict_sys->temp_id_hash : dict_sys->table_id_hash; + + HASH_INSERT(dict_table_t, id_hash, id_hash, id_fold, table); } mutex_exit(&dict_sys->mutex); @@ -6590,7 +6552,7 @@ dict_close(void) /* Free the hash elements. We don't remove them from the table because we are going to destroy the table anyway. */ - for (ulint i = 0; i < hash_get_n_cells(dict_sys->table_id_hash); i++) { + for (ulint i = 0; i < hash_get_n_cells(dict_sys->table_hash); i++) { dict_table_t* table; table = static_cast<dict_table_t*>( @@ -6611,6 +6573,7 @@ dict_close(void) /* The elements are the same instance as in dict_sys->table_hash, therefore we don't delete the individual elements. */ hash_table_free(dict_sys->table_id_hash); + hash_table_free(dict_sys->temp_id_hash); mutex_exit(&dict_sys->mutex); mutex_free(&dict_sys->mutex); @@ -6840,6 +6803,7 @@ dict_index_zip_pad_update( ulint fail_pct; ut_ad(info); + ut_ad(info->pad % ZIP_PAD_INCR == 0); total = info->success + info->failure; @@ -6864,17 +6828,16 @@ dict_index_zip_pad_update( if (fail_pct > zip_threshold) { /* Compression failures are more then user defined threshold. Increase the pad size to reduce chances of - compression failures. */ - ut_ad(info->pad % ZIP_PAD_INCR == 0); + compression failures. - /* Only do increment if it won't increase padding + Only do increment if it won't increase padding beyond max pad size. */ if (info->pad + ZIP_PAD_INCR < (srv_page_size * zip_pad_max) / 100) { /* Use atomics even though we have the mutex. This is to ensure that we are able to read info->pad atomically. */ - my_atomic_addlint(&info->pad, ZIP_PAD_INCR); + info->pad += ZIP_PAD_INCR; MONITOR_INC(MONITOR_PAD_INCREMENTS); } @@ -6892,11 +6855,10 @@ dict_index_zip_pad_update( if (info->n_rounds >= ZIP_PAD_SUCCESSFUL_ROUND_LIMIT && info->pad > 0) { - ut_ad(info->pad % ZIP_PAD_INCR == 0); /* Use atomics even though we have the mutex. This is to ensure that we are able to read info->pad atomically. */ - my_atomic_addlint(&info->pad, ulint(-ZIP_PAD_INCR)); + info->pad -= ZIP_PAD_INCR; info->n_rounds = 0; @@ -6969,7 +6931,7 @@ dict_index_zip_pad_optimal_page_size( return(srv_page_size); } - pad = my_atomic_loadlint(&index->zip_pad.pad); + pad = index->zip_pad.pad; ut_ad(pad < srv_page_size); sz = srv_page_size - pad; @@ -7011,32 +6973,16 @@ UNIV_INTERN ulint dict_sys_get_size() { - ulint size = 0; - - ut_ad(dict_sys); - - mutex_enter(&dict_sys->mutex); - - for(ulint i = 0; i < hash_get_n_cells(dict_sys->table_hash); i++) { - dict_table_t* table; - - for (table = static_cast<dict_table_t*>(HASH_GET_FIRST(dict_sys->table_hash,i)); - table != NULL; - table = static_cast<dict_table_t*>(HASH_GET_NEXT(name_hash, table))) { - dict_index_t* index; - size += mem_heap_get_size(table->heap) + strlen(table->name.m_name) +1; - - for(index = dict_table_get_first_index(table); - index != NULL; - index = dict_table_get_next_index(index)) { - size += mem_heap_get_size(index->heap); - } - } - } - - mutex_exit(&dict_sys->mutex); - - return (size); + /* No mutex; this is a very crude approximation anyway */ + ulint size = UT_LIST_GET_LEN(dict_sys->table_LRU) + + UT_LIST_GET_LEN(dict_sys->table_non_LRU); + size *= sizeof(dict_table_t) + + sizeof(dict_index_t) * 2 + + (sizeof(dict_col_t) + sizeof(dict_field_t)) * 10 + + sizeof(dict_field_t) * 5 /* total number of key fields */ + + 200; /* arbitrary, covering names and overhead */ + + return size; } /** Look for any dictionary objects that are found in the given tablespace. |