List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:September 9 2010 7:50am
Subject:bzr commit into mysql-5.5-runtime branch (jon.hauglid:3134) Bug#56494
View as plain text  
#At file:///export/home/x/mysql-5.5-runtime-bug56494/ based on revid:jon.hauglid@stripped

 3134 Jon Olav Hauglid	2010-09-09
      Bug #56494 Segfault in upgrade_shared_lock_to_exclusive() for
                 REPAIR of merge table
      
      This crash happened if a table maintenance statement (ANALYZE TABLE,
      REPAIR TABLE, etc.) was executed on a MERGE table and opening and 
      locking a child table failed. This could for example happen if a child
      table did not exist or if a lock timeout happened while waiting for
      a conflicting metadata lock to disappear.
      
      Since opening and locking the MERGE table and its children failed,
      the tables would be closed and the metadata locks released.
      However, TABLE_LIST::table for the MERGE table would still be set,
      with its value invalid since the tables had been closed.
      This caused the table maintenance statement to try to continue
      and upgrade the metadata lock on the MERGE table. But since the lock
      already had been released, this caused a segfault.
      
      This patch fixes the problem by setting TABLE_LIST::table to NULL 
      if open_and_lock_tables() fails. This prevents the maintenance
      statement from continuing and trying to upgrade the metadata lock.
      The patch also fixes a problem where REPAIR TABLE ... USE_FRM
      would cause an assert for MERGE tables, even if child tables
      were opened successfully.
      
      Test case added to mdl_sync.test.

    modified:
      mysql-test/r/log_tables_upgrade.result
      mysql-test/r/mdl_sync.result
      mysql-test/r/merge.result
      mysql-test/r/myisampack.result
      mysql-test/r/mysql_upgrade.result
      mysql-test/r/mysql_upgrade_ssl.result
      mysql-test/t/mdl_sync.test
      sql/sql_admin.cc
=== modified file 'mysql-test/r/log_tables_upgrade.result'
--- a/mysql-test/r/log_tables_upgrade.result	2010-02-26 12:22:48 +0000
+++ b/mysql-test/r/log_tables_upgrade.result	2010-09-09 07:50:04 +0000
@@ -19,7 +19,7 @@ mysql.event                             
 mysql.func                                         OK
 mysql.general_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.help_category                                OK
 mysql.help_keyword                                 OK
 mysql.help_relation                                OK
@@ -33,7 +33,7 @@ mysql.renamed_general_log               
 mysql.servers                                      OK
 mysql.slow_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.tables_priv                                  OK
 mysql.time_zone                                    OK
 mysql.time_zone_leap_second                        OK
@@ -41,6 +41,10 @@ mysql.time_zone_name                    
 mysql.time_zone_transition                         OK
 mysql.time_zone_transition_type                    OK
 mysql.user                                         OK
+
+Repairing tables
+mysql.general_log                                  OK
+mysql.slow_log                                     OK
 DROP TABLE general_log;
 RENAME TABLE renamed_general_log TO general_log;
 SET GLOBAL general_log = @saved_general_log;

=== modified file 'mysql-test/r/mdl_sync.result'
--- a/mysql-test/r/mdl_sync.result	2010-09-08 08:25:37 +0000
+++ b/mysql-test/r/mdl_sync.result	2010-09-09 07:50:04 +0000
@@ -2951,3 +2951,47 @@ SET DEBUG_SYNC= 'now SIGNAL continue';
 # Connection default
 DROP TABLE m1, t1, t2;
 SET DEBUG_SYNC= 'RESET';
