diff options
-rw-r--r-- | include/keycache.h | 1 | ||||
-rw-r--r-- | mysql-test/r/key_cache.result | 27 | ||||
-rw-r--r-- | mysql-test/t/key_cache.test | 27 | ||||
-rw-r--r-- | mysys/mf_keycache.c | 11 |
4 files changed, 59 insertions, 7 deletions
diff --git a/include/keycache.h b/include/keycache.h index dc763b8cc08..54c099fc474 100644 --- a/include/keycache.h +++ b/include/keycache.h @@ -46,7 +46,6 @@ typedef struct st_key_cache my_bool key_cache_inited; my_bool resize_in_flush; /* true during flush of resize operation */ my_bool can_be_used; /* usage of cache for read/write is allowed */ - uint key_cache_shift; ulong key_cache_mem_size; /* specified size of the cache memory */ uint key_cache_block_size; /* size of the page buffer of a cache block */ ulong min_warm_blocks; /* min number of warm blocks; */ diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index a1bf3d0e128..1ab58c1ad6c 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -341,3 +341,30 @@ Warning 1438 Cannot drop default keycache select @@global.key_buffer_size; @@global.key_buffer_size 2097152 +SET @bug28478_key_cache_block_size= @@global.key_cache_block_size; +SET GLOBAL key_cache_block_size= 1536; +CREATE TABLE t1 ( +id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c1 CHAR(150), +c2 CHAR(150), +c3 CHAR(150), +KEY(c1, c2, c3) +) ENGINE= MyISAM; +INSERT INTO t1 (c1, c2, c3) VALUES +('a', 'b', 'c'), ('b', 'c', 'd'), ('c', 'd', 'e'), ('d', 'e', 'f'), +('e', 'f', 'g'), ('f', 'g', 'h'), ('g', 'h', 'i'), ('h', 'i', 'j'), +('i', 'j', 'k'), ('j', 'k', 'l'), ('k', 'l', 'm'), ('l', 'm', 'n'), +('m', 'n', 'o'), ('n', 'o', 'p'), ('o', 'p', 'q'), ('p', 'q', 'r'), +('q', 'r', 's'), ('r', 's', 't'), ('s', 't', 'u'), ('t', 'u', 'v'), +('u', 'v', 'w'), ('v', 'w', 'x'), ('w', 'x', 'y'), ('x', 'y', 'z'); +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SHOW VARIABLES LIKE 'key_cache_block_size'; +Variable_name Value +key_cache_block_size 1536 +SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size; +DROP TABLE t1; diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index 3044964ebc3..4c14dc96aaa 100644 --- a/mysql-test/t/key_cache.test +++ b/mysql-test/t/key_cache.test @@ -219,4 +219,31 @@ set global key_cache_block_size= @my_key_cache_block_size; set @@global.key_buffer_size=0; select @@global.key_buffer_size; +# +# Bug#28478 - Improper key_cache_block_size corrupts MyISAM tables +# +SET @bug28478_key_cache_block_size= @@global.key_cache_block_size; +SET GLOBAL key_cache_block_size= 1536; +CREATE TABLE t1 ( + id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c1 CHAR(150), + c2 CHAR(150), + c3 CHAR(150), + KEY(c1, c2, c3) + ) ENGINE= MyISAM; +INSERT INTO t1 (c1, c2, c3) VALUES + ('a', 'b', 'c'), ('b', 'c', 'd'), ('c', 'd', 'e'), ('d', 'e', 'f'), + ('e', 'f', 'g'), ('f', 'g', 'h'), ('g', 'h', 'i'), ('h', 'i', 'j'), + ('i', 'j', 'k'), ('j', 'k', 'l'), ('k', 'l', 'm'), ('l', 'm', 'n'), + ('m', 'n', 'o'), ('n', 'o', 'p'), ('o', 'p', 'q'), ('p', 'q', 'r'), + ('q', 'r', 's'), ('r', 's', 't'), ('s', 't', 'u'), ('t', 'u', 'v'), + ('u', 'v', 'w'), ('v', 'w', 'x'), ('w', 'x', 'y'), ('x', 'y', 'z'); +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1; +CHECK TABLE t1; +SHOW VARIABLES LIKE 'key_cache_block_size'; +SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size; +DROP TABLE t1; + # End of 4.1 tests diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 87f136dbf81..af910678a1f 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -173,7 +173,7 @@ static void test_key_cache(KEY_CACHE *keycache, #endif #define KEYCACHE_HASH(f, pos) \ -(((ulong) ((pos) >> keycache->key_cache_shift)+ \ +(((ulong) ((pos) / keycache->key_cache_block_size) + \ (ulong) (f)) & (keycache->hash_entries-1)) #define FILE_HASH(f) ((uint) (f) & (CHANGED_BLOCKS_HASH-1)) @@ -329,7 +329,6 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, keycache->key_cache_mem_size= use_mem; keycache->key_cache_block_size= key_cache_block_size; - keycache->key_cache_shift= my_bit_log2(key_cache_block_size); DBUG_PRINT("info", ("key_cache_block_size: %u", key_cache_block_size)); @@ -352,7 +351,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) + ALIGN_SIZE(sizeof(HASH_LINK*) * keycache->hash_entries))) + - ((ulong) blocks << keycache->key_cache_shift) > use_mem) + ((ulong) blocks * keycache->key_cache_block_size) > use_mem) blocks--; /* Allocate memory for cache page buffers */ if ((keycache->block_mem= @@ -1807,7 +1806,7 @@ byte *key_cache_read(KEY_CACHE *keycache, uint status; int page_st; - offset= (uint) (filepos & (keycache->key_cache_block_size-1)); + offset= (uint) (filepos % keycache->key_cache_block_size); /* Read data in key_cache_block_size increments */ do { @@ -1946,7 +1945,7 @@ int key_cache_insert(KEY_CACHE *keycache, int error; uint offset; - offset= (uint) (filepos & (keycache->key_cache_block_size-1)); + offset= (uint) (filepos % keycache->key_cache_block_size); do { keycache_pthread_mutex_lock(&keycache->cache_lock); @@ -2081,7 +2080,7 @@ int key_cache_write(KEY_CACHE *keycache, int page_st; uint offset; - offset= (uint) (filepos & (keycache->key_cache_block_size-1)); + offset= (uint) (filepos % keycache->key_cache_block_size); do { keycache_pthread_mutex_lock(&keycache->cache_lock); |