Below is the list of changes that have just been committed into a local
5.1 repository of istruewing. When istruewing does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2006-10-18 17:08:31+02:00, istruewing@stripped +3 -0
Bug#22119 - Changing MI_KEY_BLOCK_LENGTH makes a wrong myisamchk
When compiling with a default key block size greater than the
smallest key block size used in a table, checking that table
failed with bogus errors. The table was marked corrupt. This
affected myisamchk and the server.
The problem was that the default key block size was used at
some places where sizes less or equal to the block size of the
index in check was required.
We do now use the key block size of the particular index
when checking.
mysql-test/r/myisam.result@stripped, 2006-10-18 17:08:28+02:00, istruewing@stripped +45
-0
Bug#22119 - Changing MI_KEY_BLOCK_LENGTH makes a wrong myisamchk
Added test result.
mysql-test/t/myisam.test@stripped, 2006-10-18 17:08:28+02:00, istruewing@stripped +43 -0
Bug#22119 - Changing MI_KEY_BLOCK_LENGTH makes a wrong myisamchk
Added test case.
storage/myisam/mi_check.c@stripped, 2006-10-18 17:08:28+02:00, istruewing@stripped +64
-20
Bug#22119 - Changing MI_KEY_BLOCK_LENGTH makes a wrong myisamchk
Changed check_k_link() and chk_index_down() to use the block
size of the index in check or MI_MIN_KEY_BLOCK_LENGTH where
required. Formerly myisam_block_size or MYISAM_SHARE::blocksize
was used wrongly.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: istruewing
# Host: chilla.local
# Root: /home/mydev/mysql-5.1-bug22119
--- 1.153/storage/myisam/mi_check.c 2006-10-18 17:08:38 +02:00
+++ 1.154/storage/myisam/mi_check.c 2006-10-18 17:08:38 +02:00
@@ -251,11 +251,12 @@ static int check_k_link(MI_CHECK *param,
my_off_t next_link;
uint block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH;
ha_rows records;
- char llbuff[21],*buff;
+ char llbuff[21], llbuff2[21], *buff;
DBUG_ENTER("check_k_link");
+ DBUG_PRINT("enter", ("block_size: %u", block_size));
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];
records= (ha_rows) (info->state->key_file_length / block_size);
@@ -265,14 +266,38 @@ static int check_k_link(MI_CHECK *param,
DBUG_RETURN(1);
if (param->testflag & T_VERBOSE)
printf("%16s",llstr(next_link,llbuff));
- if (next_link > info->state->key_file_length ||
- next_link & (info->s->blocksize-1))
- DBUG_RETURN(1);
+
+ /* Key blocks must lay within the key file length entirely. */
+ if (next_link + block_size > info->state->key_file_length)
+ {
+ mi_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)); /* purecov: tested */
+ DBUG_RETURN(1); /* purecov: tested */
+ }
+
+ /* Key blocks must be aligned at MI_MIN_KEY_BLOCK_LENGTH. */
+ if (next_link & (MI_MIN_KEY_BLOCK_LENGTH - 1))
+ {
+ mi_check_print_error(param, "Mis-aligned key block: %s "
+ "minimum key block length: %u",
+ llstr(next_link, llbuff),
+ MI_MIN_KEY_BLOCK_LENGTH); /* purecov: tested */
+ DBUG_RETURN(1); /* purecov: tested */
+ }
+
+ /* Read the key block with MI_MIN_KEY_BLOCK_LENGTH to find next link. */
if (!(buff=key_cache_read(info->s->key_cache,
info->s->kfile, next_link, DFLT_INIT_HITS,
- (byte*) info->buff,
- myisam_block_size, block_size, 1)))
- DBUG_RETURN(1);
+ (byte*) info->buff, MI_MIN_KEY_BLOCK_LENGTH,
+ MI_MIN_KEY_BLOCK_LENGTH, 1)))
+ {
+ mi_check_print_error(param, "key cache read error for block: %s",
+ llstr(next_link,llbuff)); /* purecov: tested */
+ DBUG_RETURN(1); /* purecov: tested */
+ }
next_link=mi_sizekorr(buff);
records--;
param->key_file_blocks+=block_size;
@@ -556,17 +581,36 @@ static int chk_index_down(MI_CHECK *para
ha_checksum *key_checksum, uint level)
{
char llbuff[22],llbuff2[22];
- if (page > info->state->key_file_length || (page &
(info->s->blocksize -1)))
+ DBUG_ENTER("chk_index_down");
+
+ /* Key blocks must lay within the key file length entirely. */
+ if (page + keyinfo->block_length > info->state->key_file_length)
{
- my_off_t max_length=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0));
- mi_check_print_error(param,"Wrong pagepointer: %s at page: %s",
- llstr(page,llbuff),llstr(page,llbuff2));
-
- if (page+info->s->blocksize > max_length)
- goto err;
- info->state->key_file_length=(max_length &
- ~ (my_off_t) (info->s->blocksize-1));
+ /* 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)); /* purecov: tested */
+ mi_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)); /* purecov: tested */
+ if (page + keyinfo->block_length > max_length) /* purecov: tested */
+ goto err; /* purecov: tested */
+ /* Fix the remebered key file length. */
+ info->state->key_file_length= (max_length &
+ ~ (my_off_t) (keyinfo->block_length -
+ 1)); /* purecov: tested */
}
+
+ /* Key blocks must be aligned at MI_MIN_KEY_BLOCK_LENGTH. */
+ if (page & (MI_MIN_KEY_BLOCK_LENGTH - 1))
+ {
+ mi_check_print_error(param, "Mis-aligned key block: %s "
+ "minimum key block length: %u", llstr(page, llbuff),
+ MI_MIN_KEY_BLOCK_LENGTH); /* purecov: tested */
+ goto err; /* purecov: tested */
+ }
+
if (!_mi_fetch_keypage(info,keyinfo,page, DFLT_INIT_HITS,buff,0))
{
mi_check_print_error(param,"Can't read key from filepos: %s",
@@ -577,9 +621,9 @@ static int chk_index_down(MI_CHECK *para
if (chk_index(param,info,keyinfo,page,buff,keys,key_checksum,level))
goto err;
- return 0;
-err:
- return 1;
+ DBUG_RETURN(0);
+err: /* purecov: tested */
+ DBUG_RETURN(1); /* purecov: tested */
}
--- 1.96/mysql-test/r/myisam.result 2006-10-18 17:08:38 +02:00
+++ 1.97/mysql-test/r/myisam.result 2006-10-18 17:08:38 +02:00
@@ -1757,4 +1757,49 @@ create table t1 (a int not null, key key
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));
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
--- 1.71/mysql-test/t/myisam.test 2006-10-18 17:08:38 +02:00
+++ 1.72/mysql-test/t/myisam.test 2006-10-18 17:08:38 +02:00
@@ -1054,4 +1054,47 @@ create table t1 (a int not null, key key
--error 1064
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
| Thread |
|---|
| • bk commit into 5.1 tree (istruewing:1.2348) BUG#22119 | ingo | 18 Oct |