+#
+# Bug#56494 Segfault in upgrade_shared_lock_to_exclusive() for
+#           REPAIR of merge table
+#
+DROP TABLE IF EXISTS t1, t2, t_not_exists;
+CREATE TABLE t1(a INT);
+ALTER TABLE t1 engine= MERGE UNION (t_not_exists);
+ANALYZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	Error	Table 'test.t_not_exists' doesn't exist
+test.t1	analyze	Error	Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+test.t1	analyze	error	Corrupt
+CHECK TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	check	Error	Table 'test.t_not_exists' doesn't exist
+test.t1	check	Error	Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+test.t1	check	error	Corrupt
+CHECKSUM TABLE t1;
+Table	Checksum
+test.t1	NULL
+Warnings:
+Error	1146	Table 'test.t_not_exists' doesn't exist
+Error	1168	Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+OPTIMIZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	Error	Table 'test.t_not_exists' doesn't exist
+test.t1	optimize	Error	Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+test.t1	optimize	error	Corrupt
+REPAIR TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	Error	Table 'test.t_not_exists' doesn't exist
+test.t1	repair	Error	Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+test.t1	repair	error	Corrupt
+REPAIR TABLE t1 USE_FRM;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	Warning	Can't open table
+test.t1	repair	error	Corrupt
+DROP TABLE t1;
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(a INT) engine= MERGE UNION (t1);
+REPAIR TABLE t2 USE_FRM;
+Table	Op	Msg_type	Msg_text
+test.t2	repair	note	The storage engine for the table doesn't support repair
+DROP TABLE t1, t2;

=== modified file 'mysql-test/r/merge.result'
--- a/mysql-test/r/merge.result	2010-09-08 08:25:37 +0000
+++ b/mysql-test/r/merge.result	2010-09-09 07:50:04 +0000
@@ -2677,7 +2677,7 @@ OPTIMIZE TABLE t1;
 Table	Op	Msg_type	Msg_text
 test.t1	optimize	Error	Table 'test.t_not_exists' doesn't exist
 test.t1	optimize	Error	Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
-test.t1	optimize	note	The storage engine for the table doesn't support optimize
+test.t1	optimize	error	Corrupt
 DROP TABLE t1;
 #
 # Bug#36171 - CREATE TEMPORARY TABLE and MERGE engine

=== modified file 'mysql-test/r/myisampack.result'
--- a/mysql-test/r/myisampack.result	2009-11-26 12:47:55 +0000
+++ b/mysql-test/r/myisampack.result	2010-09-09 07:50:04 +0000
@@ -46,14 +46,12 @@ insert into t1 select * from t1;
 flush tables;
 optimize table t1;
 Table	Op	Msg_type	Msg_text
-test.t1	optimize	error	Table 'test.t1' is read only
-Warnings:
-Error	1036	Table 't1' is read only
+test.t1	optimize	Error	Table 't1' is read only
+test.t1	optimize	error	Corrupt
 repair table t1;
 Table	Op	Msg_type	Msg_text
-test.t1	repair	error	Table 'test.t1' is read only
-Warnings:
-Error	1036	Table 't1' is read only
+test.t1	repair	Error	Table 't1' is read only
+test.t1	repair	error	Corrupt
 drop table t1;
 #
 # BUG#41541 - Valgrind warnings on packed MyISAM table

=== modified file 'mysql-test/r/mysql_upgrade.result'
--- a/mysql-test/r/mysql_upgrade.result	2010-07-05 10:22:13 +0000
+++ b/mysql-test/r/mysql_upgrade.result	2010-09-09 07:50:04 +0000
@@ -7,7 +7,7 @@ mysql.event                             
 mysql.func                                         OK
 mysql.general_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.help_category                                OK
 mysql.help_keyword                                 OK
 mysql.help_relation                                OK
@@ -20,7 +20,7 @@ mysql.procs_priv                        
 mysql.servers                                      OK
 mysql.slow_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.tables_priv                                  OK
 mysql.time_zone                                    OK
 mysql.time_zone_leap_second                        OK
@@ -28,6 +28,10 @@ mysql.time_zone_name                    
 mysql.time_zone_transition                         OK
 mysql.time_zone_transition_type                    OK
 mysql.user                                         OK
+
+Repairing tables
+mysql.general_log                                  OK
+mysql.slow_log                                     OK
 Run it again - should say already completed
 This installation of MySQL is already upgraded to VERSION, use --force if you still need to run mysql_upgrade
 Force should run it regardless of wether it's been run before
@@ -39,7 +43,7 @@ mysql.event                             
 mysql.func                                         OK
 mysql.general_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.help_category                                OK
 mysql.help_keyword                                 OK
 mysql.help_relation                                OK
