diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-05-07 15:50:38 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-05-07 15:50:38 +0300 |
commit | 1a4c355a1c5e6b0e323be450fb38633921b42324 (patch) | |
tree | 6b41d5921fc26203fe978e81bc1a953d7f60948c | |
parent | 005d53f6d59fe8e1e118c63b9af57fea2a31f4f2 (diff) | |
parent | e44ca6cc9c300cbdf93c64110bd8cf2be8125379 (diff) | |
download | mariadb-git-1a4c355a1c5e6b0e323be450fb38633921b42324.tar.gz |
Merge 10.2 into 10.3
-rw-r--r-- | mysql-test/suite/innodb/r/alter_partitioned_debug.result | 27 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/alter_partitioned_debug.test | 34 | ||||
-rw-r--r-- | storage/innobase/dict/dict0defrag_bg.cc | 4 | ||||
-rw-r--r-- | storage/innobase/dict/dict0load.cc | 16 | ||||
-rw-r--r-- | storage/innobase/dict/dict0stats.cc | 7 | ||||
-rw-r--r-- | storage/innobase/fts/fts0fts.cc | 2 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 22 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 17 | ||||
-rw-r--r-- | storage/innobase/include/dict0dict.h | 12 | ||||
-rw-r--r-- | storage/innobase/include/dict0dict.ic | 15 | ||||
-rw-r--r-- | storage/innobase/include/dict0mem.h | 10 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 3 | ||||
-rw-r--r-- | storage/innobase/row/row0log.cc | 18 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.cc | 4 | ||||
-rw-r--r-- | storage/innobase/row/row0purge.cc | 3 | ||||
-rw-r--r-- | storage/innobase/row/row0sel.cc | 6 |
16 files changed, 115 insertions, 85 deletions
diff --git a/mysql-test/suite/innodb/r/alter_partitioned_debug.result b/mysql-test/suite/innodb/r/alter_partitioned_debug.result new file mode 100644 index 00000000000..d2ec602c6d7 --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_partitioned_debug.result @@ -0,0 +1,27 @@ +CREATE TABLE t1 (a INT, b VARCHAR(10)) ENGINE=InnoDB +PARTITION BY RANGE(a) +(PARTITION pa VALUES LESS THAN (3), +PARTITION pb VALUES LESS THAN (5)); +INSERT INTO t1 VALUES(2,'two'),(2,'two'),(4,'four'); +connect ddl,localhost,root,,test; +SET DEBUG_SYNC = 'inplace_after_index_build SIGNAL go WAIT_FOR done'; +ALTER TABLE t1 ADD UNIQUE KEY (a,b(3)); +connection default; +SET DEBUG_SYNC = 'now WAIT_FOR go'; +BEGIN; +SELECT * FROM t1 FOR UPDATE; +a b +2 two +2 two +4 four +SET DEBUG_SYNC = 'now SIGNAL done'; +connection ddl; +ERROR 23000: Duplicate entry '2-two' for key 'a' +connection default; +DELETE FROM t1; +disconnect ddl; +SET DEBUG_SYNC = 'RESET'; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/alter_partitioned_debug.test b/mysql-test/suite/innodb/t/alter_partitioned_debug.test new file mode 100644 index 00000000000..34565e12036 --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_partitioned_debug.test @@ -0,0 +1,34 @@ +--source include/have_innodb.inc +--source include/have_partition.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +CREATE TABLE t1 (a INT, b VARCHAR(10)) ENGINE=InnoDB +PARTITION BY RANGE(a) +(PARTITION pa VALUES LESS THAN (3), +PARTITION pb VALUES LESS THAN (5)); + +INSERT INTO t1 VALUES(2,'two'),(2,'two'),(4,'four'); + +connect ddl,localhost,root,,test; +SET DEBUG_SYNC = 'inplace_after_index_build SIGNAL go WAIT_FOR done'; +send ALTER TABLE t1 ADD UNIQUE KEY (a,b(3)); + +connection default; +SET DEBUG_SYNC = 'now WAIT_FOR go'; +BEGIN; +SELECT * FROM t1 FOR UPDATE; +SET DEBUG_SYNC = 'now SIGNAL done'; + +connection ddl; +--error ER_DUP_ENTRY +reap; + +connection default; +DELETE FROM t1; +disconnect ddl; + +SET DEBUG_SYNC = 'RESET'; + +CHECK TABLE t1; +DROP TABLE t1; diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index 7b9a0373c48..949bbbc0d74 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2016, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2016, 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 @@ -232,7 +232,7 @@ dict_stats_process_entry_from_defrag_pool() ? dict_table_find_index_on_id(table, index_id) : NULL; - if (!index || dict_index_is_corrupted(index)) { + if (!index || index->is_corrupted()) { if (table) { dict_table_close(table, TRUE, FALSE); } diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index ad9680df2c6..0fe11e11ac9 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -2481,10 +2481,10 @@ dict_load_indexes( } ut_ad(index); + ut_ad(!dict_index_is_online_ddl(index)); /* Check whether the index is corrupted */ - if (dict_index_is_corrupted(index)) { - + if (index->is_corrupted()) { ib::error() << "Index " << index->name << " of table " << table->name << " is corrupted"; @@ -3002,10 +3002,7 @@ err_exit: table = NULL; goto func_exit; } else { - dict_index_t* clust_index; - clust_index = dict_table_get_first_index(table); - - if (dict_index_is_corrupted(clust_index)) { + if (table->indexes.start->is_corrupted()) { table->corrupted = true; } } @@ -3056,14 +3053,11 @@ err_exit: if (!srv_force_recovery || !index - || !dict_index_is_clust(index)) { - + || !index->is_primary()) { dict_table_remove_from_cache(table); table = NULL; - - } else if (dict_index_is_corrupted(index) + } else if (index->is_corrupted() && table->is_readable()) { - /* It is possible we force to load a corrupted clustered index if srv_load_corrupted is set. Mark the table as corrupted in this case */ diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 4a2fbe32243..0d59739a7ba 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -158,9 +158,8 @@ dict_stats_should_ignore_index( /*===========================*/ const dict_index_t* index) /*!< in: index */ { - return((index->type & DICT_FTS) - || dict_index_is_corrupted(index) - || dict_index_is_spatial(index) + return((index->type & (DICT_FTS | DICT_SPATIAL)) + || index->is_corrupted() || index->to_be_dropped || !index->is_committed()); } @@ -2230,7 +2229,7 @@ dict_stats_update_persistent( index = dict_table_get_first_index(table); if (index == NULL - || dict_index_is_corrupted(index) + || index->is_corrupted() || (index->type | DICT_UNIQUE) != (DICT_CLUSTERED | DICT_UNIQUE)) { /* Table definition is corrupt */ diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index bea674065bc..1f7612b4fd8 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -6526,7 +6526,7 @@ fts_check_corrupt_index( if (index->id == aux_table->index_id) { ut_ad(index->type & DICT_FTS); dict_table_close(table, true, false); - return(dict_index_is_corrupted(index)); + return index->is_corrupted(); } } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c93841a7a3a..ba97579d413 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9259,13 +9259,13 @@ ha_innobase::index_read( dict_index_t* index = m_prebuilt->index; - if (index == NULL || dict_index_is_corrupted(index)) { + if (index == NULL || index->is_corrupted()) { m_prebuilt->index_usable = FALSE; DBUG_RETURN(HA_ERR_CRASHED); } if (!m_prebuilt->index_usable) { - DBUG_RETURN(dict_index_is_corrupted(index) + DBUG_RETURN(index->is_corrupted() ? HA_ERR_INDEX_CORRUPT : HA_ERR_TABLE_DEF_CHANGED); } @@ -9523,14 +9523,14 @@ ha_innobase::change_active_index( m_prebuilt->trx, m_prebuilt->index); if (!m_prebuilt->index_usable) { - if (dict_index_is_corrupted(m_prebuilt->index)) { + if (m_prebuilt->index->is_corrupted()) { char table_name[MAX_FULL_NAME_LEN + 1]; innobase_format_name( table_name, sizeof table_name, m_prebuilt->index->table->name.m_name); - if (dict_index_is_clust(m_prebuilt->index)) { + if (m_prebuilt->index->is_primary()) { ut_ad(m_prebuilt->index->table->corrupted); push_warning_printf( m_user_thd, Sql_condition::WARN_LEVEL_WARN, @@ -13380,7 +13380,7 @@ ha_innobase::records_in_range( n_rows = HA_POS_ERROR; goto func_exit; } - if (dict_index_is_corrupted(index)) { + if (index->is_corrupted()) { n_rows = HA_ERR_INDEX_CORRUPT; goto func_exit; } @@ -14220,7 +14220,7 @@ ha_innobase::defragment_table( for (index = dict_table_get_first_index(table); index; index = dict_table_get_next_index(index)) { - if (dict_index_is_corrupted(index)) { + if (index->is_corrupted()) { continue; } @@ -14417,7 +14417,7 @@ ha_innobase::check( clustered index, we will do so here */ index = dict_table_get_first_index(m_prebuilt->table); - if (!dict_index_is_corrupted(index)) { + if (!index->is_corrupted()) { dict_set_corrupted( index, m_prebuilt->trx, "CHECK TABLE"); } @@ -14455,7 +14455,7 @@ ha_innobase::check( } if (!(check_opt->flags & T_QUICK) - && !dict_index_is_corrupted(index)) { + && !index->is_corrupted()) { /* Enlarge the fatal lock wait timeout during CHECK TABLE. */ my_atomic_addlong( @@ -14507,7 +14507,7 @@ ha_innobase::check( DBUG_EXECUTE_IF( "dict_set_index_corrupted", - if (!dict_index_is_clust(index)) { + if (!index->is_primary()) { m_prebuilt->index_usable = FALSE; // row_mysql_lock_data_dictionary(m_prebuilt->trx); dict_set_corrupted(index, m_prebuilt->trx, "dict_set_index_corrupted"); @@ -14515,7 +14515,7 @@ ha_innobase::check( }); if (UNIV_UNLIKELY(!m_prebuilt->index_usable)) { - if (dict_index_is_corrupted(m_prebuilt->index)) { + if (index->is_corrupted()) { push_warning_printf( m_user_thd, Sql_condition::WARN_LEVEL_WARN, @@ -14555,7 +14555,7 @@ ha_innobase::check( DBUG_EXECUTE_IF( "dict_set_index_corrupted", - if (!dict_index_is_clust(index)) { + if (!index->is_primary()) { ret = DB_CORRUPTION; }); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 66ca762ccce..64e1b528834 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -5232,8 +5232,7 @@ new_clustered_failed: = dict_table_get_first_index(user_table); index != NULL; index = dict_table_get_next_index(index)) { - if (!index->to_be_dropped - && dict_index_is_corrupted(index)) { + if (!index->to_be_dropped && index->is_corrupted()) { my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0)); goto error_handled; } @@ -5243,8 +5242,7 @@ new_clustered_failed: = dict_table_get_first_index(user_table); index != NULL; index = dict_table_get_next_index(index)) { - if (!index->to_be_dropped - && dict_index_is_corrupted(index)) { + if (!index->to_be_dropped && index->is_corrupted()) { my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0)); goto error_handled; } @@ -6322,8 +6320,7 @@ ha_innobase::prepare_inplace_alter_table( if (indexed_table->corrupted || dict_table_get_first_index(indexed_table) == NULL - || dict_index_is_corrupted( - dict_table_get_first_index(indexed_table))) { + || dict_table_get_first_index(indexed_table)->is_corrupted()) { /* The clustered index is corrupted. */ my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0)); DBUG_RETURN(true); @@ -6611,7 +6608,7 @@ found_fk: " with name %s", key->name); } else { ut_ad(!index->to_be_dropped); - if (!dict_index_is_clust(index)) { + if (!index->is_primary()) { drop_index[n_drop_index++] = index; } else { drop_primary = index; @@ -6712,7 +6709,7 @@ check_if_can_drop_indexes: for (dict_index_t* index = dict_table_get_first_index(indexed_table); index != NULL; index = dict_table_get_next_index(index)) { - if (!index->to_be_dropped && dict_index_is_corrupted(index)) { + if (!index->to_be_dropped && index->is_corrupted()) { my_error(ER_INDEX_CORRUPT, MYF(0), index->name()); goto err_exit; } @@ -8440,7 +8437,7 @@ commit_try_rebuild( DBUG_ASSERT(dict_index_get_online_status(index) == ONLINE_INDEX_COMPLETE); DBUG_ASSERT(index->is_committed()); - if (dict_index_is_corrupted(index)) { + if (index->is_corrupted()) { my_error(ER_INDEX_CORRUPT, MYF(0), index->name()); DBUG_RETURN(true); } @@ -8689,7 +8686,7 @@ commit_try_norebuild( DBUG_ASSERT(dict_index_get_online_status(index) == ONLINE_INDEX_COMPLETE); DBUG_ASSERT(!index->is_committed()); - if (dict_index_is_corrupted(index)) { + if (index->is_corrupted()) { /* Report a duplicate key error for the index that was flagged corrupted, most likely diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index c6d39114c4c..5d77614aeb3 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -683,7 +683,7 @@ dict_table_get_next_index( /* Skip corrupted index */ #define dict_table_skip_corrupt_index(index) \ - while (index && dict_index_is_corrupted(index)) { \ + while (index && index->is_corrupted()) { \ index = dict_table_get_next_index(index); \ } @@ -1770,16 +1770,6 @@ dict_table_is_corrupted( MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** -Check whether the index is corrupted. -@return nonzero for corrupted index, zero for valid indexes */ -UNIV_INLINE -ulint -dict_index_is_corrupted( -/*====================*/ - const dict_index_t* index) /*!< in: index */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); - -/**********************************************************************//** Flags an index and table corrupted both in the data dictionary cache and in the system table SYS_INDEXES. */ void diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index d5eea675797..905e2fef636 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -1391,21 +1391,6 @@ dict_table_is_corrupted( } /********************************************************************//** -Check whether the index is corrupted. -@return nonzero for corrupted index, zero for valid indexes */ -UNIV_INLINE -ulint -dict_index_is_corrupted( -/*====================*/ - const dict_index_t* index) /*!< in: index */ -{ - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return((index->type & DICT_CORRUPT) - || (index->table && index->table->corrupted)); -} - -/********************************************************************//** Check if the tablespace for the table has been discarded. @return true if the tablespace has been discarded. */ UNIV_INLINE diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index d4f879a6c77..1fa1a248bef 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1045,6 +1045,9 @@ struct dict_index_t{ return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF)); } + /** @return whether the index is corrupted */ + inline bool is_corrupted() const; + /** Determine how many fields of a given prefix can be set NULL. @param[in] n_prefix number of fields in the prefix @return number of fields 0..n_prefix-1 that can be set NULL */ @@ -1934,6 +1937,13 @@ inline bool dict_index_t::is_instant() const return(n_core_fields != n_fields); } +inline bool dict_index_t::is_corrupted() const +{ + return UNIV_UNLIKELY(online_status >= ONLINE_INDEX_ABORTED + || (type & DICT_CORRUPT) + || (table && table->corrupted)); +} + /*******************************************************************//** Initialise the table lock list. */ void diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index d769b9e2ec0..d4e14988e66 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -3774,8 +3774,7 @@ row_ins( node->index = NULL; node->entry = NULL; break;); /* Skip corrupted secondary index and its entry */ - while (node->index && dict_index_is_corrupted(node->index)) { - + while (node->index && node->index->is_corrupted()) { node->index = dict_table_get_next_index(node->index); node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry); } diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 1357217ee4e..3cdeaba13dd 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -328,7 +328,7 @@ row_log_online_op( ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_S) || rw_lock_own(dict_index_get_lock(index), RW_LOCK_X)); - if (dict_index_is_corrupted(index)) { + if (index->is_corrupted()) { return; } @@ -648,8 +648,8 @@ row_log_table_delete( &index->lock, RW_LOCK_FLAG_S | RW_LOCK_FLAG_X | RW_LOCK_FLAG_SX)); - if (dict_index_is_corrupted(index) - || !dict_index_is_online_ddl(index) + if (index->online_status != ONLINE_INDEX_CREATION + || (index->type & DICT_CORRUPT) || index->table->corrupted || index->online_log->error != DB_SUCCESS) { return; } @@ -1016,8 +1016,8 @@ row_log_table_low( ut_ad(!old_pk || !insert); ut_ad(!old_pk || old_pk->n_v_fields == 0); - if (dict_index_is_corrupted(index) - || !dict_index_is_online_ddl(index) + if (index->online_status != ONLINE_INDEX_CREATION + || (index->type & DICT_CORRUPT) || index->table->corrupted || index->online_log->error != DB_SUCCESS) { return; } @@ -2826,7 +2826,7 @@ next_block: goto interrupted; } - if (dict_index_is_corrupted(index)) { + if (index->is_corrupted()) { error = DB_INDEX_CORRUPT; goto func_exit; } @@ -3330,7 +3330,7 @@ row_log_apply_op_low( ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_X) == has_index_lock); - ut_ad(!dict_index_is_corrupted(index)); + ut_ad(!index->is_corrupted()); ut_ad(trx_id != 0 || op == ROW_OP_DELETE); DBUG_LOG("ib_create_index", @@ -3574,7 +3574,7 @@ row_log_apply_op( ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_X) == has_index_lock); - if (dict_index_is_corrupted(index)) { + if (index->is_corrupted()) { *error = DB_INDEX_CORRUPT; return(NULL); } @@ -3711,7 +3711,7 @@ next_block: goto func_exit; } - if (dict_index_is_corrupted(index)) { + if (index->is_corrupted()) { error = DB_INDEX_CORRUPT; goto func_exit; } diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 2fbcc16142b..f742c597e34 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -4483,13 +4483,13 @@ row_merge_is_index_usable( const trx_t* trx, /*!< in: transaction */ const dict_index_t* index) /*!< in: index to check */ { - if (!dict_index_is_clust(index) + if (!index->is_primary() && dict_index_is_online_ddl(index)) { /* Indexes that are being created are not useable. */ return(false); } - return(!dict_index_is_corrupted(index) + return(!index->is_corrupted() && (dict_table_is_temporary(index->table) || index->trx_id == 0 || !trx->read_view.is_open() diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index c863d42207c..5aa4bbcac96 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -972,8 +972,7 @@ try_again: clust_index = dict_table_get_first_index(node->table); - if (clust_index == NULL - || dict_index_is_corrupted(clust_index)) { + if (!clust_index || clust_index->is_corrupted()) { /* The table was corrupt in the data dictionary. dict_set_corrupted() works on an index, and we do not have an index to call it with. */ diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 3aed20801bb..ef3ae40f928 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4219,18 +4219,14 @@ row_search_mvcc( ut_ad(!sync_check_iterate(sync_check())); if (dict_table_is_discarded(prebuilt->table)) { - DBUG_RETURN(DB_TABLESPACE_DELETED); - } else if (!prebuilt->table->is_readable()) { DBUG_RETURN(prebuilt->table->space ? DB_DECRYPTION_FAILED : DB_TABLESPACE_NOT_FOUND); } else if (!prebuilt->index_usable) { DBUG_RETURN(DB_MISSING_HISTORY); - - } else if (dict_index_is_corrupted(prebuilt->index)) { - + } else if (prebuilt->index->is_corrupted()) { DBUG_RETURN(DB_CORRUPTION); } |