List:Commits« Previous MessageNext Message »
From:Li-Bing.Song Date:September 16 2010 9:35am
Subject:bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3489) Bug#56226
View as plain text  
#At file:///home/anders/work/bzrwork1/wt2/mysql-5.1-bugteam/ based on revid:mattias.jonsson@stripped

 3489 Li-Bing.Song@stripped	2010-09-16
      Bug#56226  Table map set to 0 after altering MyISAM table
      
      A MyISAM table's table_map_id will always be reset to 0 after altered
      only its metadata. 0 is a valid value of table_map_id. But the problem will
      cause that more than one tables have the same table_map_id 0. If more than
      one tables which's table_map_id are 0 are updated in one statement, the update
      of these different tables will be write into only one rows event. It will
      cause slave server to crash. 
      
      After this patch, table_map_id always be refreshed as a correct value after
      altered only its metadata.
     @ mysql-test/suite/rpl/r/rpl_alter.result
        Add test for BUG#56226
     @ mysql-test/suite/rpl/t/rpl_alter.test
        Add test for BUG#56226
     @ sql/sql_base.cc
        The invalid value of table_map_id is ~0UL.
        So it should be set to ~0UL but not 0 when a SHARE is initialized
        and we don't want to give a valid value.
        Because of this, we are able to know if table_map_id is invalid and should
        be set a new value when reopenning the table.

    modified:
      mysql-test/suite/rpl/r/rpl_alter.result
      mysql-test/suite/rpl/t/rpl_alter.test
      sql/sql_base.cc
=== modified file 'mysql-test/suite/rpl/r/rpl_alter.result'
--- a/mysql-test/suite/rpl/r/rpl_alter.result	2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/r/rpl_alter.result	2010-09-16 09:35:41 +0000
@@ -19,3 +19,23 @@ select * from mysqltest.t3;
 n
 45
 drop database mysqltest;
+
+# BUG#56226 Table map set to 0 after altering MyISAM table
+
+SET SESSION binlog_format='ROW';
+USE test;
+CREATE TABLE t1 (a INT, b INT) ENGINE MyISAM;
+CREATE TABLE t2 (a VARCHAR(255), b VARCHAR(255)) ENGINE MyISAM;
+CREATE TRIGGER trg_t1ai 
+AFTER INSERT ON t1 FOR EACH ROW 
+BEGIN
+INSERT INTO t2 (a) VALUES (NEW.a);
+END;//
+ALTER TABLE t1 CHANGE b c INT;
+ALTER TABLE t2 CHANGE b c VARCHAR(255);
+
+INSERT INTO t1 (a) VALUES(2);
+Comparing tables master:test.t1 and slave:test.t1
+Comparing tables master:test.t2 and slave:test.t2
+
+DROP TABLE t1, t2;

=== modified file 'mysql-test/suite/rpl/t/rpl_alter.test'
--- a/mysql-test/suite/rpl/t/rpl_alter.test	2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/t/rpl_alter.test	2010-09-16 09:35:41 +0000
@@ -10,15 +10,62 @@ insert into mysqltest.t1 values (1,2);
 create table mysqltest.t2 (n int);
 insert into mysqltest.t2 values (45);
 rename table mysqltest.t2 to mysqltest.t3, mysqltest.t1 to mysqltest.t2;
-save_master_pos;
-connection slave;
-sync_with_master;
+
+sync_slave_with_master;
 select * from mysqltest.t2;
 select * from mysqltest.t3;
+
 connection master;
 drop database mysqltest;
-save_master_pos;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
+
+--echo
+--echo # BUG#56226 Table map set to 0 after altering MyISAM table
+--echo
+connection master;
+SET SESSION binlog_format='ROW';
+USE test;
+
+CREATE TABLE t1 (a INT, b INT) ENGINE MyISAM;
+CREATE TABLE t2 (a VARCHAR(255), b VARCHAR(255)) ENGINE MyISAM;
+
+--delimiter //
+CREATE TRIGGER trg_t1ai 
+  AFTER INSERT ON t1 FOR EACH ROW 
+BEGIN
+  INSERT INTO t2 (a) VALUES (NEW.a);
+END;//
+--delimiter ;
+
+ALTER TABLE t1 CHANGE b c INT;
+ALTER TABLE t2 CHANGE b c VARCHAR(255);
+let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+--echo
+INSERT INTO t1 (a) VALUES(2);
+let _info= query_get_value(SHOW BINLOG EVENTS IN '$binlog_file' FROM $binlog_start, Info, 2);
+# Table map id should not be 0.
+if (`SELECT 'table_id: 0 (test.t1)' = '$_info'`)
+{
+  --echo test.t1's table map id is 0;
+  --die test.t1's table map id is 0;
+}
+let _info= query_get_value(SHOW BINLOG EVENTS IN '$binlog_file' FROM $binlog_start, Info, 3);
+if (`SELECT 'table_id: 0 (test.t2)' = '$_info'`)
+{
+  --echo test.t2's table map id is 0;
+  --die test.t2's table map id is 0;
+}
+
+let diff_table= test.t1;
+source include/rpl_diff_tables.inc;
+let diff_table= test.t2;
+source include/rpl_diff_tables.inc;
+
+--echo
+connection master;
+DROP TABLE t1, t2;
 
+source include/master-slave-end.inc;
 # End of 4.1 tests

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-07-20 18:07:36 +0000
+++ b/sql/sql_base.cc	2010-09-16 09:35:41 +0000
@@ -662,6 +662,7 @@ void close_handle_and_leave_table_as_loc
     share->set_table_cache_key(key_buff, old_share->table_cache_key.str,
                                old_share->table_cache_key.length);
     share->tmp_table= INTERNAL_TMP_TABLE;       // for intern_close_table()
+    share->table_map_id= ~0UL;
   }
 
   /*
@@ -3082,7 +3083,8 @@ bool reopen_table(TABLE *table)
   tmp.maybe_null=	table->maybe_null;
   tmp.status=		table->status;
 
-  tmp.s->table_map_id=  table->s->table_map_id;
+  if (table->s->table_map_id != ~0UL)
+    tmp.s->table_map_id=  table->s->table_map_id;
 
   /* Get state */
   tmp.in_use=    	thd;


Attachment: [text/bzr-bundle] bzr/li-bing.song@sun.com-20100916093541-eu0x892s0hy8nd5a.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3489) Bug#56226Li-Bing.Song16 Sep
  • Re: bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3489)Bug#56226He Zhenxing17 Sep
  • Re: bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3489)Bug#56226Dmitry Lenev20 Sep
Re: bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3489)Bug#56226Libing Song20 Sep
  • Re: bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3489)Bug#56226Dmitry Lenev20 Sep
    • Re: bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3489)Bug#56226Libing Song20 Sep
Re: bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3489)Bug#56226Dmitry Lenev20 Sep
  • Re: bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3489)Bug#56226He Zhenxing20 Sep