From b3d77069e920a600d6efe4e06041d57732fa83e0 Mon Sep 17 00:00:00 2001 From: Timothy Smith Date: Sun, 14 Dec 2008 13:31:13 -0700 Subject: [PATCH] Apply InnoDB snapshot innodb-5.1-ss2858, part 4. Fixes Bug #39438: Testcase for Bug#39436 crashes on 5.1 in fil_space_get_latch Detailed revision comments: r2719 | vasil | 2008-10-03 18:17:28 +0300 (Fri, 03 Oct 2008) | 49 lines branches/5.1: Fix Bug#39438 Testcase for Bug#39436 crashes on 5.1 in fil_space_get_latch In ha_innobase::info() - do not try to get the free space for a tablespace which has been discarded with ALTER TABLE ... DISCARD TABLESPACE or if the .ibd file is missing for some other reason. ibd_file_missing and tablespace_discarded are manipulated only in row_discard_tablespace_for_mysql() and in row_import_tablespace_for_mysql() and the manipulation is protected/surrounded by row_mysql_lock_data_dictionary()/row_mysql_unlock_data_dictionary() thus we do the same in ha_innobase::info() when checking the values of those members to avoid race conditions. I have tested the code-path with UNIV_DEBUG and UNIV_SYNC_DEBUG. rb://20 Reviewed by: Inaam, Calvin Approved by: Heikki --- mysql-test/lib/mtr_report.pl | 5 ++++- mysql-test/r/innodb_bug39438.result | 1 + mysql-test/t/innodb_bug39438-master.opt | 1 + mysql-test/t/innodb_bug39438.test | 27 +++++++++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 21 ++++++++++++++++--- 5 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 mysql-test/r/innodb_bug39438.result create mode 100644 mysql-test/t/innodb_bug39438-master.opt create mode 100644 mysql-test/t/innodb_bug39438.test diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index 3c78c3ca064..e3fabccd86d 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -412,7 +412,10 @@ sub mtr_report_stats ($) { # When trying to set lower_case_table_names = 2 # on a case sensitive file system. Bug#37402. - /lower_case_table_names was set to 2, even though your the file system '.*' is case sensitive. Now setting lower_case_table_names to 0 to avoid future problems./ + /lower_case_table_names was set to 2, even though your the file system '.*' is case sensitive. Now setting lower_case_table_names to 0 to avoid future problems./ or + + # this test is expected to print warnings + ($testname eq 'main.innodb_bug39438') ) { next; # Skip these lines diff --git a/mysql-test/r/innodb_bug39438.result b/mysql-test/r/innodb_bug39438.result new file mode 100644 index 00000000000..195775f74c8 --- /dev/null +++ b/mysql-test/r/innodb_bug39438.result @@ -0,0 +1 @@ +SET storage_engine=InnoDB; diff --git a/mysql-test/t/innodb_bug39438-master.opt b/mysql-test/t/innodb_bug39438-master.opt new file mode 100644 index 00000000000..43fac202fd4 --- /dev/null +++ b/mysql-test/t/innodb_bug39438-master.opt @@ -0,0 +1 @@ +--innodb-file-per-table=1 diff --git a/mysql-test/t/innodb_bug39438.test b/mysql-test/t/innodb_bug39438.test new file mode 100644 index 00000000000..4dc3d957c39 --- /dev/null +++ b/mysql-test/t/innodb_bug39438.test @@ -0,0 +1,27 @@ +# +# Bug#39438 Testcase for Bug#39436 crashes on 5.1 in fil_space_get_latch +# http://bugs.mysql.com/39438 +# +# This test must be run with innodb_file_per_table=1 because the crash +# only occurs if that option is turned on and DISCARD TABLESPACE only +# works with innodb_file_per_table. +# + +-- source include/have_innodb.inc + +SET storage_engine=InnoDB; + +# we care only that the following SQL commands do not crash the server +-- disable_query_log +-- disable_result_log + +DROP TABLE IF EXISTS bug39438; + +CREATE TABLE bug39438 (id INT) ENGINE=INNODB; + +ALTER TABLE bug39438 DISCARD TABLESPACE; + +# this crashes the server if the bug is present +SHOW TABLE STATUS; + +DROP TABLE bug39438; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 600473c2cd2..6e4c3b736af 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5865,9 +5865,24 @@ ha_innobase::info( so the "old" value can remain. delete_length is initialized to 0 in the ha_statistics' constructor. */ if (!(flag & HA_STATUS_NO_LOCK)) { - stats.delete_length = - fsp_get_available_space_in_free_extents( - ib_table->space) * 1024; + + /* lock the data dictionary to avoid races with + ibd_file_missing and tablespace_discarded */ + row_mysql_lock_data_dictionary(prebuilt->trx); + + /* ib_table->space must be an existent tablespace */ + if (!ib_table->ibd_file_missing + && !ib_table->tablespace_discarded) { + + stats.delete_length = + fsp_get_available_space_in_free_extents( + ib_table->space) * 1024; + } else { + + stats.delete_length = 0; + } + + row_mysql_unlock_data_dictionary(prebuilt->trx); } stats.check_time = 0;