Commit d145362e authored by Michael Widenius's avatar Michael Widenius

Fix for bug#38484 DELETE causes crash or index corruption

There is no test cases as it's not trivial to do a test case for this.
The new code for Maria is however executed by the test case in the bug report.

mysql-test/mysql-test-run.pl:
  Avoid warnings when running with --extern
storage/maria/ha_maria.cc:
  Disable not complete assert until Sanja can push a proper fix
storage/maria/ma_delete.c:
  Fix that pageflag for page is calculated based on original values
storage/maria/ma_search.c:
  Ensure that prev_length structure variable is properly reset when not used
storage/myisam/mi_search.c:
  Ensure that prev_length structure variable is properly reset when not used
parent 57e0bdb3
...@@ -3889,15 +3889,17 @@ sub mysqld_arguments ($$$$) { ...@@ -3889,15 +3889,17 @@ sub mysqld_arguments ($$$$) {
mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir); mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir);
mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir); mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir);
if ( $mysql_version_id >= 50036) if (!$opt_extern)
{ {
# By default, prevent the started mysqld to access files outside of vardir if ( $mysql_version_id >= 50036)
mtr_add_arg($args, "%s--secure-file-priv=%s", $prefix, $opt_vardir); {
} # Prevent the started mysqld to access files outside of vardir
mtr_add_arg($args, "%s--secure-file-priv=%s", $prefix, $opt_vardir);
}
if ( $mysql_version_id >= 50000 ) if ( $mysql_version_id >= 50000 ) {
{ mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix); }
} }
mtr_add_arg($args, "%s--default-character-set=latin1", $prefix); mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
...@@ -3942,7 +3944,7 @@ sub mysqld_arguments ($$$$) { ...@@ -3942,7 +3944,7 @@ sub mysqld_arguments ($$$$) {
mtr_add_arg($args, "%s--disable-sync-frm", $prefix); # Faster test mtr_add_arg($args, "%s--disable-sync-frm", $prefix); # Faster test
if ( $mysql_version_id >= 50106 ) if (!$opt_extern and $mysql_version_id >= 50106 )
{ {
# Turn on logging to bothe tables and file # Turn on logging to bothe tables and file
mtr_add_arg($args, "%s--log-output=table,file", $prefix); mtr_add_arg($args, "%s--log-output=table,file", $prefix);
......
...@@ -2363,7 +2363,9 @@ int ha_maria::external_lock(THD *thd, int lock_type) ...@@ -2363,7 +2363,9 @@ int ha_maria::external_lock(THD *thd, int lock_type)
This is a bit excessive, ACID requires this only if there are some This is a bit excessive, ACID requires this only if there are some
changes to commit (rollback shouldn't be tested). changes to commit (rollback shouldn't be tested).
*/ */
#ifdef WAITING_FOR_PATCH_FROM_SANJA
DBUG_ASSERT(!thd->main_da.is_sent); DBUG_ASSERT(!thd->main_da.is_sent);
#endif
/* autocommit ? rollback a transaction */ /* autocommit ? rollback a transaction */
#ifdef MARIA_CANNOT_ROLLBACK #ifdef MARIA_CANNOT_ROLLBACK
if (ma_commit(trn)) if (ma_commit(trn))
......
...@@ -780,6 +780,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, ...@@ -780,6 +780,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
first_key) first_key)
{ {
size_t tmp_length; size_t tmp_length;
uint next_page_flag;
/* Use page right of anc-page */ /* Use page right of anc-page */
DBUG_PRINT("test",("use right page")); DBUG_PRINT("test",("use right page"));
...@@ -805,6 +806,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, ...@@ -805,6 +806,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
DFLT_INIT_HITS, buff, 0, &next_page_link)) DFLT_INIT_HITS, buff, 0, &next_page_link))
goto err; goto err;
next_buff_length= _ma_get_page_used(share, buff); next_buff_length= _ma_get_page_used(share, buff);
next_page_flag= _ma_get_keypage_flag(share,buff);
DBUG_DUMP("next", buff, next_buff_length); DBUG_DUMP("next", buff, next_buff_length);
/* find keys to make a big key-page */ /* find keys to make a big key-page */
...@@ -829,7 +831,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, ...@@ -829,7 +831,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
_ma_store_page_used(share, buff, buff_length); _ma_store_page_used(share, buff, buff_length);
/* Set page flag from combination of both key pages and parting key */ /* Set page flag from combination of both key pages and parting key */
page_flag= (_ma_get_keypage_flag(share, buff) | page_flag= (next_page_flag |
_ma_get_keypage_flag(share, leaf_buff)); _ma_get_keypage_flag(share, leaf_buff));
if (anc_key.flag & (SEARCH_USER_KEY_HAS_TRANSID | if (anc_key.flag & (SEARCH_USER_KEY_HAS_TRANSID |
SEARCH_PAGE_KEY_HAS_TRANSID)) SEARCH_PAGE_KEY_HAS_TRANSID))
......
...@@ -2194,9 +2194,10 @@ int _ma_calc_bin_pack_key_length(const MARIA_KEY *int_key, ...@@ -2194,9 +2194,10 @@ int _ma_calc_bin_pack_key_length(const MARIA_KEY *int_key,
if (next_length > ref_length) if (next_length > ref_length)
{ {
/* We put a key with different case between two keys with the same prefix /*
Extend next key to have same prefix as We put a key with different case between two keys with the same prefix
this key */ Extend next key to have same prefix as this key
*/
s_temp->n_ref_length= ref_length; s_temp->n_ref_length= ref_length;
s_temp->prev_length= next_length-ref_length; s_temp->prev_length= next_length-ref_length;
s_temp->prev_key+= ref_length; s_temp->prev_key+= ref_length;
...@@ -2206,13 +2207,13 @@ int _ma_calc_bin_pack_key_length(const MARIA_KEY *int_key, ...@@ -2206,13 +2207,13 @@ int _ma_calc_bin_pack_key_length(const MARIA_KEY *int_key,
} }
/* Check how many characters are identical to next key */ /* Check how many characters are identical to next key */
key= s_temp->key+next_length; key= s_temp->key+next_length;
s_temp->prev_length= 0;
while (*key++ == *next_key++) ; while (*key++ == *next_key++) ;
if ((ref_length= (uint) (key - s_temp->key)-1) == next_length) if ((ref_length= (uint) (key - s_temp->key)-1) == next_length)
{ {
s_temp->next_key_pos=0; s_temp->next_key_pos=0;
return (s_temp->move_length= length); /* Can't pack next key */ return (s_temp->move_length= length); /* Can't pack next key */
} }
s_temp->prev_length=0;
s_temp->n_ref_length=ref_length; s_temp->n_ref_length=ref_length;
return s_temp->move_length= (int) (length-(ref_length - next_length) - return s_temp->move_length= (int) (length-(ref_length - next_length) -
next_length_pack + next_length_pack +
......
...@@ -1802,13 +1802,13 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, ...@@ -1802,13 +1802,13 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
} }
/* Check how many characters are identical to next key */ /* Check how many characters are identical to next key */
key= s_temp->key+next_length; key= s_temp->key+next_length;
s_temp->prev_length= 0;
while (*key++ == *next_key++) ; while (*key++ == *next_key++) ;
if ((ref_length= (uint) (key - s_temp->key)-1) == next_length) if ((ref_length= (uint) (key - s_temp->key)-1) == next_length)
{ {
s_temp->next_key_pos=0; s_temp->next_key_pos=0;
return length; /* can't pack next key */ return length; /* can't pack next key */
} }
s_temp->prev_length=0;
s_temp->n_ref_length=ref_length; s_temp->n_ref_length=ref_length;
return (int) (length-(ref_length - next_length) - next_length_pack + return (int) (length-(ref_length - next_length) - next_length_pack +
get_pack_length(ref_length)); get_pack_length(ref_length));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment