From 2c4b6dc503bdb024e10d2f464e4502dce068f80e Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Fri, 26 Feb 2010 10:58:33 +0100 Subject: [PATCH] Bug #51336 Assert in reload_acl_and_cache during RESET QUERY CACHE Attempts to execute RESET statements within a transaction that had acquired metadata locks, led to an assertion failure on debug servers. This bug didn't cause any problems on release builds. The triggered assert is designed to check that caches are not flushed or reset while having active transactions. It is triggered if acquired metadata locks exist that are not from LOCK TABLE or HANDLER statements. In this case it was triggered by RESET QUERY CACHE while having an active transaction that had acquired locks. The reason the assertion was triggered, was that RESET statements, unlike the similar FLUSH statements, was not causing an implicit commit. This patch fixes the problem by making sure RESET statements commit the current transaction before executing. The commit causes acquired metadata locks to be released, preventing the assertion from being triggered. Incompatible change: This patch changes RESET statements so that they cause an implicit commit. Test case added to query_cache.test. --- mysql-test/r/implicit_commit.result | 5 +++++ mysql-test/r/query_cache.result | 11 +++++++++++ mysql-test/t/implicit_commit.test | 4 ++++ mysql-test/t/query_cache.test | 19 +++++++++++++++++++ sql/log_event.cc | 1 + sql/sql_parse.cc | 1 + 6 files changed, 41 insertions(+) diff --git a/mysql-test/r/implicit_commit.result b/mysql-test/r/implicit_commit.result index 8c330550a3b..d568d05e7b7 100644 --- a/mysql-test/r/implicit_commit.result +++ b/mysql-test/r/implicit_commit.result @@ -658,6 +658,11 @@ YES # # SQLCOM_RESET # +INSERT INTO db1.trans (a) VALUES (1); +reset query cache; +CALL db1.test_if_commit(); +IMPLICIT COMMIT +YES # # SQLCOM_PURGE # diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index eab0c51f974..112a86e0c88 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -1721,3 +1721,14 @@ SELECT SQL_CACHE * FROM t1 WHERE a IN ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list' DROP TABLE t1; End of 5.1 tests +# +# Bug#51336 Assert in reload_acl_and_cache during RESET QUERY CACHE +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(id INT); +START TRANSACTION; +SELECT * FROM t1; +id +RESET QUERY CACHE; +COMMIT; +DROP TABLE t1; diff --git a/mysql-test/t/implicit_commit.test b/mysql-test/t/implicit_commit.test index d8ffd6e9452..b10788bd891 100644 --- a/mysql-test/t/implicit_commit.test +++ b/mysql-test/t/implicit_commit.test @@ -697,6 +697,10 @@ source include/implicit_commit_helper.inc; --echo # SQLCOM_RESET --echo # +let $statement= + reset query cache; +source include/implicit_commit_helper.inc; + --echo # --echo # SQLCOM_PURGE --echo # diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 993f231759b..ce49ca89eca 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -1363,3 +1363,22 @@ SELECT SQL_CACHE * FROM t1 WHERE a IN DROP TABLE t1; --echo End of 5.1 tests + + +--echo # +--echo # Bug#51336 Assert in reload_acl_and_cache during RESET QUERY CACHE +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1(id INT); + +START TRANSACTION; +SELECT * FROM t1; +# This caused an assert +RESET QUERY CACHE; + +COMMIT; +DROP TABLE t1; diff --git a/sql/log_event.cc b/sql/log_event.cc index b0437b7c2e5..87ac577d7b2 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2521,6 +2521,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, case SQLCOM_ASSIGN_TO_KEYCACHE: case SQLCOM_PRELOAD_KEYS: case SQLCOM_FLUSH: + case SQLCOM_RESET: case SQLCOM_CHECK: implicit_commit= TRUE; break; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 19373b58b49..e66f2756c54 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -325,6 +325,7 @@ void init_update_queries(void) sql_command_flags[SQLCOM_PRELOAD_KEYS]= CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_FLUSH]= CF_AUTO_COMMIT_TRANS; + sql_command_flags[SQLCOM_RESET]= CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_CHECK]= CF_AUTO_COMMIT_TRANS; }