Commit 7729fc9f authored by unknown's avatar unknown

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.
parent abad0dee
...@@ -3984,6 +3984,7 @@ static int fast_end_partition(THD *thd, ulonglong copied, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment