List:Commits« Previous MessageNext Message »
From:V Narayanan Date:July 27 2009 11:12am
Subject:Re: bzr commit into mysql-5.1-bugteam branch (v.narayanan:3039)
Bug#45800
View as plain text  
Hi Ingo,

Thank you for the review and the detailed comments. Pls find responses 
below.

Ingo Strüwing wrote:
> Hi VN,
>
> this is a good basis for the bug fix. The code change is probably ok. I
> just like to see a little more tests. Please see below for more comments.
>
> V Narayanan, 24.07.2009 14:31:
>
> ...
>   
>>  3039 V Narayanan	2009-07-24
>>       Bug#45800 crash when replacing into a merge table and there is a duplicate
>>       
>>       A REPLACE in the MERGE engine is actually a REPLACE
>>       into one (FIRST or LAST) of the underlying MyISAM
>>       tables. So in effect we have the meta data of the
>>       MERGE tables but we are inserting into a MyISAM table.
>>     
>
>
> I (believe to) understand, what you mean with the last sentence.
> However, I would prefer to try to improve it for other readers. It might
> be better to say that the SQL layer (or "the server") works on the meta
> data of the MERGE table, while the real insert happens in the MyISAM table.
>   
done!
>   
>>       
>>       When a REPLACE into a MERGE table (and the REPLACE
>>       conflicts with a duplicate in a child table) is done,
>>       we try to access the duplicate key information for
>>       the MERGE table. This information actually does not
>>       exist since it is the child tables that have keys
>>       and not the MERGE table. Hence this results in a crash.
>>     
>
>
> For a reader, who is not familiar with the problem, it might be easier
> to understand, if the fact, that MERGE has no index, while MyISAM has a
> unique index, is put to the beginning of this paragraph.
>   
done!
>   
>>       
>>       The problem can be resolved by modifying the MERGE
>>       engine to provide us the duplicate key information
>>       directly, instead of replying on the metadata on the
>>       server.
>>     
>
>
> I suggest: "..., instead of just returning the MyISAM index number as
> the error key. Then the SQL layer (or "the server") does not try to
> access the key_info of the MERGE table, which does not exist.
>   
done!
>   
>>       
>>       The current patch modifies the MERGE engine to provide
>>       the duplicate key information to the server.
>>      @ include/myisammrg.h
>>         Bug#45800 crash when replacing into a merge table and there is a
> duplicate
>>         
>>         Add a member to the st_mymerge_info structure that will
>>         store the duplicate key offset in the MERGE table. This
>>         offset will be the sum of the offset of the MyISAM table
>>         and the offset into the MERGE table.
>>     
>
>
> I'd say: "... the sum of the record offset of the MyISAM table within
> the MERGE table and the offset of the record within the MyISAM table."
>
> ...
>   
done!
>>      @ sql/handler.cc
>>         Bug#45800 crash when replacing into a merge table and there is a
> duplicate
>>         
>>         With the current change the MERGE engine will be able to
>>         return the duplicate key offset and will not use MAX_KEY
>>         as a error indicator. This adversely affects the case
>>         when we do a INSERT into a MERGE table that has a duplicate.
>>         
>>         An INSERT into a MERGE table having a duplicate causes the
>>         write into the storage engine to fail. When we print an error
>>         using print_keydup_error we access the key information from
>>         the server, causing a crash.
>>         
>>         This problem can be resolved by checking for the case
>>         when table->key_info is NULL.
>>     
>
>
> I prefer not to have long problem descriptions in file comments. With
> the leading line ("Bug#45800 ...") one can find the revision and the
> global revision comment, which explains this sufficiently.
>
> IMHO file comments should say, what has been changed. They can add a
> short reason, but in general reasoning should be done in the global
> comment. (Or in the bug report). Again, that's IMHO.
>
> In summary, I would leave away the middle paragraph.
>   
Ingo, I realized this change was not necessary. myrg_status returns the
key position on a MyISAM table. we could not have used this to index
this into table.key_info (errkey was primarily being used in the server
to derive information from table.key_info). we can set errkey = MAX_KEY
and keep using this as a sentinel value.

> ...
>   
>>      @ storage/myisammrg/myrg_info.c
>>         Bug#45800 crash when replacing into a merge table and there is a
> duplicate
>>         
>>         We modify the myrg_status function to return the position of the
>>         duplicate key. The duplicate key position in the MERGE table will
>>         be the MyISAM file_offset and the offset within the MyISAM table
>>         where the key is located.
>>     
>
>
> That's correct in so far as the key is part of the record. But to be
> exact, the offsets describe the start positions of the records.
>
> ...
>   
done!

