diff options
author | unknown <istruewing@stella.local> | 2008-03-14 14:15:36 +0100 |
---|---|---|
committer | unknown <istruewing@stella.local> | 2008-03-14 14:15:36 +0100 |
commit | 8001dd1b86f89080ebb79f174e871a8320086d8a (patch) | |
tree | 7a02fe42bda740b80be77fc37737660eb5413cce | |
parent | 9fa2d50559383785c72656dcdffa878cc3563da9 (diff) | |
parent | ce86b14625d2beb4bc57da04da7359b9a85f4868 (diff) | |
download | mariadb-git-8001dd1b86f89080ebb79f174e871a8320086d8a.tar.gz |
Merge stella.local:/home2/mydev/mysql-5.0-axmrg
into stella.local:/home2/mydev/mysql-5.1-axmrg
mysql-test/r/func_misc.result:
Auto merged
mysql-test/r/myisam.result:
Auto merged
mysql-test/t/func_misc.test:
Auto merged
sql/item.cc:
Auto merged
sql/item_func.cc:
Auto merged
BitKeeper/deleted/.del-rpl_transaction.test:
Auto merged
storage/myisam/ha_myisam.cc:
Auto merged
mysql-test/r/query_cache.result:
Manual merge
mysql-test/t/query_cache.test:
Manual merge
-rw-r--r-- | mysql-test/r/query_cache.result | 26 | ||||
-rw-r--r-- | mysql-test/t/query_cache.test | 19 | ||||
-rw-r--r-- | storage/myisam/ha_myisam.cc | 64 |
3 files changed, 82 insertions, 27 deletions
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 1a728354c7b..c516ad474ed 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -1654,6 +1654,32 @@ set GLOBAL query_cache_type=default; set GLOBAL query_cache_limit=default; set GLOBAL query_cache_min_res_unit=default; set GLOBAL query_cache_size=default; +FLUSH STATUS; +SET GLOBAL query_cache_size=10*1024*1024; +SET @save_concurrent_insert= @@concurrent_insert; +SET GLOBAL concurrent_insert= 0; +CREATE TABLE t1 (c1 INT NOT NULL) ENGINE=MyISAM; +INSERT INTO t1 (c1) VALUES (1), (2); +SHOW GLOBAL VARIABLES LIKE 'concurrent_insert'; +Variable_name Value +concurrent_insert 0 +SHOW STATUS LIKE 'Qcache_hits'; +Variable_name Value +Qcache_hits 0 +SELECT * FROM t1; +c1 +1 +2 +SELECT * FROM t1; +c1 +1 +2 +SHOW STATUS LIKE 'Qcache_hits'; +Variable_name Value +Qcache_hits 1 +DROP TABLE t1; +SET GLOBAL concurrent_insert= @save_concurrent_insert; +SET GLOBAL query_cache_size= default; End of 5.0 tests CREATE TABLE t1 (a ENUM('rainbow')); INSERT INTO t1 VALUES (),(),(),(),(); diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 771a32e8cd7..0e899da59da 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -1298,6 +1298,25 @@ set GLOBAL query_cache_limit=default; set GLOBAL query_cache_min_res_unit=default; set GLOBAL query_cache_size=default; +# +# Bug#33756 - query cache with concurrent_insert=0 appears broken +# +FLUSH STATUS; +SET GLOBAL query_cache_size=10*1024*1024; +SET @save_concurrent_insert= @@concurrent_insert; +SET GLOBAL concurrent_insert= 0; +CREATE TABLE t1 (c1 INT NOT NULL) ENGINE=MyISAM; +INSERT INTO t1 (c1) VALUES (1), (2); +# +SHOW GLOBAL VARIABLES LIKE 'concurrent_insert'; +SHOW STATUS LIKE 'Qcache_hits'; +SELECT * FROM t1; +SELECT * FROM t1; +SHOW STATUS LIKE 'Qcache_hits'; +DROP TABLE t1; +SET GLOBAL concurrent_insert= @save_concurrent_insert; +SET GLOBAL query_cache_size= default; + --echo End of 5.0 tests # diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 9c04a5a3523..c7584f801de 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -2098,6 +2098,7 @@ my_bool ha_myisam::register_query_cache_table(THD *thd, char *table_name, *engine_callback, ulonglong *engine_data) { + DBUG_ENTER("ha_myisam::register_query_cache_table"); /* No call back function is needed to determine if a cached statement is valid or not. @@ -2109,39 +2110,48 @@ my_bool ha_myisam::register_query_cache_table(THD *thd, char *table_name, */ *engine_data= 0; - /* - If a concurrent INSERT has happened just before the currently processed - SELECT statement, the total size of the table is unknown. + if (file->s->concurrent_insert) + { + /* + If a concurrent INSERT has happened just before the currently + processed SELECT statement, the total size of the table is + unknown. - To determine if the table size is known, the current thread's snap shot of - the table size with the actual table size are compared. + To determine if the table size is known, the current thread's snap + shot of the table size with the actual table size are compared. - If the table size is unknown the SELECT statement can't be cached. - */ - ulonglong actual_data_file_length; - ulonglong current_data_file_length; + If the table size is unknown the SELECT statement can't be cached. - /* - POSIX visibility rules specify that "2. Whatever memory values a - thread can see when it unlocks a mutex <...> can also be seen by any - thread that later locks the same mutex". In this particular case, - concurrent insert thread had modified the data_file_length in - MYISAM_SHARE before it has unlocked (or even locked) - structure_guard_mutex. So, here we're guaranteed to see at least that - value after we've locked the same mutex. We can see a later value - (modified by some other thread) though, but it's ok, as we only want - to know if the variable was changed, the actual new value doesn't matter - */ - actual_data_file_length= file->s->state.state.data_file_length; - current_data_file_length= file->save_state.data_file_length; + When concurrent inserts are disabled at table open, mi_open() + does not assign a get_status() function. In this case the local + ("current") status is never updated. We would wrongly think that + we cannot cache the statement. + */ + ulonglong actual_data_file_length; + ulonglong current_data_file_length; - if (current_data_file_length != actual_data_file_length) - { - /* Don't cache current statement. */ - return FALSE; + /* + POSIX visibility rules specify that "2. Whatever memory values a + thread can see when it unlocks a mutex <...> can also be seen by any + thread that later locks the same mutex". In this particular case, + concurrent insert thread had modified the data_file_length in + MYISAM_SHARE before it has unlocked (or even locked) + structure_guard_mutex. So, here we're guaranteed to see at least that + value after we've locked the same mutex. We can see a later value + (modified by some other thread) though, but it's ok, as we only want + to know if the variable was changed, the actual new value doesn't matter + */ + actual_data_file_length= file->s->state.state.data_file_length; + current_data_file_length= file->save_state.data_file_length; + + if (current_data_file_length != actual_data_file_length) + { + /* Don't cache current statement. */ + DBUG_RETURN(FALSE); + } } /* It is ok to try to cache current statement. */ - return TRUE; + DBUG_RETURN(TRUE); } #endif |