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-15 16:00:57+04:00, gluh@stripped +2 -0
Bug#32178 server crash when select from i_s and concurrent partition management(2nd version)
The crash happens because of the following problem:
prep_alter_part_table() func uses table name lock
but I_S table opening does not use it.
In I_S during table processing we can get discrepancy
between share->partition_info and total number of partitions
which is obtained from par file.
The fix:
check if partition info is synchronized
with the information in par file.
Total number of partitons in part_info should be
less than ha_partition::m_tot_parts value.
Otherwise we skip file->get_dynamic_partition_info() call
(see store_schema_partitions_record() func).
sql/sql_show.cc@stripped, 2007-11-15 16:00:55+04:00, gluh@stripped +47 -40
The fix:
check if partition info is synchronized
with the information in par file.
Total number of partitons in part_info should be
less than ha_partition::m_tot_parts value.
Otherwise we skip file->get_dynamic_partition_info() call
(see store_schema_partitions_record() func).
sql/table.cc@stripped, 2007-11-15 16:00:55+04:00, gluh@stripped +8 -1
added check for the result of mysql_unpack_partition()
diff -Nrup a/sql/sql_show.cc b/sql/sql_show.cc
--- a/sql/sql_show.cc 2007-10-23 13:20:49 +05:00
+++ b/sql/sql_show.cc 2007-11-15 16:00:55 +04:00
@@ -4608,48 +4608,52 @@ static void collect_partition_expr(List<
static void store_schema_partitions_record(THD *thd, TABLE *schema_table,
TABLE *showing_table,
partition_element *part_elem,
- handler *file, uint part_id)
+ handler *file, uint part_id,
+ uint total_part_no)
{
TABLE* table= schema_table;
CHARSET_INFO *cs= system_charset_info;
PARTITION_INFO stat_info;
MYSQL_TIME time;
- file->get_dynamic_partition_info(&stat_info, part_id);
- table->field[12]->store((longlong) stat_info.records, TRUE);
- table->field[13]->store((longlong) stat_info.mean_rec_length, TRUE);
- table->field[14]->store((longlong) stat_info.data_file_length, TRUE);
- if (stat_info.max_data_file_length)
+ if (total_part_no > part_id)
{
- table->field[15]->store((longlong) stat_info.max_data_file_length, TRUE);
- table->field[15]->set_notnull();
- }
- table->field[16]->store((longlong) stat_info.index_file_length, TRUE);
- table->field[17]->store((longlong) stat_info.delete_length, TRUE);
- if (stat_info.create_time)
- {
- thd->variables.time_zone->gmt_sec_to_TIME(&time,
- (my_time_t)stat_info.create_time);
- table->field[18]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
- table->field[18]->set_notnull();
- }
- if (stat_info.update_time)
- {
- thd->variables.time_zone->gmt_sec_to_TIME(&time,
- (my_time_t)stat_info.update_time);
- table->field[19]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
- table->field[19]->set_notnull();
- }
- if (stat_info.check_time)
- {
- thd->variables.time_zone->gmt_sec_to_TIME(&time,
- (my_time_t)stat_info.check_time);
- table->field[20]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
- table->field[20]->set_notnull();
- }
- if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
- {
- table->field[21]->store((longlong) stat_info.check_sum, TRUE);
- table->field[21]->set_notnull();
+ file->get_dynamic_partition_info(&stat_info, part_id);
+ table->field[12]->store((longlong) stat_info.records, TRUE);
+ table->field[13]->store((longlong) stat_info.mean_rec_length, TRUE);
+ table->field[14]->store((longlong) stat_info.data_file_length, TRUE);
+ if (stat_info.max_data_file_length)
+ {
+ table->field[15]->store((longlong) stat_info.max_data_file_length, TRUE);
+ table->field[15]->set_notnull();
+ }
+ table->field[16]->store((longlong) stat_info.index_file_length, TRUE);
+ table->field[17]->store((longlong) stat_info.delete_length, TRUE);
+ if (stat_info.create_time)
+ {
+ thd->variables.time_zone->
+ gmt_sec_to_TIME(&time,(my_time_t)stat_info.create_time);
+ table->field[18]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[18]->set_notnull();
+ }
+ if (stat_info.update_time)
+ {
+ thd->variables.time_zone->
+ gmt_sec_to_TIME(&time, (my_time_t)stat_info.update_time);
+ table->field[19]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[19]->set_notnull();
+ }
+ if (stat_info.check_time)
+ {
+ thd->variables.time_zone->gmt_sec_to_TIME(&time,
+ (my_time_t)stat_info.check_time);
+ table->field[20]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[20]->set_notnull();
+ }
+ if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
+ {
+ table->field[21]->store((longlong) stat_info.check_sum, TRUE);
+ table->field[21]->set_notnull();
+ }
}
if (part_elem)
{
@@ -4667,7 +4671,7 @@ static void store_schema_partitions_reco
if (part_elem->tablespace_name)
table->field[24]->store(part_elem->tablespace_name,
strlen(part_elem->tablespace_name), cs);
- else
+ else if (total_part_no > part_id)
{
char *ts= showing_table->file->get_tablespace_name(thd,0,0);
if(ts)
@@ -4715,7 +4719,10 @@ static int get_schema_partitions_record(
partition_element *part_elem;
List_iterator<partition_element> part_it(part_info->partitions);
uint part_pos= 0, part_id= 0;
+ uint no_parts= 0;
+
+ file->get_no_parts(show_table->s->normalized_path.str, &no_parts);
restore_record(table, s->default_values);
table->field[1]->store(db_name->str, db_name->length, cs);
table->field[2]->store(table_name->str, table_name->length, cs);
@@ -4856,7 +4863,7 @@ static int get_schema_partitions_record(
table->field[6]->set_notnull();
store_schema_partitions_record(thd, table, show_table, subpart_elem,
- file, part_id);
+ file, part_id, no_parts);
part_id++;
if(schema_table_store_record(thd, table))
DBUG_RETURN(1);
@@ -4865,7 +4872,7 @@ static int get_schema_partitions_record(
else
{
store_schema_partitions_record(thd, table, show_table, part_elem,
- file, part_id);
+ file, part_id, no_parts);
part_id++;
if(schema_table_store_record(thd, table))
DBUG_RETURN(1);
@@ -4876,7 +4883,7 @@ static int get_schema_partitions_record(
else
#endif
{
- store_schema_partitions_record(thd, table, show_table, 0, file, 0);
+ store_schema_partitions_record(thd, table, show_table, 0, file, 0, 1);
if(schema_table_store_record(thd, table))
DBUG_RETURN(1);
}
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-15 16:00:55 +04:00
@@ -1784,12 +1784,18 @@ 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_error;
+ }
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
caller's arena depending on work_part_info_used value
*/
- if (!tmp && !work_part_info_used)
+ if (!work_part_info_used)
tmp= fix_partition_func(thd, outparam, is_create_table);
thd->stmt_arena= backup_stmt_arena_ptr;
thd->restore_active_arena(&part_func_arena, &backup_arena);
@@ -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_error:
if (tmp)
{
if (is_create_table)
| Thread |
|---|
| • bk commit into 5.1 tree (gluh:1.2610) BUG#32178 | gluh | 15 Nov |