Skip to content

Commit 8e11f17

Browse files
Merge chilla.local:/home/mydev/mysql-5.0-axmrg
into chilla.local:/home/mydev/mysql-5.1-axmrg
2 parents 4ba6a0f + 937e400 commit 8e11f17

5 files changed

Lines changed: 60 additions & 8 deletions

File tree

include/keycache.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ typedef struct st_key_cache
4747
my_bool in_resize; /* true during resize operation */
4848
my_bool resize_in_flush; /* true during flush of resize operation */
4949
my_bool can_be_used; /* usage of cache for read/write is allowed */
50-
uint key_cache_shift;
5150
ulong key_cache_mem_size; /* specified size of the cache memory */
5251
uint key_cache_block_size; /* size of the page buffer of a cache block */
5352
ulong min_warm_blocks; /* min number of warm blocks; */

mysql-test/r/key_cache.result

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,30 @@ Warning 1438 Cannot drop default keycache
341341
select @@global.key_buffer_size;
342342
@@global.key_buffer_size
343343
2097152
344+
SET @bug28478_key_cache_block_size= @@global.key_cache_block_size;
345+
SET GLOBAL key_cache_block_size= 1536;
346+
CREATE TABLE t1 (
347+
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
348+
c1 CHAR(150),
349+
c2 CHAR(150),
350+
c3 CHAR(150),
351+
KEY(c1, c2, c3)
352+
) ENGINE= MyISAM;
353+
INSERT INTO t1 (c1, c2, c3) VALUES
354+
('a', 'b', 'c'), ('b', 'c', 'd'), ('c', 'd', 'e'), ('d', 'e', 'f'),
355+
('e', 'f', 'g'), ('f', 'g', 'h'), ('g', 'h', 'i'), ('h', 'i', 'j'),
356+
('i', 'j', 'k'), ('j', 'k', 'l'), ('k', 'l', 'm'), ('l', 'm', 'n'),
357+
('m', 'n', 'o'), ('n', 'o', 'p'), ('o', 'p', 'q'), ('p', 'q', 'r'),
358+
('q', 'r', 's'), ('r', 's', 't'), ('s', 't', 'u'), ('t', 'u', 'v'),
359+
('u', 'v', 'w'), ('v', 'w', 'x'), ('w', 'x', 'y'), ('x', 'y', 'z');
360+
INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
361+
INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
362+
INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
363+
CHECK TABLE t1;
364+
Table Op Msg_type Msg_text
365+
test.t1 check status OK
366+
SHOW VARIABLES LIKE 'key_cache_block_size';
367+
Variable_name Value
368+
key_cache_block_size 1536
369+
SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size;
370+
DROP TABLE t1;

mysql-test/t/key_cache.test

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,31 @@ set global key_cache_block_size= @my_key_cache_block_size;
219219
set @@global.key_buffer_size=0;
220220
select @@global.key_buffer_size;
221221

222+
#
223+
# Bug#28478 - Improper key_cache_block_size corrupts MyISAM tables
224+
#
225+
SET @bug28478_key_cache_block_size= @@global.key_cache_block_size;
226+
SET GLOBAL key_cache_block_size= 1536;
227+
CREATE TABLE t1 (
228+
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
229+
c1 CHAR(150),
230+
c2 CHAR(150),
231+
c3 CHAR(150),
232+
KEY(c1, c2, c3)
233+
) ENGINE= MyISAM;
234+
INSERT INTO t1 (c1, c2, c3) VALUES
235+
('a', 'b', 'c'), ('b', 'c', 'd'), ('c', 'd', 'e'), ('d', 'e', 'f'),
236+
('e', 'f', 'g'), ('f', 'g', 'h'), ('g', 'h', 'i'), ('h', 'i', 'j'),
237+
('i', 'j', 'k'), ('j', 'k', 'l'), ('k', 'l', 'm'), ('l', 'm', 'n'),
238+
('m', 'n', 'o'), ('n', 'o', 'p'), ('o', 'p', 'q'), ('p', 'q', 'r'),
239+
('q', 'r', 's'), ('r', 's', 't'), ('s', 't', 'u'), ('t', 'u', 'v'),
240+
('u', 'v', 'w'), ('v', 'w', 'x'), ('w', 'x', 'y'), ('x', 'y', 'z');
241+
INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
242+
INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
243+
INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
244+
CHECK TABLE t1;
245+
SHOW VARIABLES LIKE 'key_cache_block_size';
246+
SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size;
247+
DROP TABLE t1;
248+
222249
# End of 4.1 tests