@@ -52,7 +56,7 @@ mysql.procs_priv                        
 mysql.servers                                      OK
 mysql.slow_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.tables_priv                                  OK
 mysql.time_zone                                    OK
 mysql.time_zone_leap_second                        OK
@@ -60,6 +64,10 @@ mysql.time_zone_name                    
 mysql.time_zone_transition                         OK
 mysql.time_zone_transition_type                    OK
 mysql.user                                         OK
+
+Repairing tables
+mysql.general_log                                  OK
+mysql.slow_log                                     OK
 CREATE USER mysqltest1@'%' IDENTIFIED by 'sakila';
 GRANT ALL ON *.* TO mysqltest1@'%';
 Run mysql_upgrade with password protected account
@@ -71,7 +79,7 @@ mysql.event                             
 mysql.func                                         OK
 mysql.general_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.help_category                                OK
 mysql.help_keyword                                 OK
 mysql.help_relation                                OK
@@ -84,7 +92,7 @@ mysql.procs_priv                        
 mysql.servers                                      OK
 mysql.slow_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.tables_priv                                  OK
 mysql.time_zone                                    OK
 mysql.time_zone_leap_second                        OK
@@ -92,6 +100,10 @@ mysql.time_zone_name                    
 mysql.time_zone_transition                         OK
 mysql.time_zone_transition_type                    OK
 mysql.user                                         OK
+
+Repairing tables
+mysql.general_log                                  OK
+mysql.slow_log                                     OK
 DROP USER mysqltest1@'%';
 Run mysql_upgrade with a non existing server socket
 mysqlcheck: Got error: 2005: Unknown MySQL server host 'not_existing_host' (errno) when trying to connect
@@ -105,7 +117,7 @@ mysql.event                             
 mysql.func                                         OK
 mysql.general_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.help_category                                OK
 mysql.help_keyword                                 OK
 mysql.help_relation                                OK
@@ -118,7 +130,7 @@ mysql.procs_priv                        
 mysql.servers                                      OK
 mysql.slow_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.tables_priv                                  OK
 mysql.time_zone                                    OK
 mysql.time_zone_leap_second                        OK
@@ -126,6 +138,10 @@ mysql.time_zone_name                    
 mysql.time_zone_transition                         OK
 mysql.time_zone_transition_type                    OK
 mysql.user                                         OK
+
+Repairing tables
+mysql.general_log                                  OK
+mysql.slow_log                                     OK
 set GLOBAL sql_mode=default;
 #
 # Bug #41569 mysql_upgrade (ver 5.1) add 3 fields to mysql.proc table 
@@ -143,7 +159,7 @@ mysql.event                             
 mysql.func                                         OK
 mysql.general_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.help_category                                OK
 mysql.help_keyword                                 OK
 mysql.help_relation                                OK
@@ -156,7 +172,7 @@ mysql.procs_priv                        
 mysql.servers                                      OK
 mysql.slow_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.tables_priv                                  OK
 mysql.time_zone                                    OK
 mysql.time_zone_leap_second                        OK
@@ -164,6 +180,10 @@ mysql.time_zone_name                    
 mysql.time_zone_transition                         OK
 mysql.time_zone_transition_type                    OK
 mysql.user                                         OK
+
+Repairing tables
+mysql.general_log                                  OK
+mysql.slow_log                                     OK
 CALL testproc();
 DROP PROCEDURE testproc;
 WARNING: NULL values of the 'character_set_client' column ('mysql.proc' table) have been updated with a default value (latin1). Please verify if necessary.
@@ -184,7 +204,7 @@ mysql.event                             
 mysql.func                                         OK
 mysql.general_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.help_category                                OK
 mysql.help_keyword                                 OK
 mysql.help_relation                                OK
@@ -197,7 +217,7 @@ mysql.procs_priv                        
 mysql.servers                                      OK
 mysql.slow_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.tables_priv                                  OK
 mysql.time_zone                                    OK
 mysql.time_zone_leap_second                        OK
@@ -205,6 +225,10 @@ mysql.time_zone_name                    
 mysql.time_zone_transition                         OK
 mysql.time_zone_transition_type                    OK
 mysql.user                                         OK
