diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-05-24 11:09:59 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-05-24 11:09:59 +0300 |
commit | 52df8040264cc6f3226e78d371e4c1dd88dd22b6 (patch) | |
tree | 49a9a8484816a422f5c60b92b0fe7768d7b4bbb7 /storage | |
parent | fdb8d0181e04a3692aa78e3954af55e4b888f5a0 (diff) | |
download | mariadb-git-52df8040264cc6f3226e78d371e4c1dd88dd22b6.tar.gz |
MDEV-16267 Wrong INFORMATION_SCHEMA.INNODB_BUFFER_PAGE.TABLE_NAME
This is the MariaDB 10.2 version of the patch.
field_store_string(): Simplify the code.
field_store_index_name(): Remove, and use field_store_string()
instead. Starting with MariaDB 10.2.2, there is the predicate
dict_index_t::is_committed(), and dict_index_t::name never
contains the magic byte 0xff.
Correct some comments to refer to TEMP_INDEX_PREFIX_STR.
i_s_cmp_per_index_fill_low(): Use the appropriate value NULL to
identify that an index was not found. Check that storing each
column value succeeded.
i_s_innodb_buffer_page_fill(), i_s_innodb_buf_page_lru_fill():
Only invoke Field::set_notnull() if the index was found.
(This fixes the bug.)
i_s_dict_fill_sys_indexes(): Adjust the index->name that was
directly loaded from SYS_INDEXES.NAME (which can start with
the 0xff byte). This was the only function that depended
on the translation in field_store_index_name().
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/dict/dict0load.cc | 5 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 2 | ||||
-rw-r--r-- | storage/innobase/handler/i_s.cc | 177 |
3 files changed, 79 insertions, 105 deletions
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index f39c4900995..022535631cc 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -2477,8 +2477,9 @@ dict_load_indexes( && static_cast<char>(*field) == static_cast<char>(*TEMP_INDEX_PREFIX_STR)) { /* Skip indexes whose name starts with - TEMP_INDEX_PREFIX, because they will - be dropped during crash recovery. */ + TEMP_INDEX_PREFIX_STR, because they will + be dropped by row_merge_drop_temp_indexes() + during crash recovery. */ goto next_rec; } } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index f27f92dacb5..d1a68813a29 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -8169,7 +8169,7 @@ commit_cache_norebuild( (after renaming the indexes), so that in the event of a crash, crash recovery will drop the indexes, because it drops all indexes whose - names start with TEMP_INDEX_PREFIX. Once we + names start with TEMP_INDEX_PREFIX_STR. Once we have started dropping an index tree, there is no way to roll it back. */ diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index a7b678230ee..2f0bdac3f07 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -261,59 +261,13 @@ field_store_string( const char* str) /*!< in: NUL-terminated utf-8 string, or NULL */ { - int ret; - - if (str != NULL) { - - ret = field->store(str, static_cast<uint>(strlen(str)), - system_charset_info); - field->set_notnull(); - } else { - - ret = 0; /* success */ + if (!str) { field->set_null(); - } - - return(ret); -} - -/*******************************************************************//** -Store the name of an index in a MYSQL_TYPE_VARCHAR field. -Handles the names of incomplete secondary indexes. -@return 0 on success */ -static -int -field_store_index_name( -/*===================*/ - Field* field, /*!< in/out: target field for - storage */ - const char* index_name) /*!< in: NUL-terminated utf-8 - index name, possibly starting with - TEMP_INDEX_PREFIX */ -{ - int ret; - - ut_ad(index_name != NULL); - ut_ad(field->real_type() == MYSQL_TYPE_VARCHAR); - - /* Since TEMP_INDEX_PREFIX is not a valid UTF8, we need to convert - it to something else. */ - if (*index_name == *TEMP_INDEX_PREFIX_STR) { - char buf[NAME_LEN + 1]; - buf[0] = '?'; - memcpy(buf + 1, index_name + 1, strlen(index_name)); - ret = field->store( - buf, static_cast<uint>(strlen(buf)), - system_charset_info); - } else { - ret = field->store( - index_name, static_cast<uint>(strlen(index_name)), - system_charset_info); + return 0; } field->set_notnull(); - - return(ret); + return field->store(str, uint(strlen(str)), system_charset_info); } /*******************************************************************//** @@ -952,12 +906,8 @@ fill_innodb_locks_from_cache( buf, uint(bufend - buf), system_charset_info)); /* lock_index */ - if (row->lock_index != NULL) { - OK(field_store_index_name(fields[IDX_LOCK_INDEX], - row->lock_index)); - } else { - fields[IDX_LOCK_INDEX]->set_null(); - } + OK(field_store_string(fields[IDX_LOCK_INDEX], + row->lock_index)); /* lock_space */ OK(field_store_ulint(fields[IDX_LOCK_SPACE], @@ -1731,7 +1681,6 @@ i_s_cmp_per_index_fill_low( for (iter = snap.begin(), i = 0; iter != snap.end(); iter++, i++) { - char name[192]; dict_index_t* index = dict_index_find_on_id_low(iter->first); if (index != NULL) { @@ -1742,38 +1691,39 @@ i_s_cmp_per_index_fill_low( db_utf8, sizeof(db_utf8), table_utf8, sizeof(table_utf8)); - field_store_string(fields[IDX_DATABASE_NAME], db_utf8); - field_store_string(fields[IDX_TABLE_NAME], table_utf8); - field_store_index_name(fields[IDX_INDEX_NAME], - index->name); + status = field_store_string(fields[IDX_DATABASE_NAME], + db_utf8) + || field_store_string(fields[IDX_TABLE_NAME], + table_utf8) + || field_store_string(fields[IDX_INDEX_NAME], + index->name); } else { /* index not found */ - snprintf(name, sizeof(name), - "index_id:" IB_ID_FMT, iter->first); - field_store_string(fields[IDX_DATABASE_NAME], - "unknown"); - field_store_string(fields[IDX_TABLE_NAME], - "unknown"); - field_store_string(fields[IDX_INDEX_NAME], - name); + char name[MY_INT64_NUM_DECIMAL_DIGITS + + sizeof "index_id: "]; + fields[IDX_DATABASE_NAME]->set_null(); + fields[IDX_TABLE_NAME]->set_null(); + fields[IDX_INDEX_NAME]->set_notnull(); + status = fields[IDX_INDEX_NAME]->store( + name, + uint(snprintf(name, sizeof name, + "index_id: " IB_ID_FMT, + iter->first)), + system_charset_info); } - fields[IDX_COMPRESS_OPS]->store( - iter->second.compressed, true); - - fields[IDX_COMPRESS_OPS_OK]->store( - iter->second.compressed_ok, true); - - fields[IDX_COMPRESS_TIME]->store( - iter->second.compressed_usec / 1000000, true); - - fields[IDX_UNCOMPRESS_OPS]->store( - iter->second.decompressed, true); - - fields[IDX_UNCOMPRESS_TIME]->store( - iter->second.decompressed_usec / 1000000, true); - - if (schema_table_store_record(thd, table)) { + if (status + || fields[IDX_COMPRESS_OPS]->store( + iter->second.compressed, true) + || fields[IDX_COMPRESS_OPS_OK]->store( + iter->second.compressed_ok, true) + || fields[IDX_COMPRESS_TIME]->store( + iter->second.compressed_usec / 1000000, true) + || fields[IDX_UNCOMPRESS_OPS]->store( + iter->second.decompressed, true) + || fields[IDX_UNCOMPRESS_TIME]->store( + iter->second.decompressed_usec / 1000000, true) + || schema_table_store_record(thd, table)) { status = 1; break; } @@ -1781,8 +1731,9 @@ i_s_cmp_per_index_fill_low( threads to proceed. This could eventually result in the contents of INFORMATION_SCHEMA.innodb_cmp_per_index being inconsistent, but it is an acceptable compromise. */ - if (i % 1000 == 0) { + if (i == 1000) { mutex_exit(&dict_sys->mutex); + i = 0; mutex_enter(&dict_sys->mutex); } } @@ -4932,9 +4883,11 @@ i_s_innodb_buffer_page_fill( mutex_enter(&dict_sys->mutex); - if (const dict_index_t* index = - dict_index_get_if_in_cache_low( - page_info->index_id)) { + const dict_index_t* index = + dict_index_get_if_in_cache_low( + page_info->index_id); + + if (index) { table_name_end = innobase_convert_name( table_name, sizeof(table_name), index->table_name, @@ -4947,17 +4900,22 @@ i_s_innodb_buffer_page_fill( table_name_end - table_name), system_charset_info) - || field_store_index_name( - fields - [IDX_BUFFER_PAGE_INDEX_NAME], - index->name); + || fields[IDX_BUFFER_PAGE_INDEX_NAME] + ->store(index->name, + uint(strlen(index->name)), + system_charset_info); } mutex_exit(&dict_sys->mutex); OK(ret); - fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_notnull(); + if (index) { + fields[IDX_BUFFER_PAGE_TABLE_NAME] + ->set_notnull(); + fields[IDX_BUFFER_PAGE_INDEX_NAME] + ->set_notnull(); + } } OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store( @@ -5649,9 +5607,11 @@ i_s_innodb_buf_page_lru_fill( mutex_enter(&dict_sys->mutex); - if (const dict_index_t* index = - dict_index_get_if_in_cache_low( - page_info->index_id)) { + const dict_index_t* index = + dict_index_get_if_in_cache_low( + page_info->index_id); + + if (index) { table_name_end = innobase_convert_name( table_name, sizeof(table_name), index->table_name, @@ -5664,17 +5624,22 @@ i_s_innodb_buf_page_lru_fill( table_name_end - table_name), system_charset_info) - || field_store_index_name( - fields - [IDX_BUF_LRU_PAGE_INDEX_NAME], - index->name); + || fields[IDX_BUF_LRU_PAGE_INDEX_NAME] + ->store(index->name, + uint(strlen(index->name)), + system_charset_info); } mutex_exit(&dict_sys->mutex); OK(ret); - fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_notnull(); + if (index) { + fields[IDX_BUF_LRU_PAGE_TABLE_NAME] + ->set_notnull(); + fields[IDX_BUF_LRU_PAGE_INDEX_NAME] + ->set_notnull(); + } } OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store( @@ -6647,7 +6612,15 @@ i_s_dict_fill_sys_indexes( fields = table_to_fill->field; - OK(field_store_index_name(fields[SYS_INDEX_NAME], index->name)); + if (*index->name == *TEMP_INDEX_PREFIX_STR) { + /* Since TEMP_INDEX_PREFIX_STR is not valid UTF-8, we + need to convert it to something else. */ + *const_cast<char*>(index->name()) = '?'; + } + + OK(fields[SYS_INDEX_NAME]->store(index->name, + uint(strlen(index->name)), + system_charset_info)); OK(fields[SYS_INDEX_ID]->store(longlong(index->id), true)); |