Commit 887383d4 authored by unknown's avatar unknown

Manually importing Ingo's fix for BUG#22119

"Changing MI_KEY_BLOCK_LENGTH makes a wrong myisamchk"
in the Maria tree as it is really needed to get "ma_test_all" to pass
(this bug showed up in Maria first, not in MyISAM).
Now ma_test_all does not have corruption messages about test2 anymore,
and shows the same output as mi_test_all except that
ma_test_all has this at the start:
lt-maria_chk: MARIA file test1
lt-maria_chk: warning: Size of indexfile is: 8192          Should be: 16384
MARIA-table 'test1' is usable but should be fixed
This was already true before importing the bugfix.
Wonder if normal.
NOTE: this bugfix is currently in 5.1-engines, in a few days
will be in the main 5.1, then we'll merge 5.1
into Maria: this will merge the bugfix into storage/myisam, but there
will be no need to apply it to storage/maria again. I just couldn't
wait a few days for the 5.1-engines->5.1 merge to be allowed.


mysql-test/r/maria.result:
  result update
mysql-test/t/maria.test:
  test for BUG#22119
storage/maria/ma_check.c:
  fix for BUG#22119
parent 8e971a05
...@@ -1613,5 +1613,50 @@ create table t1 (a int not null, key key_block_size=1024 (a)); ...@@ -1613,5 +1613,50 @@ create table t1 (a int not null, key key_block_size=1024 (a));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '=1024 (a))' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '=1024 (a))' at line 1
create table t1 (a int not null, key `a` key_block_size=1024 (a)); create table t1 (a int not null, key `a` key_block_size=1024 (a));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key_block_size=1024 (a))' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key_block_size=1024 (a))' at line 1
CREATE TABLE t1 (
c1 INT,
c2 VARCHAR(300),
KEY (c1) KEY_BLOCK_SIZE 1024,
KEY (c2) KEY_BLOCK_SIZE 8192
);
INSERT INTO t1 VALUES (10, REPEAT('a', CEIL(RAND(10) * 300))),
(11, REPEAT('b', CEIL(RAND() * 300))),
(12, REPEAT('c', CEIL(RAND() * 300))),
(13, REPEAT('d', CEIL(RAND() * 300))),
(14, REPEAT('e', CEIL(RAND() * 300))),
(15, REPEAT('f', CEIL(RAND() * 300))),
(16, REPEAT('g', CEIL(RAND() * 300))),
(17, REPEAT('h', CEIL(RAND() * 300))),
(18, REPEAT('i', CEIL(RAND() * 300))),
(19, REPEAT('j', CEIL(RAND() * 300))),
(20, REPEAT('k', CEIL(RAND() * 300))),
(21, REPEAT('l', CEIL(RAND() * 300))),
(22, REPEAT('m', CEIL(RAND() * 300))),
(23, REPEAT('n', CEIL(RAND() * 300))),
(24, REPEAT('o', CEIL(RAND() * 300))),
(25, REPEAT('p', CEIL(RAND() * 300))),
(26, REPEAT('q', CEIL(RAND() * 300))),
(27, REPEAT('r', CEIL(RAND() * 300))),
(28, REPEAT('s', CEIL(RAND() * 300))),
(29, REPEAT('t', CEIL(RAND() * 300))),
(30, REPEAT('u', CEIL(RAND() * 300))),
(31, REPEAT('v', CEIL(RAND() * 300))),
(32, REPEAT('w', CEIL(RAND() * 300))),
(33, REPEAT('x', CEIL(RAND() * 300))),
(34, REPEAT('y', CEIL(RAND() * 300))),
(35, REPEAT('z', CEIL(RAND() * 300)));
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
DELETE FROM t1 WHERE c1 >= 10;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
End of 5.1 tests End of 5.1 tests
set global storage_engine=MyISAM; set global storage_engine=MyISAM;
...@@ -939,6 +939,50 @@ create table t1 (a int not null, key key_block_size=1024 (a)); ...@@ -939,6 +939,50 @@ create table t1 (a int not null, key key_block_size=1024 (a));
--error 1064 --error 1064
create table t1 (a int not null, key `a` key_block_size=1024 (a)); create table t1 (a int not null, key `a` key_block_size=1024 (a));
#
# Bug#22119 - Changing MI_KEY_BLOCK_LENGTH makes a wrong myisamchk
#
CREATE TABLE t1 (
c1 INT,
c2 VARCHAR(300),
KEY (c1) KEY_BLOCK_SIZE 1024,
KEY (c2) KEY_BLOCK_SIZE 8192
);
INSERT INTO t1 VALUES (10, REPEAT('a', CEIL(RAND(10) * 300))),
(11, REPEAT('b', CEIL(RAND() * 300))),
(12, REPEAT('c', CEIL(RAND() * 300))),
(13, REPEAT('d', CEIL(RAND() * 300))),
(14, REPEAT('e', CEIL(RAND() * 300))),
(15, REPEAT('f', CEIL(RAND() * 300))),
(16, REPEAT('g', CEIL(RAND() * 300))),
(17, REPEAT('h', CEIL(RAND() * 300))),
(18, REPEAT('i', CEIL(RAND() * 300))),
(19, REPEAT('j', CEIL(RAND() * 300))),
(20, REPEAT('k', CEIL(RAND() * 300))),
(21, REPEAT('l', CEIL(RAND() * 300))),
(22, REPEAT('m', CEIL(RAND() * 300))),
(23, REPEAT('n', CEIL(RAND() * 300))),
(24, REPEAT('o', CEIL(RAND() * 300))),
(25, REPEAT('p', CEIL(RAND() * 300))),
(26, REPEAT('q', CEIL(RAND() * 300))),
(27, REPEAT('r', CEIL(RAND() * 300))),
(28, REPEAT('s', CEIL(RAND() * 300))),
(29, REPEAT('t', CEIL(RAND() * 300))),
(30, REPEAT('u', CEIL(RAND() * 300))),
(31, REPEAT('v', CEIL(RAND() * 300))),
(32, REPEAT('w', CEIL(RAND() * 300))),
(33, REPEAT('x', CEIL(RAND() * 300))),
(34, REPEAT('y', CEIL(RAND() * 300))),
(35, REPEAT('z', CEIL(RAND() * 300)));
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
CHECK TABLE t1;
REPAIR TABLE t1;
DELETE FROM t1 WHERE c1 >= 10;
CHECK TABLE t1;
DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests
eval set global storage_engine=$default; eval set global storage_engine=$default;
......
...@@ -228,11 +228,12 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info, uint nr) ...@@ -228,11 +228,12 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info, uint nr)
my_off_t next_link; my_off_t next_link;
uint block_size=(nr+1)*MARIA_MIN_KEY_BLOCK_LENGTH; uint block_size=(nr+1)*MARIA_MIN_KEY_BLOCK_LENGTH;
ha_rows records; ha_rows records;
char llbuff[21],*buff; char llbuff[21], llbuff2[21], *buff;
DBUG_ENTER("check_k_link"); DBUG_ENTER("check_k_link");
DBUG_PRINT("enter", ("block_size: %u", block_size));
if (param->testflag & T_VERBOSE) if (param->testflag & T_VERBOSE)
printf("block_size %4d:",block_size); printf("block_size %4u:", block_size); /* purecov: tested */
next_link=info->s->state.key_del[nr]; next_link=info->s->state.key_del[nr];
records= (ha_rows) (info->state->key_file_length / block_size); records= (ha_rows) (info->state->key_file_length / block_size);
...@@ -242,14 +243,46 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info, uint nr) ...@@ -242,14 +243,46 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info, uint nr)
DBUG_RETURN(1); DBUG_RETURN(1);
if (param->testflag & T_VERBOSE) if (param->testflag & T_VERBOSE)
printf("%16s",llstr(next_link,llbuff)); printf("%16s",llstr(next_link,llbuff));
if (next_link > info->state->key_file_length ||
next_link & (info->s->blocksize-1)) /* Key blocks must lay within the key file length entirely. */
if (next_link + block_size > info->state->key_file_length)
{
/* purecov: begin tested */
_ma_check_print_error(param, "Invalid key block position: %s "
"key block size: %u file_length: %s",
llstr(next_link, llbuff), block_size,
llstr(info->state->key_file_length, llbuff2));
DBUG_RETURN(1);
/* purecov: end */
}
/* Key blocks must be aligned at MARIA_MIN_KEY_BLOCK_LENGTH. */
if (next_link & (MARIA_MIN_KEY_BLOCK_LENGTH - 1))
{
/* purecov: begin tested */
_ma_check_print_error(param, "Mis-aligned key block: %s "
"minimum key block length: %u",
llstr(next_link, llbuff), MARIA_MIN_KEY_BLOCK_LENGTH);
DBUG_RETURN(1); DBUG_RETURN(1);
/* purecov: end */
}
/*
Read the key block with MARIA_MIN_KEY_BLOCK_LENGTH to find next link.
If the key cache block size is smaller than block_size, we can so
avoid unecessary eviction of cache block.
*/
if (!(buff=key_cache_read(info->s->key_cache, if (!(buff=key_cache_read(info->s->key_cache,
info->s->kfile, next_link, DFLT_INIT_HITS, info->s->kfile, next_link, DFLT_INIT_HITS,
(byte*) info->buff, (byte*) info->buff, MARIA_MIN_KEY_BLOCK_LENGTH,
maria_block_size, block_size, 1))) MARIA_MIN_KEY_BLOCK_LENGTH, 1)))
{
/* purecov: begin tested */
_ma_check_print_error(param, "key cache read error for block: %s",
llstr(next_link,llbuff));
DBUG_RETURN(1); DBUG_RETURN(1);
/* purecov: end */
}
next_link=mi_sizekorr(buff); next_link=mi_sizekorr(buff);
records--; records--;
param->key_file_blocks+=block_size; param->key_file_blocks+=block_size;
...@@ -533,17 +566,37 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo ...@@ -533,17 +566,37 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo
ha_checksum *key_checksum, uint level) ha_checksum *key_checksum, uint level)
{ {
char llbuff[22],llbuff2[22]; char llbuff[22],llbuff2[22];
if (page > info->state->key_file_length || (page & (info->s->blocksize -1))) DBUG_ENTER("chk_index_down");
{
my_off_t max_length=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0)); /* Key blocks must lay within the key file length entirely. */
_ma_check_print_error(param,"Wrong pagepointer: %s at page: %s", if (page + keyinfo->block_length > info->state->key_file_length)
llstr(page,llbuff),llstr(page,llbuff2)); {
/* purecov: begin tested */
if (page+info->s->blocksize > max_length) /* Give it a chance to fit in the real file size. */
my_off_t max_length= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(0));
_ma_check_print_error(param, "Invalid key block position: %s "
"key block size: %u file_length: %s",
llstr(page, llbuff), keyinfo->block_length,
llstr(info->state->key_file_length, llbuff2));
if (page + keyinfo->block_length > max_length)
goto err; goto err;
info->state->key_file_length=(max_length & /* Fix the remebered key file length. */
~ (my_off_t) (info->s->blocksize-1)); info->state->key_file_length= (max_length &
~ (my_off_t) (keyinfo->block_length - 1));
/* purecov: end */
}
/* Key blocks must be aligned at MARIA_MIN_KEY_BLOCK_LENGTH. */
if (page & (MARIA_MIN_KEY_BLOCK_LENGTH - 1))
{
/* purecov: begin tested */
_ma_check_print_error(param, "Mis-aligned key block: %s "
"minimum key block length: %u",
llstr(page, llbuff), MARIA_MIN_KEY_BLOCK_LENGTH);
goto err;
/* purecov: end */
} }
if (!_ma_fetch_keypage(info,keyinfo,page, DFLT_INIT_HITS,buff,0)) if (!_ma_fetch_keypage(info,keyinfo,page, DFLT_INIT_HITS,buff,0))
{ {
_ma_check_print_error(param,"Can't read key from filepos: %s", _ma_check_print_error(param,"Can't read key from filepos: %s",
...@@ -554,9 +607,12 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo ...@@ -554,9 +607,12 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo
if (chk_index(param,info,keyinfo,page,buff,keys,key_checksum,level)) if (chk_index(param,info,keyinfo,page,buff,keys,key_checksum,level))
goto err; goto err;
return 0; DBUG_RETURN(0);
/* purecov: begin tested */
err: err:
return 1; DBUG_RETURN(1);
/* purecov: end */
} }
......
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