+
+Repairing tables
+mysql.general_log                                  OK
+mysql.slow_log                                     OK
 SHOW GRANTS FOR 'user3'@'%';
 Grants for user3@%
 GRANT USAGE ON *.* TO 'user3'@'%'

=== modified file 'mysql-test/r/mysql_upgrade_ssl.result'
--- a/mysql-test/r/mysql_upgrade_ssl.result	2010-08-11 17:56:56 +0000
+++ b/mysql-test/r/mysql_upgrade_ssl.result	2010-09-09 07:50:04 +0000
@@ -9,7 +9,7 @@ mysql.event                             
 mysql.func                                         OK
 mysql.general_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.help_category                                OK
 mysql.help_keyword                                 OK
 mysql.help_relation                                OK
@@ -22,7 +22,7 @@ mysql.procs_priv                        
 mysql.servers                                      OK
 mysql.slow_log
 Error    : You can't use locks with log tables.
-status   : OK
+error    : Corrupt
 mysql.tables_priv                                  OK
 mysql.time_zone                                    OK
 mysql.time_zone_leap_second                        OK
@@ -30,3 +30,7 @@ mysql.time_zone_name                    
 mysql.time_zone_transition                         OK
 mysql.time_zone_transition_type                    OK
 mysql.user                                         OK
+
+Repairing tables
+mysql.general_log                                  OK
+mysql.slow_log                                     OK

=== modified file 'mysql-test/t/mdl_sync.test'
--- a/mysql-test/t/mdl_sync.test	2010-09-08 08:25:37 +0000
+++ b/mysql-test/t/mdl_sync.test	2010-09-09 07:50:04 +0000
@@ -4594,6 +4594,36 @@ disconnect con1;
 disconnect con2;
 
 
+--echo #
+--echo # Bug#56494 Segfault in upgrade_shared_lock_to_exclusive() for
+--echo #           REPAIR of merge table
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, t_not_exists;
+--enable_warnings
+
+CREATE TABLE t1(a INT);
+ALTER TABLE t1 engine= MERGE UNION (t_not_exists);
+# This caused the segfault
+ANALYZE TABLE t1;
+CHECK TABLE t1;
+CHECKSUM TABLE t1;
+OPTIMIZE TABLE t1;
+REPAIR TABLE t1;
+
+# This caused an assert
+REPAIR TABLE t1 USE_FRM;
+
+DROP TABLE t1;
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(a INT) engine= MERGE UNION (t1);
+# This caused an assert
+REPAIR TABLE t2 USE_FRM;
+
+DROP TABLE t1, t2;
+
+
 # Check that all connections opened by test cases in this file are really
 # gone so execution of other tests won't be affected by their presence.
 --source include/wait_until_count_sessions.inc

=== modified file 'sql/sql_admin.cc'
--- a/sql/sql_admin.cc	2010-08-18 11:29:04 +0000
+++ b/sql/sql_admin.cc	2010-09-09 07:50:04 +0000
@@ -112,7 +112,8 @@ static int prepare_for_repair(THD *thd, 
   }
 
   /* A MERGE table must not come here. */
-  DBUG_ASSERT(table->file->ht->db_type != DB_TYPE_MRG_MYISAM);
+  if (table->file->ht->db_type == DB_TYPE_MRG_MYISAM)
+    goto end;
 
   /*
     REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
@@ -320,6 +321,14 @@ static bool mysql_admin_table(THD* thd, 
       table->next_global= save_next_global;
       table->next_local= save_next_local;
       thd->open_options&= ~extra_open_options;
+
+      /*
+        If open_and_lock_tables() failed, close_thread_tables() will close
+        the table and table->table can therefore be invalid.
+      */
+      if (open_error)
+        table->table= NULL;
+
       /*
         Under locked tables, we know that the table can be opened,
         so any errors opening the table are logical errors.


Attachment: [text/bzr-bundle] bzr/jon.hauglid@oracle.com-20100909075004-qpouhrstqjwk05c0.bundle
Thread
bzr commit into mysql-5.5-runtime branch (jon.hauglid:3134) Bug#56494Jon Olav Hauglid9 Sep