I was in two minds on whether we should retain the setting of the errkey 
here.
It is anyway being set to the sentinel MAX_KEY in ha_myisammrg::info. 
But I decided
to let it remain for completeness and to retain the resemblance to the 
way this works
for the MyISAM storage engine.
>> === modified file 'mysql-test/t/merge.test'
>> --- a/mysql-test/t/merge.test	2009-07-15 23:23:57 +0000
>> +++ b/mysql-test/t/merge.test	2009-07-24 12:31:47 +0000
>> @@ -1515,6 +1515,34 @@ insert into m1 (col1) values (1);
>>  
>>  drop table m1, t1;
>>  
>> +--echo #
>> +--echo # Bug#45800 crash when replacing into a merge table and there is a
> duplicate
>> +--echo #
>> +
>> +--echo # Replace duplicate value in child table when merge table doesn't have
> key
>> +--echo # Create child table
>> +CREATE TABLE t1 (c1 INT PRIMARY KEY) ENGINE=MyISAM;
>> +--echo # Create Merge table
>> +CREATE TABLE m1 (c1 INT NOT NULL) ENGINE=MRG_MyISAM INSERT_METHOD=LAST
> UNION=(t1);
>> +INSERT INTO m1  VALUES (666);
>> +SELECT * FROM m1;
>> +--echo # insert the duplicate value into the merge table
>> +REPLACE INTO m1 VALUES (666);
>> +SELECT * FROM m1;
>> +DROP TABLE m1, t1;
>> +
>> +--echo # Insert... on duplicate key update (with duplicate values in the table)
>> +--echo # Create child table
>> +CREATE TABLE t1 (c1 INT PRIMARY KEY) ENGINE=MyISAM;
>> +--echo # Create Merge table
>> +CREATE TABLE m1 (c1 INT NOT NULL) ENGINE=MRG_MyISAM INSERT_METHOD=LAST
> UNION=(t1);
>> +INSERT INTO m1  VALUES (666);
>> +SELECT * FROM m1;
>> +--echo # insert the duplicate value into the merge table
>> +INSERT INTO m1 VALUES (666) ON DUPLICATE KEY UPDATE c1=c1+1;
>> +SELECT * FROM m1;
>> +DROP TABLE m1, t1;
>> +
>>     
>
>
> These tests are good. However, I'd like to see these additional tests:
>
> - Do an INSERT (not REPLACE) one these tables so that a duplicate key
> error is reported. I want to see the error message in the result file.
> The sense is to verify that the key contents is correctly reported. This
> would prove that the new way to get at the duplicate key does indeed
> work. The tests above prove that the duplicate key is noticed as such,
> but not that its value is correctly retrieved. (Or tell me that we have
> that already in the test suite.)
>   
This exists in the form of the test for Bug#41305 just above these set 
of tests.
> - Repeat the tests on tables, where MERGE has a key, but MyISAM has more
> keys:
> CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE c1, UNIQUE c2)
> CREATE TABLE m1 (c1 INT, c2 INT, UNIQUE c1)
> Provoke the duplicate key error on c2.
>
> - If it is possible to define MERGE and MyISAM with keys on different
> columns, repeat the tests on such tables too:
> CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE c1)
> CREATE TABLE m1 (c1 INT, c2 INT, UNIQUE c2)
> Provoke the duplicate key error on the column that has no key in MERGE.
> If it is not possible to use such differently defined tables, have a
> test that shows, that it is not possible. (Or tell me that we have that
> already in the test suite.)
>
> ...
>   

Added these tests!

>> === modified file 'storage/myisammrg/ha_myisammrg.cc'
>>     
> ...
>   
>> +  if (flag & HA_STATUS_ERRKEY)
>> +  {
>> +    /* 
>> +      Set the index of the key and the offset of the key that caused
>> +      the duplicate error. Here the mrg_info.dupp_key_pos will be the
>> +      sum of the offset of the myisam file and the offset into the
>> +      myisam file where the duplicate key is located.
>> +    */
>> +    errkey= mrg_info.errkey;
>>     
>
>
> I suggest to extend the comment so that it explicitly says that "errkey"
> is set to the index number of the MyISAM tables (which must all have the
> same indexes), not of the MERGE table.
>   
 Since errkey is now being set to a sentinel value, I removed the 
comments above
errkey.
> ...
>
> Regards
> Ingo
>   

Thanks again for the detailed review Ingo!

Narayanan
Thread
bzr commit into mysql-5.1-bugteam branch (v.narayanan:3039) Bug#45800V Narayanan24 Jul
  • Re: bzr commit into mysql-5.1-bugteam branch (v.narayanan:3039)Bug#45800Ingo Strüwing24 Jul
    • Re: bzr commit into mysql-5.1-bugteam branch (v.narayanan:3039)Bug#45800V Narayanan27 Jul