Bug#32178 server crash when select from i_s and concurrent partition management
The crash happens because we change share->partition_info where 'share' is global struct (it affects other threads which use the same 'share'). It causes discrepancy between 'share' and handler data. The fix: Move share->partition_info update into WFRM_INSTALL_SHADOW part which is protected by OPEN_lock. sql/sql_partition.cc: fast_end_partition: added close_thread_tables() for the case when error occures fast_alter_partition_table: added close_thread_tables() for the case when error occures sql/sql_table.cc: The crash happens because we change share->partition_info where 'share' is global struct. It causes discrepancy between 'share' and handler data. The fix: Move share->partition_info update into WFRM_INSTALL_SHADOW part which is protected by OPEN_lock.
This commit is contained in:
parent
339e8f5d63
commit
6b3fed49ea
@ -3984,6 +3984,7 @@ static int fast_end_partition(THD *thd, ulonglong copied,
|
|||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
table->file->print_error(error, MYF(0));
|
table->file->print_error(error, MYF(0));
|
||||||
|
close_thread_tables(thd);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6106,7 +6107,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
|||||||
(error= table->file->repair_partitions(thd))))
|
(error= table->file->repair_partitions(thd))))
|
||||||
{
|
{
|
||||||
table->file->print_error(error, MYF(0));
|
table->file->print_error(error, MYF(0));
|
||||||
DBUG_RETURN(TRUE);
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fast_alter_partition & HA_PARTITION_ONE_PHASE)
|
else if (fast_alter_partition & HA_PARTITION_ONE_PHASE)
|
||||||
@ -6153,7 +6154,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
|||||||
if (mysql_write_frm(lpt, WFRM_WRITE_SHADOW | WFRM_PACK_FRM) ||
|
if (mysql_write_frm(lpt, WFRM_WRITE_SHADOW | WFRM_PACK_FRM) ||
|
||||||
mysql_change_partitions(lpt))
|
mysql_change_partitions(lpt))
|
||||||
{
|
{
|
||||||
DBUG_RETURN(TRUE);
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (alter_info->flags == ALTER_DROP_PARTITION)
|
else if (alter_info->flags == ALTER_DROP_PARTITION)
|
||||||
@ -6246,7 +6247,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
|||||||
(release_name_lock(lpt), FALSE))
|
(release_name_lock(lpt), FALSE))
|
||||||
{
|
{
|
||||||
handle_alter_part_error(lpt, not_completed, TRUE, frm_install);
|
handle_alter_part_error(lpt, not_completed, TRUE, frm_install);
|
||||||
DBUG_RETURN(TRUE);
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((alter_info->flags & ALTER_ADD_PARTITION) &&
|
else if ((alter_info->flags & ALTER_ADD_PARTITION) &&
|
||||||
@ -6315,7 +6316,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
|||||||
(release_name_lock(lpt), FALSE))
|
(release_name_lock(lpt), FALSE))
|
||||||
{
|
{
|
||||||
handle_alter_part_error(lpt, not_completed, FALSE, frm_install);
|
handle_alter_part_error(lpt, not_completed, FALSE, frm_install);
|
||||||
DBUG_RETURN(TRUE);
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -6408,7 +6409,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
|||||||
(release_name_lock(lpt), FALSE))
|
(release_name_lock(lpt), FALSE))
|
||||||
{
|
{
|
||||||
handle_alter_part_error(lpt, not_completed, FALSE, frm_install);
|
handle_alter_part_error(lpt, not_completed, FALSE, frm_install);
|
||||||
DBUG_RETURN(TRUE);
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -6418,6 +6419,9 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
|||||||
DBUG_RETURN(fast_end_partition(thd, lpt->copied, lpt->deleted,
|
DBUG_RETURN(fast_end_partition(thd, lpt->copied, lpt->deleted,
|
||||||
table, table_list, FALSE, NULL,
|
table, table_list, FALSE, NULL,
|
||||||
written_bin_log));
|
written_bin_log));
|
||||||
|
err:
|
||||||
|
close_thread_tables(thd);
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1248,6 +1248,10 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
|
|||||||
char shadow_path[FN_REFLEN+1];
|
char shadow_path[FN_REFLEN+1];
|
||||||
char shadow_frm_name[FN_REFLEN+1];
|
char shadow_frm_name[FN_REFLEN+1];
|
||||||
char frm_name[FN_REFLEN+1];
|
char frm_name[FN_REFLEN+1];
|
||||||
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
|
char *part_syntax_buf;
|
||||||
|
uint syntax_len;
|
||||||
|
#endif
|
||||||
DBUG_ENTER("mysql_write_frm");
|
DBUG_ENTER("mysql_write_frm");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1271,12 +1275,8 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
|
|||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
{
|
{
|
||||||
partition_info *part_info= lpt->table->part_info;
|
partition_info *part_info= lpt->table->part_info;
|
||||||
char *part_syntax_buf;
|
|
||||||
uint syntax_len;
|
|
||||||
|
|
||||||
if (part_info)
|
if (part_info)
|
||||||
{
|
{
|
||||||
TABLE_SHARE *share= lpt->table->s;
|
|
||||||
if (!(part_syntax_buf= generate_partition_syntax(part_info,
|
if (!(part_syntax_buf= generate_partition_syntax(part_info,
|
||||||
&syntax_len,
|
&syntax_len,
|
||||||
TRUE, TRUE)))
|
TRUE, TRUE)))
|
||||||
@ -1284,16 +1284,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
|
|||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
part_info->part_info_string= part_syntax_buf;
|
part_info->part_info_string= part_syntax_buf;
|
||||||
share->partition_info_len= part_info->part_info_len= syntax_len;
|
part_info->part_info_len= syntax_len;
|
||||||
if (share->partition_info_buffer_size < syntax_len + 1)
|
|
||||||
{
|
|
||||||
share->partition_info_buffer_size= syntax_len+1;
|
|
||||||
if (!(share->partition_info=
|
|
||||||
(char*) alloc_root(&share->mem_root, syntax_len+1)))
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
|
|
||||||
}
|
|
||||||
memcpy((char*) share->partition_info, part_syntax_buf, syntax_len + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1371,7 +1362,40 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
error= 1;
|
error= 1;
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
|
if (part_info)
|
||||||
|
{
|
||||||
|
TABLE_SHARE *share= lpt->table->s;
|
||||||
|
char *tmp_part_syntax_str;
|
||||||
|
if (!(part_syntax_buf= generate_partition_syntax(part_info,
|
||||||
|
&syntax_len,
|
||||||
|
TRUE, TRUE)))
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (share->partition_info_buffer_size < syntax_len + 1)
|
||||||
|
{
|
||||||
|
share->partition_info_buffer_size= syntax_len+1;
|
||||||
|
if (!(tmp_part_syntax_str= (char*) strmake_root(&share->mem_root,
|
||||||
|
part_syntax_buf,
|
||||||
|
syntax_len)))
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
share->partition_info= tmp_part_syntax_str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memcpy((char*) share->partition_info, part_syntax_buf, syntax_len + 1);
|
||||||
|
share->partition_info_len= part_info->part_info_len= syntax_len;
|
||||||
|
part_info->part_info_string= part_syntax_buf;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
err:
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos);
|
deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user