From 7f04686a2a50be00e25f2073266dd341664155f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 29 Oct 2020 09:15:35 +0200 Subject: MDEV-24049 InnoDB: Failing assertion: node->is_open() in fil_space_t::flush_low As part of MDEV-23855, we eliminated fil_system.LRU and changed the way how InnoDB data files are opened. We are also enforcing the innodb_open_files limit when new data files are created. The function fil_space_t::flush() would be invoked by row_quiesce_table_start(). If the table was already in clean state, it is possible that the data file is not open. fil_space_t::flush_low(): If the data file is not open, check with a debug assertion that there are no unflushed changes, and carry on. Reviewed by: Eugene Kosov and Thirunarayanan Balathandayuthapani --- mysql-test/suite/innodb/r/flush.result | 16 ++++++++++++++++ mysql-test/suite/innodb/t/flush.opt | 1 + mysql-test/suite/innodb/t/flush.test | 19 +++++++++++++++++++ storage/innobase/fil/fil0fil.cc | 6 +++++- 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/innodb/r/flush.result create mode 100644 mysql-test/suite/innodb/t/flush.opt create mode 100644 mysql-test/suite/innodb/t/flush.test diff --git a/mysql-test/suite/innodb/r/flush.result b/mysql-test/suite/innodb/r/flush.result new file mode 100644 index 00000000000..cd6bec48d4e --- /dev/null +++ b/mysql-test/suite/innodb/r/flush.result @@ -0,0 +1,16 @@ +SELECT @@GLOBAL.innodb_open_files; +@@GLOBAL.innodb_open_files +10 +CREATE TABLE t0 (a INT) ENGINE=InnoDB; +FLUSH TABLE t0 WITH READ LOCK; +UNLOCK TABLES; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +CREATE TABLE t3 (a INT) ENGINE=InnoDB; +CREATE TABLE t4 (a INT) ENGINE=InnoDB; +CREATE TABLE t5 (a INT) ENGINE=InnoDB; +CREATE TABLE t6 (a INT) ENGINE=InnoDB; +CREATE TABLE t7 (a INT) ENGINE=InnoDB; +FLUSH TABLE t0 WITH READ LOCK; +UNLOCK TABLES; +DROP TABLE t0, t1, t2, t3, t4, t5, t6, t7; diff --git a/mysql-test/suite/innodb/t/flush.opt b/mysql-test/suite/innodb/t/flush.opt new file mode 100644 index 00000000000..99dbd8f47c3 --- /dev/null +++ b/mysql-test/suite/innodb/t/flush.opt @@ -0,0 +1 @@ +--innodb-open-files=10 diff --git a/mysql-test/suite/innodb/t/flush.test b/mysql-test/suite/innodb/t/flush.test new file mode 100644 index 00000000000..e03728825cf --- /dev/null +++ b/mysql-test/suite/innodb/t/flush.test @@ -0,0 +1,19 @@ +--source include/have_innodb.inc + +SELECT @@GLOBAL.innodb_open_files; + +CREATE TABLE t0 (a INT) ENGINE=InnoDB; +# Ensure that the created table t0 is clean. +FLUSH TABLE t0 WITH READ LOCK; +UNLOCK TABLES; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +CREATE TABLE t3 (a INT) ENGINE=InnoDB; +CREATE TABLE t4 (a INT) ENGINE=InnoDB; +CREATE TABLE t5 (a INT) ENGINE=InnoDB; +CREATE TABLE t6 (a INT) ENGINE=InnoDB; +CREATE TABLE t7 (a INT) ENGINE=InnoDB; +# Now, the data file for t0 should not be open anymore. +FLUSH TABLE t0 WITH READ LOCK; +UNLOCK TABLES; +DROP TABLE t0, t1, t2, t3, t4, t5, t6, t7; diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index d234fed4e89..c515cd82c48 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -514,7 +514,11 @@ inline void fil_space_t::flush_low() for (fil_node_t *node= UT_LIST_GET_FIRST(chain); node; node= UT_LIST_GET_NEXT(chain, node)) { - ut_a(node->is_open()); + if (!node->is_open()) + { + ut_ad(!is_in_unflushed_spaces); + continue; + } IF_WIN(if (node->is_raw_disk) continue,); os_file_flush(node->handle); } -- cgit v1.2.1