summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-01-11 12:03:23 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2018-01-11 12:05:57 +0200
commite9842de20c09fa97bd95118eefaed6c87cf6645a (patch)
tree06b4830fe7bbc0f73c6e231b03e121de0b62056e
parentcdb7a8fa6928f3fb103ed7f66486dc9130a60e89 (diff)
parent578ffcc5efad3da20a21056067755e0ae9e39267 (diff)
downloadmariadb-git-e9842de20c09fa97bd95118eefaed6c87cf6645a.tar.gz
Merge 10.1 into 10.2
-rw-r--r--mysql-test/r/subselect.result26
-rw-r--r--mysql-test/r/subselect_no_exists_to_in.result26
-rw-r--r--mysql-test/r/subselect_no_mat.result26
-rw-r--r--mysql-test/r/subselect_no_opts.result26
-rw-r--r--mysql-test/r/subselect_no_scache.result26
-rw-r--r--mysql-test/r/subselect_no_semijoin.result26
-rw-r--r--mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result9
-rw-r--r--mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test24
-rw-r--r--mysql-test/suite/innodb/t/innodb-master.opt2
-rw-r--r--mysql-test/suite/mariabackup/huge_lsn.test1
-rw-r--r--mysql-test/t/subselect.test27
-rw-r--r--sql/opt_subselect.cc64
-rw-r--r--storage/innobase/buf/buf0lru.cc40
-rw-r--r--storage/innobase/trx/trx0purge.cc22
-rw-r--r--storage/xtradb/buf/buf0lru.cc138
-rw-r--r--storage/xtradb/trx/trx0purge.cc26
16 files changed, 327 insertions, 182 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 6021b501cb1..e2ed43158f1 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -7215,6 +7215,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result
index 3f20b30c809..6306cfff89d 100644
--- a/mysql-test/r/subselect_no_exists_to_in.result
+++ b/mysql-test/r/subselect_no_exists_to_in.result
@@ -7215,6 +7215,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
index f2b1403ef9f..0db1b031133 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -7208,6 +7208,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
index 301d1bef580..1fa6f385b2b 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -7206,6 +7206,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
index 5f719bb3d84..986542bd0bf 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -7221,6 +7221,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
index e5d89ccad5a..d5fcc17f08c 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -7206,6 +7206,32 @@ NULL
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
#
drop table t1, t2;
+#
+# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+# (5.5 test)
+#
+SET @optimiser_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+a
+5
+5
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+End of 5.5 tests
# End of 10.0 tests
#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
diff --git a/mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result b/mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result
new file mode 100644
index 00000000000..b9fee24c7ff
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result
@@ -0,0 +1,9 @@
+call mtr.add_suppression("\\[Warning\\] InnoDB: Difficult to find free blocks in the buffer pool.");
+SET SESSION debug_dbug="+d,ib_lru_force_no_free_page";
+CREATE TABLE t1 (j LONGBLOB) ENGINE = InnoDB;
+BEGIN;
+INSERT INTO t1 VALUES (repeat('abcdefghijklmnopqrstuvwxyz',200));
+COMMIT;
+SET SESSION debug_dbug="";
+DROP TABLE t1;
+FOUND 1 /InnoDB: Difficult to find free blocks / in mysqld.1.err
diff --git a/mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test b/mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test
new file mode 100644
index 00000000000..e358446eca9
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test
@@ -0,0 +1,24 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+call mtr.add_suppression("\\[Warning\\] InnoDB: Difficult to find free blocks in the buffer pool.");
+
+SET SESSION debug_dbug="+d,ib_lru_force_no_free_page";
+
+CREATE TABLE t1 (j LONGBLOB) ENGINE = InnoDB;
+BEGIN;
+INSERT INTO t1 VALUES (repeat('abcdefghijklmnopqrstuvwxyz',200));
+COMMIT;
+
+SET SESSION debug_dbug="";
+
+DROP TABLE t1;
+
+#
+# There should be only one message
+#
+let SEARCH_RANGE= -50000;
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
+--let SEARCH_PATTERN=InnoDB: Difficult to find free blocks
+--source include/search_pattern_in_file.inc
+
diff --git a/mysql-test/suite/innodb/t/innodb-master.opt b/mysql-test/suite/innodb/t/innodb-master.opt
index 5266978e4f0..2e71d62206d 100644
--- a/mysql-test/suite/innodb/t/innodb-master.opt
+++ b/mysql-test/suite/innodb/t/innodb-master.opt
@@ -2,3 +2,5 @@
--default-storage-engine=MyISAM
--innodb-strict-mode=0
--innodb-file-per-table=0
+--loose-innodb-track-changed-pages
+--loose-innodb-log-archive
diff --git a/mysql-test/suite/mariabackup/huge_lsn.test b/mysql-test/suite/mariabackup/huge_lsn.test
index 7a9dd4e2631..417d40c8e7a 100644
--- a/mysql-test/suite/mariabackup/huge_lsn.test
+++ b/mysql-test/suite/mariabackup/huge_lsn.test
@@ -1,4 +1,5 @@
--source include/not_embedded.inc
+--source include/have_file_key_management.inc
--echo #
--echo # MDEV-13416 mariabackup fails with EFAULT "Bad Address"
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index a7c07b78017..7e9e5a731bc 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -6076,6 +6076,33 @@ SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
--echo #
drop table t1, t2;
+--echo #
+--echo # MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
+--echo # (5.5 test)
+--echo #
+SET @optimiser_switch_save= @@optimizer_switch;
+
+CREATE TABLE t1 (a INT NOT NULL);
+INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
+
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (5),(1);
+
+CREATE TABLE t3 (c INT, KEY(c));
+INSERT INTO t3 VALUES (5),(5);
+
+SET optimizer_switch='semijoin=on';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+
+SET optimizer_switch='semijoin=off';
+select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
+and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
+
+SET @@optimizer_switch= @optimiser_switch_save;
+DROP TABLE t1, t2, t3;
+
+--echo End of 5.5 tests
--echo # End of 10.0 tests
--echo #
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 43be2ea8ad4..e048df6ef11 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -2701,7 +2701,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
LooseScan detector in best_access_path)
*/
remaining_tables &= ~new_join_tab->table->map;
- table_map dups_producing_tables;
+ table_map dups_producing_tables, prev_dups_producing_tables,
+ prev_sjm_lookup_tables;
if (idx == join->const_tables)
dups_producing_tables= 0;
@@ -2712,7 +2713,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
if ((emb_sj_nest= new_join_tab->emb_sj_nest))
dups_producing_tables |= emb_sj_nest->sj_inner_tables;
- Semi_join_strategy_picker **strategy;
+ Semi_join_strategy_picker **strategy, **prev_strategy;
if (idx == join->const_tables)
{
/* First table, initialize pickers */
@@ -2764,23 +2765,54 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
3. We have no clue what to do about fanount of semi-join Y.
*/
if ((dups_producing_tables & handled_fanout) ||
- (read_time < *current_read_time &&
+ (read_time < *current_read_time &&
!(handled_fanout & pos->inner_tables_handled_with_other_sjs)))
{
- /* Mark strategy as used */
- (*strategy)->mark_used();
- pos->sj_strategy= sj_strategy;
- if (sj_strategy == SJ_OPT_MATERIALIZE)
- join->sjm_lookup_tables |= handled_fanout;
+ DBUG_ASSERT(pos->sj_strategy != sj_strategy);
+ /*
+ If the strategy choosen first time or
+ the strategy replace strategy which was used to exectly the same
+ tables
+ */
+ if (pos->sj_strategy == SJ_OPT_NONE ||
+ handled_fanout ==
+ (prev_dups_producing_tables ^ dups_producing_tables))
+ {
+ prev_strategy= strategy;
+ if (pos->sj_strategy == SJ_OPT_NONE)
+ {
+ prev_dups_producing_tables= dups_producing_tables;
+ prev_sjm_lookup_tables= join->sjm_lookup_tables;
+ }
+ /* Mark strategy as used */
+ (*strategy)->mark_used();
+ pos->sj_strategy= sj_strategy;
+ if (sj_strategy == SJ_OPT_MATERIALIZE)
+ join->sjm_lookup_tables |= handled_fanout;
+ else
+ join->sjm_lookup_tables &= ~handled_fanout;
+ *current_read_time= read_time;
+ *current_record_count= rec_count;
+ dups_producing_tables &= ~handled_fanout;
+ //TODO: update bitmap of semi-joins that were handled together with
+ // others.
+ if (is_multiple_semi_joins(join, join->positions, idx,
+ handled_fanout))
+ pos->inner_tables_handled_with_other_sjs |= handled_fanout;
+ }
else
- join->sjm_lookup_tables &= ~handled_fanout;
- *current_read_time= read_time;
- *current_record_count= rec_count;
- dups_producing_tables &= ~handled_fanout;
- //TODO: update bitmap of semi-joins that were handled together with
- // others.
- if (is_multiple_semi_joins(join, join->positions, idx, handled_fanout))
- pos->inner_tables_handled_with_other_sjs |= handled_fanout;
+ {
+ /* Conflict fall to most general variant */
+ (*prev_strategy)->set_empty();
+ dups_producing_tables= prev_dups_producing_tables;
+ join->sjm_lookup_tables= prev_sjm_lookup_tables;
+ // mark it 'none' to avpoid loops
+ pos->sj_strategy= SJ_OPT_NONE;
+ // next skip to last;
+ strategy= pickers +
+ (sizeof(pickers)/sizeof(Semi_join_strategy_picker*) - 3);
+ continue;
+ }
}
else
{
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 26814418033..10ee106137d 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -80,6 +80,10 @@ static const ulint BUF_LRU_SEARCH_SCAN_THRESHOLD = 100;
frames in the buffer pool, we set this to TRUE */
static bool buf_lru_switched_on_innodb_mon = false;
+/** True if diagnostic message about difficult to find free blocks
+in the buffer bool has already printed. */
+static bool buf_lru_free_blocks_error_printed;
+
/******************************************************************//**
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
and page_zip_decompress() operations. Based on the statistics,
@@ -1079,8 +1083,6 @@ buf_LRU_get_free_block(
bool freed = false;
ulint n_iterations = 0;
ulint flush_failures = 0;
- bool mon_value_was = false;
- bool started_monitor = false;
MONITOR_INC(MONITOR_LRU_GET_FREE_SEARCH);
loop:
@@ -1088,6 +1090,11 @@ loop:
buf_LRU_check_size_of_non_data_objects(buf_pool);
+ DBUG_EXECUTE_IF("ib_lru_force_no_free_page",
+ if (!buf_lru_free_blocks_error_printed) {
+ n_iterations = 21;
+ goto not_found;});
+
/* If there is a block in the free list, take it */
block = buf_LRU_get_free_only(buf_pool);
@@ -1097,11 +1104,6 @@ loop:
ut_ad(buf_pool_from_block(block) == buf_pool);
memset(&block->page.zip, 0, sizeof block->page.zip);
- if (started_monitor) {
- srv_print_innodb_monitor =
- static_cast<my_bool>(mon_value_was);
- }
-
block->skip_flush_check = false;
block->page.flush_observer = NULL;
return(block);
@@ -1131,24 +1133,24 @@ loop:
}
}
+#ifndef DBUG_OFF
+not_found:
+#endif
+
buf_pool_mutex_exit(buf_pool);
if (freed) {
goto loop;
}
- if (n_iterations > 20
+ if (n_iterations > 20 && !buf_lru_free_blocks_error_printed
&& srv_buf_pool_old_size == srv_buf_pool_size) {
ib::warn() << "Difficult to find free blocks in the buffer pool"
" (" << n_iterations << " search iterations)! "
<< flush_failures << " failed attempts to"
- " flush a page! Consider increasing the buffer pool"
- " size. It is also possible that in your Unix version"
- " fsync is very slow, or completely frozen inside"
- " the OS kernel. Then upgrading to a newer version"
- " of your operating system may help. Look at the"
- " number of fsyncs in diagnostic info below."
+ " flush a page!"
+ " Consider increasing innodb_buffer_pool_size."
" Pending flushes (fsync) log: "
<< fil_n_pending_log_flushes
<< "; buffer pool: "
@@ -1156,13 +1158,9 @@ loop:
<< ". " << os_n_file_reads << " OS file reads, "
<< os_n_file_writes << " OS file writes, "
<< os_n_fsyncs
- << " OS fsyncs. Starting InnoDB Monitor to print"
- " further diagnostics to the standard output.";
+ << " OS fsyncs.";
- mon_value_was = srv_print_innodb_monitor;
- started_monitor = true;
- srv_print_innodb_monitor = true;
- os_event_set(srv_monitor_event);
+ buf_lru_free_blocks_error_printed = true;
}
/* If we have scanned the whole LRU and still are unable to
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 4fd9333c0ba..07150577d22 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -1162,28 +1162,6 @@ trx_purge_rseg_get_next_history_log(
mutex_exit(&(rseg->mutex));
mtr_commit(&mtr);
-
- trx_sys_mutex_enter();
-
- /* Add debug code to track history list corruption reported
- on the MySQL mailing list on Nov 9, 2004. The fut0lst.cc
- file-based list was corrupt. The prev node pointer was
- FIL_NULL, even though the list length was over 8 million nodes!
- We assume that purge truncates the history list in large
- size pieces, and if we here reach the head of the list, the
- list cannot be longer than 2000 000 undo logs now. */
-
- if (trx_sys->rseg_history_len > 2000000) {
- ib::warn() << "Purge reached the head of the history"
- " list, but its length is still reported as "
- << trx_sys->rseg_history_len << "! Make"
- " a detailed bug report, and submit it to"
- " https://jira.mariadb.org/";
- ut_ad(0);
- }
-
- trx_sys_mutex_exit();
-
return;
}
diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc
index c71d45009e4..a84f2a832f3 100644
--- a/storage/xtradb/buf/buf0lru.cc
+++ b/storage/xtradb/buf/buf0lru.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -87,6 +87,10 @@ buffer pools. */
frames in the buffer pool, we set this to TRUE */
static ibool buf_lru_switched_on_innodb_mon = FALSE;
+/** True if diagnostic message about difficult to find free blocks
+in the buffer bool has already printed. */
+static bool buf_lru_free_blocks_error_printed;
+
/******************************************************************//**
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
and page_zip_decompress() operations. Based on the statistics,
@@ -1080,68 +1084,39 @@ buf_LRU_check_size_of_non_data_objects(
}
/** Diagnose failure to get a free page and request InnoDB monitor output in
-the error log if more than two seconds have been spent already.
+the error log if it has not yet printed.
@param[in] n_iterations how many buf_LRU_get_free_page iterations
already completed
-@param[in] started_ms timestamp in ms of when the attempt to get the
- free page started
@param[in] flush_failures how many times single-page flush, if allowed,
has failed
-@param[out] mon_value_was previous srv_print_innodb_monitor value
-@param[out] started_monitor whether InnoDB monitor print has been requested
*/
static
void
-buf_LRU_handle_lack_of_free_blocks(ulint n_iterations, ulint started_ms,
- ulint flush_failures,
- ibool *mon_value_was,
- ibool *started_monitor)
+buf_LRU_handle_lack_of_free_blocks(
+ ulint n_iterations,
+ ulint flush_failures)
{
- static ulint last_printout_ms = 0;
-
- /* Legacy algorithm started warning after at least 2 seconds, we
- emulate this. */
- const ulint current_ms = ut_time_ms();
-
- if ((current_ms > started_ms + 2000)
- && (current_ms > last_printout_ms + 2000)) {
-
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: difficult to find free blocks in\n"
- "InnoDB: the buffer pool (%lu search iterations)!\n"
- "InnoDB: %lu failed attempts to flush a page!"
- " Consider\n"
- "InnoDB: increasing the buffer pool size.\n"
- "InnoDB: It is also possible that"
- " in your Unix version\n"
- "InnoDB: fsync is very slow, or"
- " completely frozen inside\n"
- "InnoDB: the OS kernel. Then upgrading to"
- " a newer version\n"
- "InnoDB: of your operating system may help."
- " Look at the\n"
- "InnoDB: number of fsyncs in diagnostic info below.\n"
- "InnoDB: Pending flushes (fsync) log: %lu;"
- " buffer pool: %lu\n"
- "InnoDB: %lu OS file reads, %lu OS file writes,"
- " %lu OS fsyncs\n"
- "InnoDB: Starting InnoDB Monitor to print further\n"
- "InnoDB: diagnostics to the standard output.\n",
- (ulong) n_iterations,
- (ulong) flush_failures,
- (ulong) fil_n_pending_log_flushes,
- (ulong) fil_n_pending_tablespace_flushes,
- (ulong) os_n_file_reads, (ulong) os_n_file_writes,
- (ulong) os_n_fsyncs);
-
- last_printout_ms = current_ms;
- *mon_value_was = srv_print_innodb_monitor;
- *started_monitor = TRUE;
- srv_print_innodb_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ if (n_iterations > 20 && !buf_lru_free_blocks_error_printed) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Difficult to find free blocks in"
+ " the buffer pool (" ULINTPF " search iterations)! "
+ ULINTPF " failed attempts to flush a page!",
+ n_iterations, flush_failures);
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Consider increasing the buffer pool size.");
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Pending flushes (fsync) log: " ULINTPF
+ " buffer pool: " ULINTPF
+ " OS file reads: " ULINTPF " OS file writes: "
+ ULINTPF " OS fsyncs: " ULINTPF "",
+ fil_n_pending_log_flushes,
+ fil_n_pending_tablespace_flushes,
+ os_n_file_reads,
+ os_n_file_writes,
+ os_n_fsyncs);
+
+ buf_lru_free_blocks_error_printed = true;
}
-
}
/** The maximum allowed backoff sleep time duration, microseconds */
@@ -1189,9 +1164,6 @@ buf_LRU_get_free_block(
ibool freed = FALSE;
ulint n_iterations = 0;
ulint flush_failures = 0;
- ibool mon_value_was = FALSE;
- ibool started_monitor = FALSE;
- ulint started_ms = 0;
ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));
@@ -1199,42 +1171,20 @@ buf_LRU_get_free_block(
loop:
buf_LRU_check_size_of_non_data_objects(buf_pool);
- /* If there is a block in the free list, take it */
- if (DBUG_EVALUATE_IF("simulate_lack_of_pages", true, false)) {
-
- block = NULL;
-
- if (srv_debug_monitor_printed)
- DBUG_SET("-d,simulate_lack_of_pages");
-
- } else if (DBUG_EVALUATE_IF("simulate_recovery_lack_of_pages",
- recv_recovery_on, false)) {
-
- block = NULL;
-
- if (srv_debug_monitor_printed)
- DBUG_SUICIDE();
- } else {
+ DBUG_EXECUTE_IF("ib_lru_force_no_free_page",
+ if (!buf_lru_free_blocks_error_printed) {
+ n_iterations = 21;
+ goto not_found;});
- block = buf_LRU_get_free_only(buf_pool);
- }
+ block = buf_LRU_get_free_only(buf_pool);
if (block) {
ut_ad(buf_pool_from_block(block) == buf_pool);
memset(&block->page.zip, 0, sizeof block->page.zip);
-
- if (started_monitor) {
- srv_print_innodb_monitor =
- static_cast<my_bool>(mon_value_was);
- }
-
return(block);
}
- if (!started_ms)
- started_ms = ut_time_ms();
-
if (srv_empty_free_list_algorithm == SRV_EMPTY_FREE_LIST_BACKOFF
&& buf_lru_manager_is_active
&& (srv_shutdown_state == SRV_SHUTDOWN_NONE
@@ -1272,10 +1222,7 @@ loop:
: FREE_LIST_BACKOFF_LOW_PRIO_DIVIDER));
}
- buf_LRU_handle_lack_of_free_blocks(n_iterations, started_ms,
- flush_failures,
- &mon_value_was,
- &started_monitor);
+ buf_LRU_handle_lack_of_free_blocks(n_iterations, flush_failures);
n_iterations++;
@@ -1314,13 +1261,8 @@ loop:
mutex_exit(&buf_pool->flush_state_mutex);
- if (DBUG_EVALUATE_IF("simulate_recovery_lack_of_pages", true, false)
- || DBUG_EVALUATE_IF("simulate_lack_of_pages", true, false)) {
-
- buf_pool->try_LRU_scan = false;
- }
-
freed = FALSE;
+
if (buf_pool->try_LRU_scan || n_iterations > 0) {
/* If no block was in the free list, search from the
@@ -1345,9 +1287,11 @@ loop:
}
- buf_LRU_handle_lack_of_free_blocks(n_iterations, started_ms,
- flush_failures, &mon_value_was,
- &started_monitor);
+#ifndef DBUG_OFF
+not_found:
+#endif
+
+ buf_LRU_handle_lack_of_free_blocks(n_iterations, flush_failures);
/* If we have scanned the whole LRU and still are unable to
find a free block then we should sleep here to let the
diff --git a/storage/xtradb/trx/trx0purge.cc b/storage/xtradb/trx/trx0purge.cc
index ff82bb2ad4e..cbf783628f9 100644
--- a/storage/xtradb/trx/trx0purge.cc
+++ b/storage/xtradb/trx/trx0purge.cc
@@ -584,32 +584,6 @@ trx_purge_rseg_get_next_history_log(
mutex_exit(&(rseg->mutex));
mtr_commit(&mtr);
-
- mutex_enter(&trx_sys->mutex);
-
- /* Add debug code to track history list corruption reported
- on the MySQL mailing list on Nov 9, 2004. The fut0lst.cc
- file-based list was corrupt. The prev node pointer was
- FIL_NULL, even though the list length was over 8 million nodes!
- We assume that purge truncates the history list in large
- size pieces, and if we here reach the head of the list, the
- list cannot be longer than 2000 000 undo logs now. */
-
- if (trx_sys->rseg_history_len > 2000000) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: purge reached the"
- " head of the history list,\n"
- "InnoDB: but its length is still"
- " reported as %lu! Make a detailed bug\n"
- "InnoDB: report, and submit it"
- " to https://jira.mariadb.org/\n",
- (ulong) trx_sys->rseg_history_len);
- ut_ad(0);
- }
-
- mutex_exit(&trx_sys->mutex);
-
return;
}