diff options
-rw-r--r-- | mysql-test/r/log_tables.result | 5 | ||||
-rw-r--r-- | mysql-test/t/log_tables.test | 10 | ||||
-rw-r--r-- | sql/sql_base.cc | 18 |
3 files changed, 26 insertions, 7 deletions
diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result index c61dd2247ee..c817c2752a0 100644 --- a/mysql-test/r/log_tables.result +++ b/mysql-test/r/log_tables.result @@ -72,3 +72,8 @@ sleep(2) select * from mysql.slow_log; start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text TIMESTAMP USER_HOST QUERY_TIME 00:00:00 1 0 test 0 0 1 select sleep(2) +flush tables with read lock; +unlock tables; +use mysql; +lock tables general_log read local, help_category read local; +unlock tables; diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test index 5b79e5e4625..236ef87e948 100644 --- a/mysql-test/t/log_tables.test +++ b/mysql-test/t/log_tables.test @@ -171,6 +171,16 @@ select sleep(2); --replace_column 1 TIMESTAMP 2 USER_HOST 3 QUERY_TIME select * from mysql.slow_log; +# +# Bug #20139 Infinite loop after "FLUSH" and "LOCK tabX, general_log" +# + +flush tables with read lock; +unlock tables; +use mysql; +lock tables general_log read local, help_category read local; +unlock tables; + # kill all connections disconnect con1; disconnect con2; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index db11a3442c2..53ece79562a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1997,17 +1997,17 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length, &state)) { - if (table->s->version != refresh_version) + /* + Here we flush tables marked for flush. However we never flush log + tables here. They are flushed only on FLUSH LOGS. + */ + if (table->s->version != refresh_version && !table->s->log_table) { DBUG_PRINT("note", ("Found table '%s.%s' with different refresh version", table_list->db, table_list->table_name)); - /* - Don't close tables if we are working with a log table or were - asked not to close the table explicitly - */ - if (flags & MYSQL_LOCK_IGNORE_FLUSH || table->s->log_table) + if (flags & MYSQL_LOCK_IGNORE_FLUSH) { /* Force close at once after usage */ thd->version= table->s->version; @@ -2346,7 +2346,11 @@ void close_old_data_files(THD *thd, TABLE *table, bool abort_locks, for (; table ; table=table->next) { - if (table->s->version != refresh_version) + /* + Reopen marked for flush. But close log tables. They are flushed only + explicitly on FLUSH LOGS + */ + if (table->s->version != refresh_version && !table->s->log_table) { found=1; if (table->db_stat) |