diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index 844109dba1f310d4efbdcd29a6e8ca23da6d1ec9..d63698710bf06a50fb4e8aea7ca4b595aa7e14f8 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -383,3 +383,19 @@ Variable_name Value key_cache_block_size 1536 SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size; DROP TABLE t1; +# +# Bug#12361113: crash when load index into cache +# +# Note that this creates an empty disabled key cache! +SET GLOBAL key_cache_none.key_cache_block_size = 1024; +CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) ENGINE = MYISAM; +INSERT INTO t1 VALUES (1, 1); +CACHE INDEX t1 in key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +# The bug crashed the server at LOAD INDEX below. Now it will succeed +# since the default cache is used due to CACHE INDEX failed for +# key_cache_none. +LOAD INDEX INTO CACHE t1; +Table Op Msg_type Msg_text +test.t1 preload_keys status OK +DROP TABLE t1; diff --git a/mysql-test/r/partition_key_cache.result b/mysql-test/r/partition_key_cache.result index c5241c6ea90d48df9718ef38ab36979f7e410f41..154f2008a96c1c45f63f63471689d6a9bef21947 100644 --- a/mysql-test/r/partition_key_cache.result +++ b/mysql-test/r/partition_key_cache.result @@ -397,6 +397,33 @@ test.t1 assign_to_keycache error Subpartition sp0 returned error test.t1 assign_to_keycache Error Key 'inx_b' doesn't exist in table 't1' test.t1 assign_to_keycache status Operation failed DROP TABLE t1,t2; +# +# Bug#12361113: crash when load index into cache +# +# Note that this creates an empty disabled key cache! +SET GLOBAL key_cache_none.key_cache_block_size = 1024; +CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) +ENGINE = MYISAM +PARTITION BY HASH(a) PARTITIONS 2; +INSERT INTO t1 VALUES (1, 1); +CACHE INDEX t1 IN key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +CACHE INDEX t1 PARTITION (p0) IN key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +CACHE INDEX t1 PARTITION (p1) IN key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +CACHE INDEX t1 PARTITION (p0) KEY (`b`) IN key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +CACHE INDEX t1 PARTITION (p1) KEY (`b`) IN key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +# The bug crashed the server at LOAD INDEX below. Now it will succeed +# since the default cache is used due to CACHE INDEX failed for +# key_cache_none. +LOAD INDEX INTO CACHE t1; +Table Op Msg_type Msg_text +test.t1 preload_keys status OK +DROP TABLE t1; +# Clean up SET GLOBAL hot_cache.key_buffer_size = 0; SET GLOBAL warm_cache.key_buffer_size = 0; SET @@global.cold_cache.key_buffer_size = 0; diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index a404e9bf15a9dbc19e8b8bc97e4cb1dd9e647cdf..76b538c301d4f9f2d1c11f170ff4b4cb48fa18d1 100644 --- a/mysql-test/t/key_cache.test +++ b/mysql-test/t/key_cache.test @@ -251,3 +251,19 @@ SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size; DROP TABLE t1; # End of 4.1 tests + +--echo # +--echo # Bug#12361113: crash when load index into cache +--echo # + +--echo # Note that this creates an empty disabled key cache! +SET GLOBAL key_cache_none.key_cache_block_size = 1024; +CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) ENGINE = MYISAM; +INSERT INTO t1 VALUES (1, 1); +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 in key_cache_none; +--echo # The bug crashed the server at LOAD INDEX below. Now it will succeed +--echo # since the default cache is used due to CACHE INDEX failed for +--echo # key_cache_none. +LOAD INDEX INTO CACHE t1; +DROP TABLE t1; diff --git a/mysql-test/t/partition_key_cache.test b/mysql-test/t/partition_key_cache.test index 4beb9506b053aac1281e6b0bc58e02a7473ce179..067eb7fae596ec5b9e70b5557700a765c50183e5 100644 --- a/mysql-test/t/partition_key_cache.test +++ b/mysql-test/t/partition_key_cache.test @@ -239,6 +239,34 @@ CACHE INDEX t2 INDEX (`inx_b`) IN hot_cache; CACHE INDEX t1 PARTITION (p0) KEY (`inx_b`) IN hot_cache; CACHE INDEX t1 INDEX (`inx_b`) IN hot_cache; DROP TABLE t1,t2; + +--echo # +--echo # Bug#12361113: crash when load index into cache +--echo # +--echo # Note that this creates an empty disabled key cache! +SET GLOBAL key_cache_none.key_cache_block_size = 1024; +CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) +ENGINE = MYISAM +PARTITION BY HASH(a) PARTITIONS 2; +INSERT INTO t1 VALUES (1, 1); +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 IN key_cache_none; +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 PARTITION (p0) IN key_cache_none; +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 PARTITION (p1) IN key_cache_none; +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 PARTITION (p0) KEY (`b`) IN key_cache_none; +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 PARTITION (p1) KEY (`b`) IN key_cache_none; +--echo # The bug crashed the server at LOAD INDEX below. Now it will succeed +--echo # since the default cache is used due to CACHE INDEX failed for +--echo # key_cache_none. +LOAD INDEX INTO CACHE t1; +DROP TABLE t1; + + +--echo # Clean up SET GLOBAL hot_cache.key_buffer_size = 0; SET GLOBAL warm_cache.key_buffer_size = 0; SET @@global.cold_cache.key_buffer_size = 0; diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index ab59ff501aa62556ccc3c605a43590d77e9d3899..5bb777437b0fa287cd86b121a74587448ce9f37e 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -911,6 +911,11 @@ bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, DBUG_RETURN(TRUE); } mysql_mutex_unlock(&LOCK_global_system_variables); + if (!key_cache->key_cache_inited) + { + my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str); + DBUG_RETURN(true); + } check_opt.key_cache= key_cache; DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt, "assign_to_keycache", TL_READ_NO_INSERT, 0, 0, diff --git a/storage/myisam/mi_preload.c b/storage/myisam/mi_preload.c index 01b740cc56415ca0d1bead95fe86bf0dffb3fab2..a0187ec7f994564e2bcdd9194ad05b6359223955 100644 --- a/storage/myisam/mi_preload.c +++ b/storage/myisam/mi_preload.c @@ -53,6 +53,9 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) if (!keys || !mi_is_any_key_active(key_map) || key_file_length == pos) DBUG_RETURN(0); + /* Preload into a non initialized key cache should never happen. */ + DBUG_ASSERT(share->key_cache->key_cache_inited); + block_length= keyinfo[0].block_length; if (ignore_leaves)