From: Mattias Jonsson Date: November 5 2010 11:01am Subject: bzr commit into mysql-5.5-bugteam branch (mattias.jonsson:3115) Bug#57778 List-Archive: http://lists.mysql.com/commits/122935 X-Bug: 57778 Message-Id: <201011051102.oA59alaW015732@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============2343680460473275278==" --===============2343680460473275278== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///Users/mattiasj/mysql-bzr/b57778-55-bt/ based on revid:georgi.kodinov@stripped 3115 Mattias Jonsson 2010-11-05 Bug#57778: failed primary key add to partitioned innodb table inconsistent and crashes It was possible to issue an ALTER TABLE ADD PRIMARY KEY on an partitioned InnoDB table that failed and crashed the server. The problem was that it succeeded to create the PK on at least one partition, and then failed on a subsequent partition, due to duplicate key violation. Since the partitions that already had added the PK was not reverted all partitions was not consistent with the table definition, which caused the crash. The solution was to add a revert step to ha_partition::add_index() that dropped the index for the already succeeded partitions, on failure. @ mysql-test/r/partition.result updated result @ mysql-test/t/partition.test Added test @ sql/ha_partition.cc Only allow ADD/DROP flags in pairs, so that they can be reverted on failures. If add_index() fails for a partition, revert (drop the index) for the previous partitions. @ sql/handler.h Added some extra info in a comment. modified: mysql-test/r/partition.result mysql-test/t/partition.test sql/ha_partition.cc sql/handler.h === modified file 'mysql-test/r/partition.result' --- a/mysql-test/r/partition.result 2010-10-01 14:06:10 +0000 +++ b/mysql-test/r/partition.result 2010-11-05 11:01:10 +0000 @@ -1,5 +1,38 @@ drop table if exists t1, t2; # +# Bug#57778: failed primary key add to partitioned innodb table +# inconsistent and crashes +# +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL) +PARTITION BY KEY (a) PARTITIONS 2; +INSERT INTO t1 VALUES (0,1), (0,2); +ALTER TABLE t1 ADD PRIMARY KEY (a); +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` int(11) NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY KEY (a) +PARTITIONS 2 */ +SELECT * FROM t1; +a b +0 1 +0 2 +UPDATE t1 SET a = 1, b = 1 WHERE a = 0 AND b = 2; +ALTER TABLE t1 ADD PRIMARY KEY (a); +SELECT * FROM t1; +a b +1 1 +0 1 +ALTER TABLE t1 DROP PRIMARY KEY; +SELECT * FROM t1; +a b +1 1 +0 1 +DROP TABLE t1; +# # Bug#57113: ha_partition::extra(ha_extra_function): # Assertion `m_extra_cache' failed CREATE TABLE t1 === modified file 'mysql-test/t/partition.test' --- a/mysql-test/t/partition.test 2010-10-01 14:06:10 +0000 +++ b/mysql-test/t/partition.test 2010-11-05 11:01:10 +0000 @@ -15,6 +15,24 @@ drop table if exists t1, t2; --enable_warnings --echo # +--echo # Bug#57778: failed primary key add to partitioned innodb table +--echo # inconsistent and crashes +--echo # +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL) +PARTITION BY KEY (a) PARTITIONS 2; +INSERT INTO t1 VALUES (0,1), (0,2); +--error ER_DUP_ENTRY +ALTER TABLE t1 ADD PRIMARY KEY (a); +SHOW CREATE TABLE t1; +SELECT * FROM t1; +UPDATE t1 SET a = 1, b = 1 WHERE a = 0 AND b = 2; +ALTER TABLE t1 ADD PRIMARY KEY (a); +SELECT * FROM t1; +ALTER TABLE t1 DROP PRIMARY KEY; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # --echo # Bug#57113: ha_partition::extra(ha_extra_function): --echo # Assertion `m_extra_cache' failed CREATE TABLE t1 === modified file 'sql/ha_partition.cc' --- a/sql/ha_partition.cc 2010-10-06 14:34:28 +0000 +++ b/sql/ha_partition.cc 2010-11-05 11:01:10 +0000 @@ -6375,9 +6375,42 @@ bool ha_partition::get_error_message(int */ uint ha_partition::alter_table_flags(uint flags) { + uint flags_to_return, flags_to_check; DBUG_ENTER("ha_partition::alter_table_flags"); - DBUG_RETURN(ht->alter_table_flags(flags) | - m_file[0]->alter_table_flags(flags)); + + flags_to_return= ht->alter_table_flags(flags); + flags_to_return|= m_file[0]->alter_table_flags(flags); + + /* + If one partition fails we must be able to revert the change for the other, + already altered, partitions. So both ADD and DROP can only be supported in + pairs. + */ + flags_to_check= HA_ONLINE_ADD_INDEX_NO_WRITES; + flags_to_check|= HA_ONLINE_DROP_INDEX_NO_WRITES; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + flags_to_check= HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES; + flags_to_check|= HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + flags_to_check= HA_ONLINE_ADD_PK_INDEX_NO_WRITES; + flags_to_check|= HA_ONLINE_DROP_PK_INDEX_NO_WRITES; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + flags_to_check= HA_ONLINE_ADD_INDEX; + flags_to_check|= HA_ONLINE_DROP_INDEX; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + flags_to_check= HA_ONLINE_ADD_UNIQUE_INDEX; + flags_to_check|= HA_ONLINE_DROP_UNIQUE_INDEX; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + flags_to_check= HA_ONLINE_ADD_PK_INDEX; + flags_to_check|= HA_ONLINE_DROP_PK_INDEX; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + DBUG_RETURN(flags_to_return); } @@ -6412,6 +6445,7 @@ int ha_partition::add_index(TABLE *table handler **file; int ret= 0; + DBUG_ENTER("ha_partition::add_index"); /* There has already been a check in fix_partition_func in mysql_alter_table before this call, which checks for unique/primary key violations of the @@ -6419,8 +6453,28 @@ int ha_partition::add_index(TABLE *table */ for (file= m_file; *file; file++) if ((ret= (*file)->add_index(table_arg, key_info, num_of_keys))) - break; - return ret; + goto err; + DBUG_RETURN(ret); +err: + if (file > m_file) + { + uint *key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys); + uint old_num_of_keys= table_arg->s->keys; + uint i; + /* The newly created keys have the last id's */ + for (i= 0; i < num_of_keys; i++) + key_numbers[i]= i + old_num_of_keys; + if (!table_arg->key_info) + table_arg->key_info= key_info; + while (--file >= m_file) + { + (void) (*file)->prepare_drop_index(table_arg, key_numbers, num_of_keys); + (void) (*file)->final_drop_index(table_arg); + } + if (table_arg->key_info == key_info) + table_arg->key_info= NULL; + } + DBUG_RETURN(ret); } === modified file 'sql/handler.h' --- a/sql/handler.h 2010-10-06 14:34:28 +0000 +++ b/sql/handler.h 2010-11-05 11:01:10 +0000 @@ -174,6 +174,8 @@ /* These bits are set if different kinds of indexes can be created off-line without re-create of the table (but with a table lock). + Partitioning needs both ADD and DROP to be supported by its underlying + handlers, due to error handling, see bug#57778. */ #define HA_ONLINE_ADD_INDEX_NO_WRITES (1L << 0) /*add index w/lock*/ #define HA_ONLINE_DROP_INDEX_NO_WRITES (1L << 1) /*drop index w/lock*/ --===============2343680460473275278== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/mattias.jonsson@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: mattias.jonsson@stripped\ # 8yw1yaervuchqy5g # target_branch: file:///Users/mattiasj/mysql-bzr/b57778-55-bt/ # testament_sha1: 0c73d125799283309bdc46e9962f3a30e8b039c4 # timestamp: 2010-11-05 12:01:24 +0100 # base_revision_id: georgi.kodinov@stripped\ # vaqdd1jpof0f25w2 # # Begin bundle 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 qNdRftDPkyGcpr/4u5IpwoSEO8onOA== --===============2343680460473275278==--