Skip to content
Permalink
Browse files

MDEV-10555: Server crashes in mysql_admin_table upon killing ANALYZE

Take into acount result of open table operation in mysql_admin_table.
  • Loading branch information...
Oleksandr Byelkin
Oleksandr Byelkin committed Mar 8, 2017
1 parent eded624 commit c0fb7b458bd6d555161994a5dd9f73495105cf66
Showing with 90 additions and 45 deletions.
  1. +10 −0 mysql-test/r/analyze_debug.result
  2. +13 −0 mysql-test/t/analyze_debug.test
  3. +67 −45 sql/sql_admin.cc
@@ -0,0 +1,10 @@
SET @save_use_stat_tables= @@use_stat_tables;
SET use_stat_tables= PREFERABLY;
CREATE TABLE t1 (a int);
insert into t1 values (1),(2),(3);
SET STATEMENT debug_dbug="d,fail_2call_open_only_one_table" for
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status Operation failed
drop table t1;
SET use_stat_tables= @save_use_stat_tables;
@@ -0,0 +1,13 @@

--source include/have_debug.inc

SET @save_use_stat_tables= @@use_stat_tables;
SET use_stat_tables= PREFERABLY;
CREATE TABLE t1 (a int);
insert into t1 values (1),(2),(3);

SET STATEMENT debug_dbug="d,fail_2call_open_only_one_table" for
ANALYZE TABLE t1;

drop table t1;
SET use_stat_tables= @save_use_stat_tables;
@@ -295,6 +295,10 @@ static inline bool table_not_corrupt_error(uint sql_errno)
sql_errno == ER_WRONG_OBJECT);
}

#ifndef DBUG_OFF
// It is counter for debugging fail on second call of open_only_one_table
static int debug_fail_counter= 0;
#endif

static bool open_only_one_table(THD* thd, TABLE_LIST* table,
bool repair_table_use_frm,
@@ -319,6 +323,16 @@ static bool open_only_one_table(THD* thd, TABLE_LIST* table,
lex->query_tables_last= &table->next_global;
lex->query_tables_own_last= 0;

DBUG_EXECUTE_IF("fail_2call_open_only_one_table", {
if (debug_fail_counter)
{
open_error= TRUE;
goto dbug_err;
}
else
debug_fail_counter++;
});

/*
CHECK TABLE command is allowed for views as well. Check on alter flags
to differentiate from ALTER TABLE...CHECK PARTITION on which view is not
@@ -378,6 +392,9 @@ static bool open_only_one_table(THD* thd, TABLE_LIST* table,
open_error= (thd->open_temporary_tables(table) ||
open_and_lock_tables(thd, table, TRUE, 0));
}

dbug_err:

thd->prepare_derived_at_open= FALSE;

/*
@@ -807,59 +824,64 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
repair_table_use_frm, FALSE);
thd->open_options&= ~extra_open_options;

TABLE *tab= table->table;
Field **field_ptr= tab->field;
if (!lex->column_list)
if (!open_error)
{
bitmap_clear_all(tab->read_set);
for (uint fields= 0; *field_ptr; field_ptr++, fields++)
TABLE *tab= table->table;
Field **field_ptr= tab->field;
if (!lex->column_list)
{
enum enum_field_types type= (*field_ptr)->type();
if (type < MYSQL_TYPE_MEDIUM_BLOB ||
type > MYSQL_TYPE_BLOB)
bitmap_set_bit(tab->read_set, fields);
else
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_NO_EIS_FOR_FIELD,
ER_THD(thd, ER_NO_EIS_FOR_FIELD),
(*field_ptr)->field_name);
bitmap_clear_all(tab->read_set);
for (uint fields= 0; *field_ptr; field_ptr++, fields++)
{
enum enum_field_types type= (*field_ptr)->type();
if (type < MYSQL_TYPE_MEDIUM_BLOB ||
type > MYSQL_TYPE_BLOB)
bitmap_set_bit(tab->read_set, fields);
else
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_NO_EIS_FOR_FIELD,
ER_THD(thd, ER_NO_EIS_FOR_FIELD),
(*field_ptr)->field_name);
}
}
}
else
{
int pos;
LEX_STRING *column_name;
List_iterator_fast<LEX_STRING> it(*lex->column_list);

bitmap_clear_all(tab->read_set);
while ((column_name= it++))
else
{
if (tab->s->fieldnames.type_names == 0 ||
(pos= find_type(&tab->s->fieldnames, column_name->str,
column_name->length, 1)) <= 0)
int pos;
LEX_STRING *column_name;
List_iterator_fast<LEX_STRING> it(*lex->column_list);

bitmap_clear_all(tab->read_set);
while ((column_name= it++))
{
compl_result_code= result_code= HA_ADMIN_INVALID;
break;
if (tab->s->fieldnames.type_names == 0 ||
(pos= find_type(&tab->s->fieldnames, column_name->str,
column_name->length, 1)) <= 0)
{
compl_result_code= result_code= HA_ADMIN_INVALID;
break;
}
pos--;
enum enum_field_types type= tab->field[pos]->type();
if (type < MYSQL_TYPE_MEDIUM_BLOB ||
type > MYSQL_TYPE_BLOB)
bitmap_set_bit(tab->read_set, pos);
else
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_NO_EIS_FOR_FIELD,
ER_THD(thd, ER_NO_EIS_FOR_FIELD),
column_name->str);
}
pos--;
enum enum_field_types type= tab->field[pos]->type();
if (type < MYSQL_TYPE_MEDIUM_BLOB ||
type > MYSQL_TYPE_BLOB)
bitmap_set_bit(tab->read_set, pos);
else
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_NO_EIS_FOR_FIELD,
ER_THD(thd, ER_NO_EIS_FOR_FIELD),
column_name->str);
tab->file->column_bitmaps_signal();
}
tab->file->column_bitmaps_signal();
if (!(compl_result_code=
alloc_statistics_for_table(thd, table->table)) &&
!(compl_result_code=
collect_statistics_for_table(thd, table->table)))
compl_result_code= update_statistics_for_table(thd, table->table);
}
if (!open_error &&
!(compl_result_code=
alloc_statistics_for_table(thd, table->table)) &&
!(compl_result_code=
collect_statistics_for_table(thd, table->table)))
compl_result_code= update_statistics_for_table(thd, table->table);
else
compl_result_code= HA_ADMIN_FAILED;

if (compl_result_code)
result_code= HA_ADMIN_FAILED;
else

0 comments on commit c0fb7b4

Please sign in to comment.
You can’t perform that action at this time.