mysys/mf_keycache.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ static void test_key_cache(KEY_CACHE *keycache,
234234
#endif
235235

236236
#define KEYCACHE_HASH(f, pos) \
237-
(((ulong) ((pos) >> keycache->key_cache_shift)+ \
237+
(((ulong) ((pos) / keycache->key_cache_block_size) + \
238238
(ulong) (f)) & (keycache->hash_entries-1))
239239
#define FILE_HASH(f) ((uint) (f) & (CHANGED_BLOCKS_HASH-1))
240240

@@ -399,7 +399,6 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
399399

400400
keycache->key_cache_mem_size= use_mem;
401401
keycache->key_cache_block_size= key_cache_block_size;
402-
keycache->key_cache_shift= my_bit_log2(key_cache_block_size);
403402
DBUG_PRINT("info", ("key_cache_block_size: %u",
404403
key_cache_block_size));
405404

@@ -422,7 +421,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
422421
ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) +
423422
ALIGN_SIZE(sizeof(HASH_LINK*) *
424423
keycache->hash_entries))) +
425-
((ulong) blocks << keycache->key_cache_shift) > use_mem)
424+
((ulong) blocks * keycache->key_cache_block_size) > use_mem)
426425
blocks--;
427426
/* Allocate memory for cache page buffers */
428427
if ((keycache->block_mem=
@@ -2558,7 +2557,7 @@ uchar *key_cache_read(KEY_CACHE *keycache,
25582557
inc_counter_for_resize_op(keycache);
25592558
locked_and_incremented= TRUE;
25602559
/* Requested data may not always be aligned to cache blocks. */
2561-
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
2560+
offset= (uint) (filepos % keycache->key_cache_block_size);
25622561
/* Read data in key_cache_block_size increments */
25632562
do
25642563
{
@@ -2756,7 +2755,7 @@ int key_cache_insert(KEY_CACHE *keycache,
27562755
inc_counter_for_resize_op(keycache);
27572756
locked_and_incremented= TRUE;
27582757
/* Loaded data may not always be aligned to cache blocks. */
2759-
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
2758+
offset= (uint) (filepos % keycache->key_cache_block_size);
27602759
/* Load data in key_cache_block_size increments. */
27612760
do
27622761
{
@@ -3030,7 +3029,7 @@ int key_cache_write(KEY_CACHE *keycache,
30303029
inc_counter_for_resize_op(keycache);
30313030
locked_and_incremented= TRUE;
30323031
/* Requested data may not always be aligned to cache blocks. */
3033-
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
3032+
offset= (uint) (filepos % keycache->key_cache_block_size);
30343033
/* Write data in key_cache_block_size increments. */
30353034
do
30363035
{

sql/mysqld.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5910,7 +5910,7 @@ log and this option does nothing anymore.",
59105910
(uchar**) &dflt_key_cache_var.param_block_size,
59115911
(uchar**) 0,
59125912
0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
5913-
KEY_CACHE_BLOCK_SIZE , 512, 1024*16, MALLOC_OVERHEAD, 512, 0},
5913+
KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
59145914
{"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
59155915
"The minimum percentage of warm blocks in key cache",
59165916
(uchar**) &dflt_key_cache_var.param_division_limit,

0 commit comments

Comments
 (0)