Below is the list of changes that have just been committed into a local
5.1 repository of gluh. When gluh does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-11-21 21:12:35+04:00, gluh@stripped +3 -0
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 struc
(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@stripped, 2007-11-21 21:12:33+04:00, gluh@stripped +9 -5
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@stripped, 2007-11-21 21:12:33+04:00, gluh@stripped +38 -14
The crash happens because we change share->partition_info where 'share' is global struc.
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/table.cc@stripped, 2007-11-21 21:12:33+04:00, gluh@stripped +7 -0
added check for the result of mysql_unpack_partition()
diff -Nrup a/sql/sql_partition.cc b/sql/sql_partition.cc
--- a/sql/sql_partition.cc 2007-10-09 19:16:37 +05:00
+++ b/sql/sql_partition.cc 2007-11-21 21:12:33 +04:00
@@ -3971,6 +3971,7 @@ static int fast_end_partition(THD *thd,
DBUG_RETURN(FALSE);
}
table->file->print_error(error, MYF(0));
+ close_thread_tables(thd);
DBUG_RETURN(TRUE);
}
@@ -6090,7 +6091,7 @@ uint fast_alter_partition_table(THD *thd
(error= table->file->repair_partitions(thd))))
{
table->file->print_error(error, MYF(0));
- DBUG_RETURN(TRUE);
+ goto err;
}
}
else if (fast_alter_partition & HA_PARTITION_ONE_PHASE)
@@ -6137,7 +6138,7 @@ uint fast_alter_partition_table(THD *thd
if (mysql_write_frm(lpt, WFRM_WRITE_SHADOW | WFRM_PACK_FRM) ||
mysql_change_partitions(lpt))
{
- DBUG_RETURN(TRUE);
+ goto err;
}
}
else if (alter_info->flags == ALTER_DROP_PARTITION)
@@ -6230,7 +6231,7 @@ uint fast_alter_partition_table(THD *thd
(release_name_lock(lpt), FALSE))
{
handle_alter_part_error(lpt, not_completed, TRUE, frm_install);
- DBUG_RETURN(TRUE);
+ goto err;
}
}
else if ((alter_info->flags & ALTER_ADD_PARTITION) &&
@@ -6299,7 +6300,7 @@ uint fast_alter_partition_table(THD *thd
(release_name_lock(lpt), FALSE))
{
handle_alter_part_error(lpt, not_completed, FALSE, frm_install);
- DBUG_RETURN(TRUE);
+ goto err;
}
}
else
@@ -6392,7 +6393,7 @@ uint fast_alter_partition_table(THD *thd
(release_name_lock(lpt), FALSE))
{
handle_alter_part_error(lpt, not_completed, FALSE, frm_install);
- DBUG_RETURN(TRUE);
+ goto err;
}
}
/*
@@ -6402,6 +6403,9 @@ uint fast_alter_partition_table(THD *thd
DBUG_RETURN(fast_end_partition(thd, lpt->copied, lpt->deleted,
table, table_list, FALSE, NULL,
written_bin_log));
+err:
+ close_thread_tables(thd);
+ DBUG_RETURN(TRUE);
}
#endif
diff -Nrup a/sql/sql_table.cc b/sql/sql_table.cc
--- a/sql/sql_table.cc 2007-11-02 02:48:11 +04:00
+++ b/sql/sql_table.cc 2007-11-21 21:12:33 +04:00
@@ -1241,6 +1241,10 @@ bool mysql_write_frm(ALTER_PARTITION_PAR
char shadow_path[FN_REFLEN+1];
char shadow_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");
/*
@@ -1264,12 +1268,8 @@ bool mysql_write_frm(ALTER_PARTITION_PAR
#ifdef WITH_PARTITION_STORAGE_ENGINE
{
partition_info *part_info= lpt->table->part_info;
- char *part_syntax_buf;
- uint syntax_len;
-
if (part_info)
{
- TABLE_SHARE *share= lpt->table->s;
if (!(part_syntax_buf= generate_partition_syntax(part_info,
&syntax_len,
TRUE, TRUE)))
@@ -1277,16 +1277,7 @@ bool mysql_write_frm(ALTER_PARTITION_PAR
DBUG_RETURN(TRUE);
}
part_info->part_info_string= part_syntax_buf;
- share->partition_info_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);
+ part_info->part_info_len= syntax_len;
}
}
#endif
@@ -1364,7 +1355,40 @@ bool mysql_write_frm(ALTER_PARTITION_PAR
#endif
{
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));
#ifdef WITH_PARTITION_STORAGE_ENGINE
deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos);
diff -Nrup a/sql/table.cc b/sql/table.cc
--- a/sql/table.cc 2007-10-23 19:02:26 +05:00
+++ b/sql/table.cc 2007-11-21 21:12:33 +04:00
@@ -1784,6 +1784,12 @@ int open_table_from_share(THD *thd, TABL
outparam, is_create_table,
share->default_part_db_type,
&work_part_info_used);
+ if (tmp)
+ {
+ thd->stmt_arena= backup_stmt_arena_ptr;
+ thd->restore_active_arena(&part_func_arena, &backup_arena);
+ goto part_err;
+ }
outparam->part_info->is_auto_partitioned= share->auto_partitioned;
DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned));
/* we should perform the fix_partition_func in either local or
@@ -1799,6 +1805,7 @@ int open_table_from_share(THD *thd, TABL
tmp= fix_partition_func(thd, outparam, is_create_table);
outparam->part_info->item_free_list= part_func_arena.free_list;
}
+part_err:
if (tmp)
{
if (is_create_table)