Bug #43032 | The query cache can appear to no longer function in certain circumstances | ||
---|---|---|---|
Submitted: | 19 Feb 2009 19:38 | Modified: | 13 Mar 2009 19:55 |
Reporter: | Von Chance | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: Query Cache | Severity: | S5 (Performance) |
Version: | 5.0.67, 5.0.76, any | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[19 Feb 2009 19:38]
Von Chance
[20 Feb 2009 10:40]
Valeriy Kravchuk
Thank you for the problem report. Verified just as described. May be related to bug #42197.
[12 Mar 2009 18:10]
MySQL Verification Team
This is not a bug. The query cache itself is a global resource. It is not aware of any transactional states nor does it keep multiple versions of any one query based on their transaction number. This is exactly why we implemented the Qcache_not_cached statistic: There is no way for us to cache the results of a query that must be repeatable from within a transaction because the Query Cache is a global, non-transactional resource. Unless the core implementation of the Query Cache changes considerably, this must be considered appropriate behavior. Marking this as "Not a Bug"
[13 Mar 2009 19:55]
Von Chance
I agree with some of the statements above, however I don't think it is appropriate to indicate that this is "not a bug" because the implementation does not account for it. That could apply to just about every bug out there. The query cache does have knowledge of the transactional state, albeit indirectly. This is evidenced by the behavior of the test scenario above and reviewing the source code of mysql itself. The query cache makes a call to ask_handler_allowance which asks the engine if any of the tables included in the current query are not cacheable. In the innodb case, it eventually flows down to the row_search_check_if_query_cache_permitted function. In this function, the following check is performed: ... if (UT_LIST_GET_LEN(table->locks) == 0 && ut_dulint_cmp(trx->id, table->query_cache_inv_trx_id) >= 0) { ... This seems to invalidate any open transaction that was created before a transaction causing the query cache to be invalidated. This would be true for a repeatable read isolation level, but is not true for a read committed isolation level. ** This could be changed to allow this or simply document that this is one of the conditions that would prevent a query to be cacheable. The ability to fetch the reason why a particular query was not cacheable would also be beneficial.