summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/log_tables.result5
-rw-r--r--mysql-test/t/log_tables.test10
-rw-r--r--sql/sql_base.cc18
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)