天天看点

[MySQL Bug]对一个已经discard tablespace的表做DDL导致crash

————————————————–

该bug在mysql的内部版本号为bug13943231,并且很容易触发该bug

1.test case:

create table t1(c1 int) engine=innodb;

alter table t1 discard tablespace;

alter table t1 add unique index(c1);

2.原因:

mysql的discard tablespace操作实际上已经删除了.ibd文件,但在innodb层并没有判断该行为,而是继续执行下去,因此很快就触发断言失败,以下是一次crash的backtrace:

(gdb) f 2

#2 0x000000000089a39b in fil_space_get_latch (id=5988266, flags=0x4a20ed20)

at /home/yinfeng.zwx/project/ps5518/trunk/percona-server-5.5.18/storage/innobase/fil/fil0fil.c:537

537 ut_a(space);

(gdb) l

532

533 mutex_enter(&fil_system->mutex);

534

535 space = fil_space_get_by_id(id);

536

538

539 if (flags) {

540 *flags = space->flags;

541 }

(gdb) p space

$1 = (fil_space_t *) 0x0

#2 fil_space_get_latch

#3 fseg_create_general

#4 btr_create

#5 dict_create_index_tree_step

#6 dict_create_index_step

#7 que_thr_step

#8 que_run_threads_low

#9 que_run_threads

#10 row_merge_create_index_graph

#11 row_merge_create_index

#12 ha_innobase::add_index

3.修复(来自官方):

修复的方法很简单,就是在add_index时判断是否已经discard tablespace了,如果是,就返回错误。

=== modified file ‘storage/innobase/handler/handler0alter.cc’

— storage/innobase/handler/handler0alter.cc   2012-02-28 12:04:21 +0000

+++ storage/innobase/handler/handler0alter.cc   2012-05-16 11:03:22 +0000

@@ -708,6 +708,10 @@

ut_a(indexed_table == prebuilt->table);

+       if (indexed_table->tablespace_discarded) {

+               dbug_return(-1);

+       }

+

/* check that index keys are sensible */

error = innobase_check_index_keys(key_info, num_of_keys, prebuilt->table);