diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2017-07-21 16:05:20 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2017-07-21 16:05:20 +0300 |
commit | 92cbe388b6839bc1e21abb9859c54c58fc1769cf (patch) | |
tree | e34c5a03f82d2feba7ea91d0d7ca7bd6de0ceb92 | |
parent | 0ec147b6174a8069c303a6d0bd4e3822fe16e4c2 (diff) | |
download | mariadb-git-bb-10.0-jan.tar.gz |
MDEV-13325: InnoDB assert dict_sys->size > 0 during ALTER TABLEbb-10.0-jan
Problem was that dict_sys->size tries to maintain used memory
occupied by the data dictionary table and index objects.
However at least on table objects table->heap size can increase
between when table object is inserted to dict_sys and when
it is removed from dict_sys causing inconsistency on amount
of memory added to and removed from dict_sys->size variable.
Removed unnecessary dict_sys:size variable as it is really
used only for status output.
Introduced dict_sys_get_size function to calculate memory
occupied by the data dictionary table and index objects
that is then used on show engine innodb output.
dict_table_add_to_cache(),
dict_table_rename_in_cache(),
dict_table_remove_from_cache_low(),
dict_index_remove_from_cache_low(),
Remove size calculation.
srv_printf_innodb_monitor(): Use dict_sys_get_size function to
get dictionary memory allocated.
xtradb_internal_hash_tables_fill_table(): Use dict_sys_get_size
function to get dictionary memory allocated.
-rw-r--r-- | storage/innobase/dict/dict0dict.cc | 57 | ||||
-rw-r--r-- | storage/innobase/include/dict0dict.h | 10 | ||||
-rw-r--r-- | storage/innobase/srv/srv0srv.cc | 2 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0dict.cc | 57 | ||||
-rw-r--r-- | storage/xtradb/handler/xtradb_i_s.cc | 5 | ||||
-rw-r--r-- | storage/xtradb/include/dict0dict.h | 10 | ||||
-rw-r--r-- | storage/xtradb/srv/srv0srv.cc | 10 |
7 files changed, 94 insertions, 57 deletions
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index b6ca02fa164..be19a3f1e75 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -1365,9 +1365,6 @@ dict_table_add_to_cache( dict_table_autoinc_restore(table); ut_ad(dict_lru_validate()); - - dict_sys->size += mem_heap_get_size(table->heap) - + strlen(table->name) + 1; } /**********************************************************************//** @@ -1782,9 +1779,6 @@ dict_table_rename_in_cache( HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); - dict_sys->size += strlen(new_name) - strlen(old_name); - ut_a(dict_sys->size > 0); - /* Update the table_name field in indexes */ for (index = dict_table_get_first_index(table); index != NULL; @@ -2071,7 +2065,6 @@ dict_table_remove_from_cache_low( { dict_foreign_t* foreign; dict_index_t* index; - ulint size; ut_ad(table); ut_ad(dict_lru_validate()); @@ -2151,12 +2144,6 @@ dict_table_remove_from_cache_low( trx_free_for_background(trx); } - size = mem_heap_get_size(table->heap) + strlen(table->name) + 1; - - ut_ad(dict_sys->size >= size); - - dict_sys->size -= size; - dict_mem_table_free(table); } @@ -2692,8 +2679,6 @@ undo_size_ok: dict_index_is_ibuf(index) ? SYNC_IBUF_INDEX_TREE : SYNC_INDEX_TREE); - dict_sys->size += mem_heap_get_size(new_index->heap); - dict_mem_index_free(index); return(DB_SUCCESS); @@ -2710,7 +2695,6 @@ dict_index_remove_from_cache_low( ibool lru_evict) /*!< in: TRUE if index being evicted to make room in the table LRU list */ { - ulint size; ulint retries = 0; btr_search_t* info; @@ -2778,12 +2762,6 @@ dict_index_remove_from_cache_low( /* Remove the index from the list of indexes of the table */ UT_LIST_REMOVE(indexes, table->indexes, index); - size = mem_heap_get_size(index->heap); - - ut_ad(dict_sys->size >= size); - - dict_sys->size -= size; - dict_mem_index_free(index); } @@ -7258,3 +7236,38 @@ dict_tf_to_row_format_string( return(0); } #endif /* !UNIV_HOTBACKUP */ + +/** Calculate the used memory occupied by the data dictionary +table and index objects. +@return number of bytes occupied. */ +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) +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); +} diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 7c00ac096cb..bee291910ed 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1614,9 +1614,6 @@ struct dict_sys_t{ on name */ hash_table_t* table_id_hash; /*!< hash table of the tables, based on id */ - ulint size; /*!< varying space in bytes occupied - by the data dictionary table and - index objects */ dict_table_t* sys_tables; /*!< SYS_TABLES table */ dict_table_t* sys_columns; /*!< SYS_COLUMNS table */ dict_table_t* sys_indexes; /*!< SYS_INDEXES table */ @@ -1861,6 +1858,13 @@ dict_table_get_index_on_first_col( ulint col_index); /*!< in: position of column in table */ +/** Calculate the used memory occupied by the data dictionary +table and index objects. +@return number of bytes occupied. */ +UNIV_INTERN +ulint +dict_sys_get_size(); + #endif /* !UNIV_HOTBACKUP */ #ifndef UNIV_NONINL diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 10baf546e5b..e552e54846f 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1283,7 +1283,7 @@ srv_printf_innodb_monitor( ut_total_allocated_memory, mem_pool_get_reserved(mem_comm_pool)); fprintf(file, "Dictionary memory allocated " ULINTPF "\n", - dict_sys->size); + dict_sys_get_size()); buf_print_io(file); diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index 108bdd8f60b..567d24cd89d 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -1374,9 +1374,6 @@ dict_table_add_to_cache( dict_table_autoinc_restore(table); ut_ad(dict_lru_validate()); - - dict_sys->size += mem_heap_get_size(table->heap) - + strlen(table->name) + 1; } /**********************************************************************//** @@ -1791,9 +1788,6 @@ dict_table_rename_in_cache( HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); - dict_sys->size += strlen(new_name) - strlen(old_name); - ut_a(dict_sys->size > 0); - /* Update the table_name field in indexes */ for (index = dict_table_get_first_index(table); index != NULL; @@ -2080,7 +2074,6 @@ dict_table_remove_from_cache_low( { dict_foreign_t* foreign; dict_index_t* index; - ulint size; ut_ad(table); ut_ad(dict_lru_validate()); @@ -2160,12 +2153,6 @@ dict_table_remove_from_cache_low( trx_free_for_background(trx); } - size = mem_heap_get_size(table->heap) + strlen(table->name) + 1; - - ut_ad(dict_sys->size >= size); - - dict_sys->size -= size; - dict_mem_table_free(table); } @@ -2701,8 +2688,6 @@ undo_size_ok: dict_index_is_ibuf(index) ? SYNC_IBUF_INDEX_TREE : SYNC_INDEX_TREE); - dict_sys->size += mem_heap_get_size(new_index->heap); - dict_mem_index_free(index); return(DB_SUCCESS); @@ -2719,7 +2704,6 @@ dict_index_remove_from_cache_low( ibool lru_evict) /*!< in: TRUE if index being evicted to make room in the table LRU list */ { - ulint size; ulint retries = 0; btr_search_t* info; @@ -2788,12 +2772,6 @@ dict_index_remove_from_cache_low( /* Remove the index from the list of indexes of the table */ UT_LIST_REMOVE(indexes, table->indexes, index); - size = mem_heap_get_size(index->heap); - - ut_ad(dict_sys->size >= size); - - dict_sys->size -= size; - dict_mem_index_free(index); } @@ -7296,3 +7274,38 @@ dict_tf_to_row_format_string( return(0); } #endif /* !UNIV_HOTBACKUP */ + +/** Calculate the used memory occupied by the data dictionary +table and index objects. +@return number of bytes occupied. */ +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) +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); +} diff --git a/storage/xtradb/handler/xtradb_i_s.cc b/storage/xtradb/handler/xtradb_i_s.cc index 84c1e5852bc..6ae32d24c92 100644 --- a/storage/xtradb/handler/xtradb_i_s.cc +++ b/storage/xtradb/handler/xtradb_i_s.cc @@ -401,19 +401,20 @@ static int xtradb_internal_hash_tables_fill_table(THD* thd, TABLE_LIST* tables, if (dict_sys) { + ulint dict_size = dict_sys_get_size(); OK(field_store_string(fields[INT_HASH_TABLES_NAME], "Dictionary Cache")); OK(field_store_ulint(fields[INT_HASH_TABLES_TOTAL], ((dict_sys->table_hash->n_cells + dict_sys->table_id_hash->n_cells ) * sizeof(hash_cell_t) - + dict_sys->size))); + + dict_size))); OK(field_store_ulint(fields[INT_HASH_TABLES_CONSTANT], ((dict_sys->table_hash->n_cells + dict_sys->table_id_hash->n_cells ) * sizeof(hash_cell_t)))); OK(field_store_ulint(fields[INT_HASH_TABLES_VARIABLE], - dict_sys->size)); + dict_size)); OK(schema_table_store_record(thd, table)); } diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h index ef6c32b1787..33edab3ae98 100644 --- a/storage/xtradb/include/dict0dict.h +++ b/storage/xtradb/include/dict0dict.h @@ -1617,9 +1617,6 @@ struct dict_sys_t{ on name */ hash_table_t* table_id_hash; /*!< hash table of the tables, based on id */ - ulint size; /*!< varying space in bytes occupied - by the data dictionary table and - index objects */ dict_table_t* sys_tables; /*!< SYS_TABLES table */ dict_table_t* sys_columns; /*!< SYS_COLUMNS table */ dict_table_t* sys_indexes; /*!< SYS_INDEXES table */ @@ -1863,6 +1860,13 @@ dict_table_get_index_on_first_col( ulint col_index); /*!< in: position of column in table */ +/** Calculate the used memory occupied by the data dictionary +table and index objects. +@return number of bytes occupied. */ +UNIV_INTERN +ulint +dict_sys_get_size(); + #endif /* !UNIV_HOTBACKUP */ /************************************************************************* set is_corrupt flag by space_id*/ diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index e11697081c6..6a119756401 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -1520,6 +1520,8 @@ srv_printf_innodb_monitor( recv_sys_subtotal = ((recv_sys && recv_sys->addr_hash) ? mem_heap_get_size(recv_sys->heap) : 0); + ulint dict_size = dict_sys ? dict_sys_get_size() : 0; + fprintf(file, "Internal hash tables (constant factor + variable factor)\n" " Adaptive hash index %lu \t(%lu + " ULINTPF ")\n" @@ -1538,11 +1540,11 @@ srv_printf_innodb_monitor( (ulong) (dict_sys ? ((dict_sys->table_hash->n_cells + dict_sys->table_id_hash->n_cells ) * sizeof(hash_cell_t) - + dict_sys->size) : 0), + + dict_size) : 0), (ulong) (dict_sys ? ((dict_sys->table_hash->n_cells + dict_sys->table_id_hash->n_cells ) * sizeof(hash_cell_t)) : 0), - dict_sys ? (dict_sys->size) : 0, + dict_size, (ulong) (fil_system_hash_cells() * sizeof(hash_cell_t) + fil_system_hash_nodes()), @@ -1563,7 +1565,7 @@ srv_printf_innodb_monitor( fprintf(file, "Dictionary memory allocated " ULINTPF "\n", - dict_sys ? dict_sys->size : 0); + dict_sys ? dict_sys_get_size() : 0); buf_print_io(file); @@ -1719,7 +1721,7 @@ srv_export_innodb_status(void) mem_dictionary = (dict_sys ? ((dict_sys->table_hash->n_cells + dict_sys->table_id_hash->n_cells ) * sizeof(hash_cell_t) - + dict_sys->size) : 0); + + dict_sys_get_size()) : 0); mutex_enter(&srv_innodb_monitor_mutex); |