mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-14825 Assertion `col->ord_part' in row_build_index_entry_low upon ROLLBACK or DELETE with concurrent ALTER on partitioned table
If creating a secondary index fails (typically, ADD UNIQUE INDEX fails due to duplicate key), it is possible that concurrently running UPDATE or DELETE will access the index stub and hit the debug assertion. It does not make any sense to keep updating an uncommitted index whose creation has failed. dict_index_t::is_corrupted(): Replaces dict_index_is_corrupted(). Also take online_status into account. Replace some calls to dict_index_is_clust() with calls to dict_index_t::is_primary().
This commit is contained in:
27
mysql-test/suite/innodb/r/alter_partitioned_debug.result
Normal file
27
mysql-test/suite/innodb/r/alter_partitioned_debug.result
Normal file
@@ -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;
|
34
mysql-test/suite/innodb/t/alter_partitioned_debug.test
Normal file
34
mysql-test/suite/innodb/t/alter_partitioned_debug.test
Normal file
@@ -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;
|
@@ -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
|
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
|
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)
|
? dict_table_find_index_on_id(table, index_id)
|
||||||
: NULL;
|
: NULL;
|
||||||
|
|
||||||
if (!index || dict_index_is_corrupted(index)) {
|
if (!index || index->is_corrupted()) {
|
||||||
if (table) {
|
if (table) {
|
||||||
dict_table_close(table, TRUE, FALSE);
|
dict_table_close(table, TRUE, FALSE);
|
||||||
}
|
}
|
||||||
|
@@ -2521,10 +2521,10 @@ dict_load_indexes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(index);
|
ut_ad(index);
|
||||||
|
ut_ad(!dict_index_is_online_ddl(index));
|
||||||
|
|
||||||
/* Check whether the index is corrupted */
|
/* Check whether the index is corrupted */
|
||||||
if (dict_index_is_corrupted(index)) {
|
if (index->is_corrupted()) {
|
||||||
|
|
||||||
ib::error() << "Index " << index->name
|
ib::error() << "Index " << index->name
|
||||||
<< " of table " << table->name
|
<< " of table " << table->name
|
||||||
<< " is corrupted";
|
<< " is corrupted";
|
||||||
@@ -3044,10 +3044,7 @@ err_exit:
|
|||||||
table = NULL;
|
table = NULL;
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
} else {
|
} else {
|
||||||
dict_index_t* clust_index;
|
if (table->indexes.start->is_corrupted()) {
|
||||||
clust_index = dict_table_get_first_index(table);
|
|
||||||
|
|
||||||
if (dict_index_is_corrupted(clust_index)) {
|
|
||||||
table->corrupted = true;
|
table->corrupted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3095,14 +3092,11 @@ err_exit:
|
|||||||
|
|
||||||
if (!srv_force_recovery
|
if (!srv_force_recovery
|
||||||
|| !index
|
|| !index
|
||||||
|| !dict_index_is_clust(index)) {
|
|| !index->is_primary()) {
|
||||||
|
|
||||||
dict_table_remove_from_cache(table);
|
dict_table_remove_from_cache(table);
|
||||||
table = NULL;
|
table = NULL;
|
||||||
|
} else if (index->is_corrupted()
|
||||||
} else if (dict_index_is_corrupted(index)
|
|
||||||
&& table->is_readable()) {
|
&& table->is_readable()) {
|
||||||
|
|
||||||
/* It is possible we force to load a corrupted
|
/* It is possible we force to load a corrupted
|
||||||
clustered index if srv_load_corrupted is set.
|
clustered index if srv_load_corrupted is set.
|
||||||
Mark the table as corrupted in this case */
|
Mark the table as corrupted in this case */
|
||||||
|
@@ -158,9 +158,8 @@ dict_stats_should_ignore_index(
|
|||||||
/*===========================*/
|
/*===========================*/
|
||||||
const dict_index_t* index) /*!< in: index */
|
const dict_index_t* index) /*!< in: index */
|
||||||
{
|
{
|
||||||
return((index->type & DICT_FTS)
|
return((index->type & (DICT_FTS | DICT_SPATIAL))
|
||||||
|| dict_index_is_corrupted(index)
|
|| index->is_corrupted()
|
||||||
|| dict_index_is_spatial(index)
|
|
||||||
|| index->to_be_dropped
|
|| index->to_be_dropped
|
||||||
|| !index->is_committed());
|
|| !index->is_committed());
|
||||||
}
|
}
|
||||||
@@ -2228,7 +2227,7 @@ dict_stats_update_persistent(
|
|||||||
index = dict_table_get_first_index(table);
|
index = dict_table_get_first_index(table);
|
||||||
|
|
||||||
if (index == NULL
|
if (index == NULL
|
||||||
|| dict_index_is_corrupted(index)
|
|| index->is_corrupted()
|
||||||
|| (index->type | DICT_UNIQUE) != (DICT_CLUSTERED | DICT_UNIQUE)) {
|
|| (index->type | DICT_UNIQUE) != (DICT_CLUSTERED | DICT_UNIQUE)) {
|
||||||
|
|
||||||
/* Table definition is corrupt */
|
/* Table definition is corrupt */
|
||||||
|
@@ -6549,7 +6549,7 @@ fts_check_corrupt_index(
|
|||||||
if (index->id == aux_table->index_id) {
|
if (index->id == aux_table->index_id) {
|
||||||
ut_ad(index->type & DICT_FTS);
|
ut_ad(index->type & DICT_FTS);
|
||||||
dict_table_close(table, true, false);
|
dict_table_close(table, true, false);
|
||||||
return(dict_index_is_corrupted(index));
|
return index->is_corrupted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9406,13 +9406,13 @@ ha_innobase::index_read(
|
|||||||
|
|
||||||
dict_index_t* index = m_prebuilt->index;
|
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;
|
m_prebuilt->index_usable = FALSE;
|
||||||
DBUG_RETURN(HA_ERR_CRASHED);
|
DBUG_RETURN(HA_ERR_CRASHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_prebuilt->index_usable) {
|
if (!m_prebuilt->index_usable) {
|
||||||
DBUG_RETURN(dict_index_is_corrupted(index)
|
DBUG_RETURN(index->is_corrupted()
|
||||||
? HA_ERR_INDEX_CORRUPT
|
? HA_ERR_INDEX_CORRUPT
|
||||||
: HA_ERR_TABLE_DEF_CHANGED);
|
: HA_ERR_TABLE_DEF_CHANGED);
|
||||||
}
|
}
|
||||||
@@ -9671,14 +9671,14 @@ ha_innobase::change_active_index(
|
|||||||
m_prebuilt->trx, m_prebuilt->index);
|
m_prebuilt->trx, m_prebuilt->index);
|
||||||
|
|
||||||
if (!m_prebuilt->index_usable) {
|
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];
|
char table_name[MAX_FULL_NAME_LEN + 1];
|
||||||
|
|
||||||
innobase_format_name(
|
innobase_format_name(
|
||||||
table_name, sizeof table_name,
|
table_name, sizeof table_name,
|
||||||
m_prebuilt->index->table->name.m_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);
|
ut_ad(m_prebuilt->index->table->corrupted);
|
||||||
push_warning_printf(
|
push_warning_printf(
|
||||||
m_user_thd, Sql_condition::WARN_LEVEL_WARN,
|
m_user_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||||
@@ -13662,7 +13662,7 @@ ha_innobase::records_in_range(
|
|||||||
n_rows = HA_POS_ERROR;
|
n_rows = HA_POS_ERROR;
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
if (dict_index_is_corrupted(index)) {
|
if (index->is_corrupted()) {
|
||||||
n_rows = HA_ERR_INDEX_CORRUPT;
|
n_rows = HA_ERR_INDEX_CORRUPT;
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
@@ -14522,7 +14522,7 @@ ha_innobase::defragment_table(
|
|||||||
for (index = dict_table_get_first_index(table); index;
|
for (index = dict_table_get_first_index(table); index;
|
||||||
index = dict_table_get_next_index(index)) {
|
index = dict_table_get_next_index(index)) {
|
||||||
|
|
||||||
if (dict_index_is_corrupted(index)) {
|
if (index->is_corrupted()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14721,7 +14721,7 @@ ha_innobase::check(
|
|||||||
clustered index, we will do so here */
|
clustered index, we will do so here */
|
||||||
index = dict_table_get_first_index(m_prebuilt->table);
|
index = dict_table_get_first_index(m_prebuilt->table);
|
||||||
|
|
||||||
if (!dict_index_is_corrupted(index)) {
|
if (!index->is_corrupted()) {
|
||||||
dict_set_corrupted(
|
dict_set_corrupted(
|
||||||
index, m_prebuilt->trx, "CHECK TABLE");
|
index, m_prebuilt->trx, "CHECK TABLE");
|
||||||
}
|
}
|
||||||
@@ -14759,7 +14759,7 @@ ha_innobase::check(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(check_opt->flags & T_QUICK)
|
if (!(check_opt->flags & T_QUICK)
|
||||||
&& !dict_index_is_corrupted(index)) {
|
&& !index->is_corrupted()) {
|
||||||
/* Enlarge the fatal lock wait timeout during
|
/* Enlarge the fatal lock wait timeout during
|
||||||
CHECK TABLE. */
|
CHECK TABLE. */
|
||||||
my_atomic_addlong(
|
my_atomic_addlong(
|
||||||
@@ -14811,7 +14811,7 @@ ha_innobase::check(
|
|||||||
|
|
||||||
DBUG_EXECUTE_IF(
|
DBUG_EXECUTE_IF(
|
||||||
"dict_set_index_corrupted",
|
"dict_set_index_corrupted",
|
||||||
if (!dict_index_is_clust(index)) {
|
if (!index->is_primary()) {
|
||||||
m_prebuilt->index_usable = FALSE;
|
m_prebuilt->index_usable = FALSE;
|
||||||
// row_mysql_lock_data_dictionary(m_prebuilt->trx);
|
// row_mysql_lock_data_dictionary(m_prebuilt->trx);
|
||||||
dict_set_corrupted(index, m_prebuilt->trx, "dict_set_index_corrupted");
|
dict_set_corrupted(index, m_prebuilt->trx, "dict_set_index_corrupted");
|
||||||
@@ -14819,7 +14819,7 @@ ha_innobase::check(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(!m_prebuilt->index_usable)) {
|
if (UNIV_UNLIKELY(!m_prebuilt->index_usable)) {
|
||||||
if (dict_index_is_corrupted(m_prebuilt->index)) {
|
if (index->is_corrupted()) {
|
||||||
push_warning_printf(
|
push_warning_printf(
|
||||||
m_user_thd,
|
m_user_thd,
|
||||||
Sql_condition::WARN_LEVEL_WARN,
|
Sql_condition::WARN_LEVEL_WARN,
|
||||||
@@ -14859,7 +14859,7 @@ ha_innobase::check(
|
|||||||
|
|
||||||
DBUG_EXECUTE_IF(
|
DBUG_EXECUTE_IF(
|
||||||
"dict_set_index_corrupted",
|
"dict_set_index_corrupted",
|
||||||
if (!dict_index_is_clust(index)) {
|
if (!index->is_primary()) {
|
||||||
ret = DB_CORRUPTION;
|
ret = DB_CORRUPTION;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -4784,8 +4784,7 @@ new_clustered_failed:
|
|||||||
= dict_table_get_first_index(user_table);
|
= dict_table_get_first_index(user_table);
|
||||||
index != NULL;
|
index != NULL;
|
||||||
index = dict_table_get_next_index(index)) {
|
index = dict_table_get_next_index(index)) {
|
||||||
if (!index->to_be_dropped
|
if (!index->to_be_dropped && index->is_corrupted()) {
|
||||||
&& dict_index_is_corrupted(index)) {
|
|
||||||
my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0));
|
my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0));
|
||||||
goto error_handled;
|
goto error_handled;
|
||||||
}
|
}
|
||||||
@@ -4795,8 +4794,7 @@ new_clustered_failed:
|
|||||||
= dict_table_get_first_index(user_table);
|
= dict_table_get_first_index(user_table);
|
||||||
index != NULL;
|
index != NULL;
|
||||||
index = dict_table_get_next_index(index)) {
|
index = dict_table_get_next_index(index)) {
|
||||||
if (!index->to_be_dropped
|
if (!index->to_be_dropped && index->is_corrupted()) {
|
||||||
&& dict_index_is_corrupted(index)) {
|
|
||||||
my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0));
|
my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0));
|
||||||
goto error_handled;
|
goto error_handled;
|
||||||
}
|
}
|
||||||
@@ -5597,8 +5595,7 @@ ha_innobase::prepare_inplace_alter_table(
|
|||||||
|
|
||||||
if (indexed_table->corrupted
|
if (indexed_table->corrupted
|
||||||
|| dict_table_get_first_index(indexed_table) == NULL
|
|| dict_table_get_first_index(indexed_table) == NULL
|
||||||
|| dict_index_is_corrupted(
|
|| dict_table_get_first_index(indexed_table)->is_corrupted()) {
|
||||||
dict_table_get_first_index(indexed_table))) {
|
|
||||||
/* The clustered index is corrupted. */
|
/* The clustered index is corrupted. */
|
||||||
my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0));
|
my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0));
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
@@ -5885,7 +5882,7 @@ found_fk:
|
|||||||
" with name %s", key->name);
|
" with name %s", key->name);
|
||||||
} else {
|
} else {
|
||||||
ut_ad(!index->to_be_dropped);
|
ut_ad(!index->to_be_dropped);
|
||||||
if (!dict_index_is_clust(index)) {
|
if (!index->is_primary()) {
|
||||||
drop_index[n_drop_index++] = index;
|
drop_index[n_drop_index++] = index;
|
||||||
} else {
|
} else {
|
||||||
drop_primary = index;
|
drop_primary = index;
|
||||||
@@ -5986,7 +5983,7 @@ check_if_can_drop_indexes:
|
|||||||
for (dict_index_t* index = dict_table_get_first_index(indexed_table);
|
for (dict_index_t* index = dict_table_get_first_index(indexed_table);
|
||||||
index != NULL; index = dict_table_get_next_index(index)) {
|
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());
|
my_error(ER_INDEX_CORRUPT, MYF(0), index->name());
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
@@ -7717,7 +7714,7 @@ commit_try_rebuild(
|
|||||||
DBUG_ASSERT(dict_index_get_online_status(index)
|
DBUG_ASSERT(dict_index_get_online_status(index)
|
||||||
== ONLINE_INDEX_COMPLETE);
|
== ONLINE_INDEX_COMPLETE);
|
||||||
DBUG_ASSERT(index->is_committed());
|
DBUG_ASSERT(index->is_committed());
|
||||||
if (dict_index_is_corrupted(index)) {
|
if (index->is_corrupted()) {
|
||||||
my_error(ER_INDEX_CORRUPT, MYF(0), index->name());
|
my_error(ER_INDEX_CORRUPT, MYF(0), index->name());
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
@@ -7966,7 +7963,7 @@ commit_try_norebuild(
|
|||||||
DBUG_ASSERT(dict_index_get_online_status(index)
|
DBUG_ASSERT(dict_index_get_online_status(index)
|
||||||
== ONLINE_INDEX_COMPLETE);
|
== ONLINE_INDEX_COMPLETE);
|
||||||
DBUG_ASSERT(!index->is_committed());
|
DBUG_ASSERT(!index->is_committed());
|
||||||
if (dict_index_is_corrupted(index)) {
|
if (index->is_corrupted()) {
|
||||||
/* Report a duplicate key
|
/* Report a duplicate key
|
||||||
error for the index that was
|
error for the index that was
|
||||||
flagged corrupted, most likely
|
flagged corrupted, most likely
|
||||||
|
@@ -702,7 +702,7 @@ dict_table_get_next_index(
|
|||||||
|
|
||||||
/* Skip corrupted index */
|
/* Skip corrupted index */
|
||||||
#define dict_table_skip_corrupt_index(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); \
|
index = dict_table_get_next_index(index); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1835,16 +1835,6 @@ dict_table_is_corrupted(
|
|||||||
const dict_table_t* table) /*!< in: table */
|
const dict_table_t* table) /*!< in: table */
|
||||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
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
|
Flags an index and table corrupted both in the data dictionary cache
|
||||||
and in the system table SYS_INDEXES. */
|
and in the system table SYS_INDEXES. */
|
||||||
|
@@ -1486,21 +1486,6 @@ dict_table_is_corrupted(
|
|||||||
return(table->corrupted);
|
return(table->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.
|
Check if the tablespace for the table has been discarded.
|
||||||
@return true if the tablespace has been discarded. */
|
@return true if the tablespace has been discarded. */
|
||||||
|
@@ -980,6 +980,9 @@ struct dict_index_t{
|
|||||||
{
|
{
|
||||||
return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF));
|
return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return whether the index is corrupted */
|
||||||
|
inline bool is_corrupted() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The status of online index creation */
|
/** The status of online index creation */
|
||||||
@@ -1724,6 +1727,13 @@ inline bool dict_index_t::is_readable() const
|
|||||||
return(UNIV_LIKELY(!table->file_unreadable));
|
return(UNIV_LIKELY(!table->file_unreadable));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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. */
|
Initialise the table lock list. */
|
||||||
void
|
void
|
||||||
|
@@ -3686,8 +3686,7 @@ row_ins(
|
|||||||
node->index = NULL; node->entry = NULL; break;);
|
node->index = NULL; node->entry = NULL; break;);
|
||||||
|
|
||||||
/* Skip corrupted secondary index and its entry */
|
/* 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->index = dict_table_get_next_index(node->index);
|
||||||
node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry);
|
node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry);
|
||||||
}
|
}
|
||||||
|
@@ -293,7 +293,7 @@ row_log_online_op(
|
|||||||
ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_S)
|
ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_S)
|
||||||
|| rw_lock_own(dict_index_get_lock(index), RW_LOCK_X));
|
|| rw_lock_own(dict_index_get_lock(index), RW_LOCK_X));
|
||||||
|
|
||||||
if (dict_index_is_corrupted(index)) {
|
if (index->is_corrupted()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,8 +613,8 @@ row_log_table_delete(
|
|||||||
&index->lock,
|
&index->lock,
|
||||||
RW_LOCK_FLAG_S | RW_LOCK_FLAG_X | RW_LOCK_FLAG_SX));
|
RW_LOCK_FLAG_S | RW_LOCK_FLAG_X | RW_LOCK_FLAG_SX));
|
||||||
|
|
||||||
if (dict_index_is_corrupted(index)
|
if (index->online_status != ONLINE_INDEX_CREATION
|
||||||
|| !dict_index_is_online_ddl(index)
|
|| (index->type & DICT_CORRUPT) || index->table->corrupted
|
||||||
|| index->online_log->error != DB_SUCCESS) {
|
|| index->online_log->error != DB_SUCCESS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -922,8 +922,8 @@ row_log_table_low(
|
|||||||
ut_ad(!old_pk || !insert);
|
ut_ad(!old_pk || !insert);
|
||||||
ut_ad(!old_pk || old_pk->n_v_fields == 0);
|
ut_ad(!old_pk || old_pk->n_v_fields == 0);
|
||||||
|
|
||||||
if (dict_index_is_corrupted(index)
|
if (index->online_status != ONLINE_INDEX_CREATION
|
||||||
|| !dict_index_is_online_ddl(index)
|
|| (index->type & DICT_CORRUPT) || index->table->corrupted
|
||||||
|| index->online_log->error != DB_SUCCESS) {
|
|| index->online_log->error != DB_SUCCESS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2672,7 +2672,7 @@ next_block:
|
|||||||
goto interrupted;
|
goto interrupted;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dict_index_is_corrupted(index)) {
|
if (index->is_corrupted()) {
|
||||||
error = DB_INDEX_CORRUPT;
|
error = DB_INDEX_CORRUPT;
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
@@ -3167,7 +3167,7 @@ row_log_apply_op_low(
|
|||||||
ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_X)
|
ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_X)
|
||||||
== has_index_lock);
|
== has_index_lock);
|
||||||
|
|
||||||
ut_ad(!dict_index_is_corrupted(index));
|
ut_ad(!index->is_corrupted());
|
||||||
ut_ad(trx_id != 0 || op == ROW_OP_DELETE);
|
ut_ad(trx_id != 0 || op == ROW_OP_DELETE);
|
||||||
|
|
||||||
DBUG_LOG("ib_create_index",
|
DBUG_LOG("ib_create_index",
|
||||||
@@ -3411,7 +3411,7 @@ row_log_apply_op(
|
|||||||
ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_X)
|
ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_X)
|
||||||
== has_index_lock);
|
== has_index_lock);
|
||||||
|
|
||||||
if (dict_index_is_corrupted(index)) {
|
if (index->is_corrupted()) {
|
||||||
*error = DB_INDEX_CORRUPT;
|
*error = DB_INDEX_CORRUPT;
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
@@ -3548,7 +3548,7 @@ next_block:
|
|||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dict_index_is_corrupted(index)) {
|
if (index->is_corrupted()) {
|
||||||
error = DB_INDEX_CORRUPT;
|
error = DB_INDEX_CORRUPT;
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
@@ -4443,13 +4443,13 @@ row_merge_is_index_usable(
|
|||||||
const trx_t* trx, /*!< in: transaction */
|
const trx_t* trx, /*!< in: transaction */
|
||||||
const dict_index_t* index) /*!< in: index to check */
|
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)) {
|
&& dict_index_is_online_ddl(index)) {
|
||||||
/* Indexes that are being created are not useable. */
|
/* Indexes that are being created are not useable. */
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(!dict_index_is_corrupted(index)
|
return(!index->is_corrupted()
|
||||||
&& (dict_table_is_temporary(index->table)
|
&& (dict_table_is_temporary(index->table)
|
||||||
|| index->trx_id == 0
|
|| index->trx_id == 0
|
||||||
|| !MVCC::is_view_active(trx->read_view)
|
|| !MVCC::is_view_active(trx->read_view)
|
||||||
|
@@ -888,8 +888,7 @@ try_again:
|
|||||||
|
|
||||||
clust_index = dict_table_get_first_index(node->table);
|
clust_index = dict_table_get_first_index(node->table);
|
||||||
|
|
||||||
if (clust_index == NULL
|
if (!clust_index || clust_index->is_corrupted()) {
|
||||||
|| dict_index_is_corrupted(clust_index)) {
|
|
||||||
/* The table was corrupt in the data dictionary.
|
/* The table was corrupt in the data dictionary.
|
||||||
dict_set_corrupted() works on an index, and
|
dict_set_corrupted() works on an index, and
|
||||||
we do not have an index to call it with. */
|
we do not have an index to call it with. */
|
||||||
|
@@ -4253,18 +4253,14 @@ row_search_mvcc(
|
|||||||
ut_ad(!sync_check_iterate(sync_check()));
|
ut_ad(!sync_check_iterate(sync_check()));
|
||||||
|
|
||||||
if (dict_table_is_discarded(prebuilt->table)) {
|
if (dict_table_is_discarded(prebuilt->table)) {
|
||||||
|
|
||||||
DBUG_RETURN(DB_TABLESPACE_DELETED);
|
DBUG_RETURN(DB_TABLESPACE_DELETED);
|
||||||
|
|
||||||
} else if (!prebuilt->table->is_readable()) {
|
} else if (!prebuilt->table->is_readable()) {
|
||||||
DBUG_RETURN(fil_space_get(prebuilt->table->space)
|
DBUG_RETURN(fil_space_get(prebuilt->table->space)
|
||||||
? DB_DECRYPTION_FAILED
|
? DB_DECRYPTION_FAILED
|
||||||
: DB_TABLESPACE_NOT_FOUND);
|
: DB_TABLESPACE_NOT_FOUND);
|
||||||
} else if (!prebuilt->index_usable) {
|
} else if (!prebuilt->index_usable) {
|
||||||
DBUG_RETURN(DB_MISSING_HISTORY);
|
DBUG_RETURN(DB_MISSING_HISTORY);
|
||||||
|
} else if (prebuilt->index->is_corrupted()) {
|
||||||
} else if (dict_index_is_corrupted(prebuilt->index)) {
|
|
||||||
|
|
||||||
DBUG_RETURN(DB_CORRUPTION);
|
DBUG_RETURN(DB_CORRUPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user