diff options
-rw-r--r-- | mysql-test/r/ndb_cache.result | 26 | ||||
-rw-r--r-- | mysql-test/r/ndb_cache2.result | 24 | ||||
-rw-r--r-- | mysql-test/t/ndb_cache.test | 20 | ||||
-rw-r--r-- | mysql-test/t/ndb_cache2.test | 20 | ||||
-rw-r--r-- | sql/ha_innodb.h | 8 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 122 | ||||
-rw-r--r-- | sql/ha_ndbcluster.h | 10 | ||||
-rw-r--r-- | sql/handler.h | 11 | ||||
-rw-r--r-- | sql/sql_cache.cc | 9 |
9 files changed, 136 insertions, 114 deletions
diff --git a/mysql-test/r/ndb_cache.result b/mysql-test/r/ndb_cache.result index 7423771e026..478663b1aa1 100644 --- a/mysql-test/r/ndb_cache.result +++ b/mysql-test/r/ndb_cache.result @@ -36,22 +36,22 @@ Variable_name Value Qcache_hits 1 insert into t1 value (2, 7, 8, 'Second row'); insert into t1 value (4, 5, 6, 'Fourth row'); -select * from t1; +select * from t1 order by pk; pk a b c +1 3 3 First row 2 7 8 Second row 4 5 6 Fourth row -1 3 3 First row show status like "Qcache_inserts"; Variable_name Value Qcache_inserts 3 show status like "Qcache_hits"; Variable_name Value Qcache_hits 1 -select * from t1; +select * from t1 order by pk; pk a b c +1 3 3 First row 2 7 8 Second row 4 5 6 Fourth row -1 3 3 First row show status like "Qcache_hits"; Variable_name Value Qcache_hits 2 @@ -81,10 +81,10 @@ show status like "Qcache_hits"; Variable_name Value Qcache_hits 3 use test; -select * from t1; +select * from t1 order by pk; pk a b c -2 7 8 Second row 1 3 3 First row +2 7 8 Second row select * from t1 where b=3; pk a b c 1 3 3 First row @@ -96,11 +96,11 @@ use test; show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 4 3 First row -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 4 3 First row @@ -110,11 +110,11 @@ Qcache_inserts 7 show status like "Qcache_hits"; Variable_name Value Qcache_hits 5 -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 4 3 First row -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 4 3 First row @@ -138,7 +138,7 @@ Qcache_inserts 7 show status like "Qcache_hits"; Variable_name Value Qcache_hits 7 -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 4 3 First row @@ -161,7 +161,7 @@ Qcache_inserts 8 show status like "Qcache_hits"; Variable_name Value Qcache_hits 7 -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 5 3 First row @@ -171,7 +171,7 @@ Qcache_inserts 9 show status like "Qcache_hits"; Variable_name Value Qcache_hits 7 -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 5 3 First row diff --git a/mysql-test/r/ndb_cache2.result b/mysql-test/r/ndb_cache2.result index ce10e9dab00..de4b3e31874 100644 --- a/mysql-test/r/ndb_cache2.result +++ b/mysql-test/r/ndb_cache2.result @@ -37,10 +37,10 @@ Variable_name Value Qcache_hits 1 insert into t1 value (2, 7, 8, 'Second row'); insert into t1 value (4, 5, 6, 'Fourth row'); -select * from t1; +select * from t1 order by pk desc; pk a b c -2 7 8 Second row 4 5 6 Fourth row +2 7 8 Second row 1 3 3 First row show status like "Qcache_inserts"; Variable_name Value @@ -48,10 +48,10 @@ Qcache_inserts 3 show status like "Qcache_hits"; Variable_name Value Qcache_hits 1 -select * from t1; +select * from t1 order by pk desc; pk a b c -2 7 8 Second row 4 5 6 Fourth row +2 7 8 Second row 1 3 3 First row show status like "Qcache_hits"; Variable_name Value @@ -82,7 +82,7 @@ show status like "Qcache_hits"; Variable_name Value Qcache_hits 3 use test; -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 3 3 First row @@ -97,11 +97,11 @@ use test; show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 4 3 First row -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 4 3 First row @@ -111,11 +111,11 @@ Qcache_inserts 7 show status like "Qcache_hits"; Variable_name Value Qcache_hits 5 -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 4 3 First row -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 4 3 First row @@ -139,7 +139,7 @@ Qcache_inserts 7 show status like "Qcache_hits"; Variable_name Value Qcache_hits 7 -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 4 3 First row @@ -162,7 +162,7 @@ Qcache_inserts 8 show status like "Qcache_hits"; Variable_name Value Qcache_hits 7 -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 5 3 First row @@ -172,7 +172,7 @@ Qcache_inserts 9 show status like "Qcache_hits"; Variable_name Value Qcache_hits 7 -select * from t1; +select * from t1 order by pk desc; pk a b c 2 7 8 Second row 1 5 3 First row diff --git a/mysql-test/t/ndb_cache.test b/mysql-test/t/ndb_cache.test index 8bdcbe17728..e899e94e4ac 100644 --- a/mysql-test/t/ndb_cache.test +++ b/mysql-test/t/ndb_cache.test @@ -35,10 +35,10 @@ show status like "Qcache_hits"; # Insert a new record and make sure the correct data is returned insert into t1 value (2, 7, 8, 'Second row'); insert into t1 value (4, 5, 6, 'Fourth row'); -select * from t1; +select * from t1 order by pk; show status like "Qcache_inserts"; show status like "Qcache_hits"; -select * from t1; +select * from t1 order by pk; show status like "Qcache_hits"; # Perform a "new" query and make sure the query cache is not hit @@ -60,7 +60,7 @@ show status like "Qcache_hits"; connect (con1,localhost,root,,); connection con1; use test; -select * from t1; +select * from t1 order by pk; select * from t1 where b=3; show status like "Qcache_hits"; @@ -70,13 +70,13 @@ connect (con2,localhost,root,,); connection con2; use test; show status like "Qcache_queries_in_cache"; -select * from t1; -select * from t1; +select * from t1 order by pk desc; +select * from t1 order by pk desc; show status like "Qcache_inserts"; show status like "Qcache_hits"; connection con1; -select * from t1; -select * from t1; +select * from t1 order by pk desc; +select * from t1 order by pk desc; show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; @@ -92,7 +92,7 @@ show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; connection con2; -select * from t1; +select * from t1 order by pk desc; show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; @@ -103,11 +103,11 @@ show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; connection con2; -select * from t1; +select * from t1 order by pk desc; show status like "Qcache_inserts"; show status like "Qcache_hits"; connection con1; -select * from t1; +select * from t1 order by pk desc; show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; diff --git a/mysql-test/t/ndb_cache2.test b/mysql-test/t/ndb_cache2.test index 5c1674a7021..c46935e8601 100644 --- a/mysql-test/t/ndb_cache2.test +++ b/mysql-test/t/ndb_cache2.test @@ -41,10 +41,10 @@ show status like "Qcache_hits"; # Insert a new record and make sure the correct data is returned insert into t1 value (2, 7, 8, 'Second row'); insert into t1 value (4, 5, 6, 'Fourth row'); -select * from t1; +select * from t1 order by pk desc; show status like "Qcache_inserts"; show status like "Qcache_hits"; -select * from t1; +select * from t1 order by pk desc; show status like "Qcache_hits"; # Perform a "new" query and make sure the query cache is not hit @@ -66,7 +66,7 @@ show status like "Qcache_hits"; connect (con1,localhost,root,,); connection con1; use test; -select * from t1; +select * from t1 order by pk desc; select * from t1 where b=3; show status like "Qcache_hits"; @@ -76,13 +76,13 @@ connect (con2,localhost,root,,); connection con2; use test; show status like "Qcache_queries_in_cache"; -select * from t1; -select * from t1; +select * from t1 order by pk desc; +select * from t1 order by pk desc; show status like "Qcache_inserts"; show status like "Qcache_hits"; connection con1; -select * from t1; -select * from t1; +select * from t1 order by pk desc; +select * from t1 order by pk desc; show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; @@ -95,7 +95,7 @@ show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; connection con2; -select * from t1; +select * from t1 order by pk desc; show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; @@ -107,11 +107,11 @@ show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; connection con2; -select * from t1; +select * from t1 order by pk desc; show status like "Qcache_inserts"; show status like "Qcache_hits"; connection con1; -select * from t1; +select * from t1 order by pk desc; show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index c5d501f3702..cca33cbbe1c 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -180,10 +180,10 @@ class ha_innobase: public handler /* ask handler about permission to cache table during query registration */ - my_bool cached_table_registration(THD *thd, char *table_key, - uint key_length, - qc_engine_callback *call_back, - ulonglong *engine_data) + my_bool register_query_cache_table(THD *thd, char *table_key, + uint key_length, + qc_engine_callback *call_back, + ulonglong *engine_data) { *call_back= innobase_query_caching_of_table_permitted; *engine_data= 0; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 849fac07821..d146e55f798 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -4026,7 +4026,6 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_force_send(TRUE), m_autoincrement_prefetch(32), m_transaction_on(TRUE), - m_use_local_query_cache(FALSE), m_multi_cursor(NULL) { int i; @@ -4820,31 +4819,48 @@ uint ndb_get_commitcount(THD* thd, char* dbname, char* tabname, DBUG_RETURN(1); ndb->setDatabaseName(dbname); - if (ndb_get_table_statistics(ndb, tabname, 0, commit_count)) + struct Ndb_statistics stat; + if (ndb_get_table_statistics(ndb, tabname, &stat)) DBUG_RETURN(1); + *commit_count= stat.commit_count; DBUG_RETURN(0); } -static -my_bool -ndbcluster_cache_retrieval_allowed( -/*======================================*/ - /* out: TRUE if permitted, FALSE if not; - note that the value FALSE means invalidation - of query cache if *engine_data is changed */ - THD* thd, /* in: thd of the user who is trying to - store a result to the query cache or - retrieve it */ - char* full_name, /* in: concatenation of database name, - the null character '\0', and the table - name */ - uint full_name_len, /* in: length of the full name, i.e. - len(dbname) + len(tablename) + 1 */ - ulonglong *engine_data) /* in: value set in call to - ha_ndbcluster::cached_table_registration - out: if return FALSE this is used to invalidate - all cached queries with this table*/ +/* + Check if a cached query can be used. + This is done by comparing the supplied engine_data to commit_count of + the table. + The commit_count is either retrieved from the share for the table, where + it has been cached by the util thread. If the util thread is not started, + NDB has to be contacetd to retrieve the commit_count, this will introduce + a small delay while waiting for NDB to answer. + + + SYNOPSIS + ndbcluster_cache_retrieval_allowed + thd thread handle + full_name concatenation of database name, + the null character '\0', and the table + name + full_name_len length of the full name, + i.e. len(dbname) + len(tablename) + 1 + + engine_data parameter retrieved when query was first inserted into + the cache. If the value of engine_data is changed, + all queries for this table should be invalidated. + + RETURN VALUE + TRUE Yes, use the query from cache + FALSE No, don't use the cached query, and if engine_data + has changed, all queries for this table should be invalidated + +*/ + +static my_bool +ndbcluster_cache_retrieval_allowed(THD* thd, + char* full_name, uint full_name_len, + ulonglong *engine_data) { DBUG_ENTER("ndbcluster_cache_retrieval_allowed"); @@ -4861,7 +4877,7 @@ ndbcluster_cache_retrieval_allowed( if (ndb_get_commitcount(thd, dbname, tabname, &commit_count)) { - *engine_data= *engine_data+1; // invalidate + *engine_data+= 1; // invalidate DBUG_RETURN(FALSE); } DBUG_PRINT("info", ("*engine_data=%llu, commit_count=%llu", @@ -4877,27 +4893,36 @@ ndbcluster_cache_retrieval_allowed( DBUG_RETURN(TRUE); } + +/** + Register a table for use in the query cache. Fetch the commit_count + for the table and return it in engine_data, this will later be used + to check if the table has changed, before the cached query is reused. + + SYNOPSIS + ha_ndbcluster::can_query_cache_table + thd thread handle + full_name concatenation of database name, + the null character '\0', and the table + name + full_name_len length of the full name, + i.e. len(dbname) + len(tablename) + 1 + qc_engine_callback function to be called before using cache on this table + engine_data out, commit_count for this table + + RETURN VALUE + TRUE Yes, it's ok to cahce this query + FALSE No, don't cach the query + +*/ + my_bool -ha_ndbcluster::cached_table_registration( -/*======================================*/ - /* out: TRUE if permitted, FALSE if not; - note that the value FALSE means invalidation - of query cache if *engine_data is changed */ - THD* thd, /* in: thd of the user who is trying to - store a result to the query cache or - retrieve it */ - char* full_name, /* in: concatenation of database name, - the null character '\0', and the table - name */ - uint full_name_len, /* in: length of the full name, i.e. - len(dbname) + len(tablename) + 1 */ - qc_engine_callback - *engine_callback, /* out: function to be called before using - cache on this table */ - ulonglong *engine_data) /* out: if return FALSE this is used to - invalidate all cached queries with this table*/ -{ - DBUG_ENTER("ha_ndbcluster::cached_table_registration"); +ha_ndbcluster::register_query_cache_table(THD* thd, + char* full_name, uint full_name_len, + qc_engine_callback *engine_callback, + ulonglong *engine_data) +{ + DBUG_ENTER("ha_ndbcluster::register_query_cache_table"); bool is_autocommit= !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)); DBUG_PRINT("enter",("dbname=%s, tabname=%s, is_autocommit=%d", @@ -5139,10 +5164,6 @@ ndb_get_table_statistics(Ndb* ndb, const char * table, pOp->close(TRUE); ndb->closeTransaction(pTrans); - if(row_count) - *row_count= sum_rows; - if(commit_count) - *commit_count= sum_commits; ndbstat->row_count= sum_rows; ndbstat->commit_count= sum_commits; @@ -5662,13 +5683,12 @@ extern "C" pthread_handler_decl(ndb_util_thread_func,arg __attribute__((unused)) // Contact NDB to get commit count for table g_ndb->setDatabaseName(db); - Uint64 rows, commit_count; - if(ndb_get_table_statistics(g_ndb, tabname, - &rows, &commit_count) == 0){ + struct Ndb_statistics stat;; + if(ndb_get_table_statistics(g_ndb, tabname, &stat) == 0){ DBUG_PRINT("ndb_util_thread", ("Table: %s, rows: %llu, commit_count: %llu", - share->table_name, rows, commit_count)); - share->commit_count= commit_count; + share->table_name, stat.row_count, stat.commit_count)); + share->commit_count= stat.commit_count; } else { diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index bd0d8cc7be5..fb624353491 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -157,11 +157,11 @@ class ha_ndbcluster: public handler static Thd_ndb* seize_thd_ndb(); static void release_thd_ndb(Thd_ndb* thd_ndb); uint8 table_cache_type(); - my_bool cached_table_registration(THD *thd, char *table_key, - uint key_length, - qc_engine_callback *engine_callback, - ulonglong *engine_data); - private: + my_bool register_query_cache_table(THD *thd, char *table_key, + uint key_length, + qc_engine_callback *engine_callback, + ulonglong *engine_data); +private: int alter_table_name(const char *to); int drop_table(); int create_index(const char *name, KEY *key_info, bool unique); diff --git a/sql/handler.h b/sql/handler.h index 2720a0bff33..04f196dccca 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -592,11 +592,12 @@ public: /* Type of table for caching query */ virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; } - /* ask handler about permission to cache table during query registration */ - virtual my_bool cached_table_registration(THD *thd, char *table_key, - uint key_length, - qc_engine_callback *engine_callback, - ulonglong *engine_data) + /* ask handler about permission to cache table when query is to be cached */ + virtual my_bool register_query_cache_table(THD *thd, char *table_key, + uint key_length, + qc_engine_callback + *engine_callback, + ulonglong *engine_data) { *engine_callback= 0; return 1; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 68964d80bf7..e38e417e6df 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2770,10 +2770,11 @@ my_bool Query_cache::ask_handler_allowance(THD *thd, for (; tables_used; tables_used= tables_used->next_global) { TABLE *table= tables_used->table; - if (!handler->cached_table_registration(thd, table->s->table_cache_key, - table->s->key_length, - &tables_used->callback_func, - &tables_used->engine_data)) + handler *handler= table->file; + if (!handler->register_query_cache_table(thd, table->s->table_cache_key, + table->s->key_length, + &tables_used->callback_func, + &tables_used->engine_data)) { DBUG_PRINT("qcache", ("Handler does not allow caching for %s.%s", tables_used->db, tables_used->alias)); |