mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge 10.1 into 10.2
This commit is contained in:
@ -7215,6 +7215,32 @@ NULL
|
|||||||
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
||||||
#
|
#
|
||||||
drop table t1, t2;
|
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
|
# End of 10.0 tests
|
||||||
#
|
#
|
||||||
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
||||||
|
@ -7215,6 +7215,32 @@ NULL
|
|||||||
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
||||||
#
|
#
|
||||||
drop table t1, t2;
|
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
|
# End of 10.0 tests
|
||||||
#
|
#
|
||||||
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
||||||
|
@ -7208,6 +7208,32 @@ NULL
|
|||||||
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
||||||
#
|
#
|
||||||
drop table t1, t2;
|
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
|
# End of 10.0 tests
|
||||||
#
|
#
|
||||||
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
||||||
|
@ -7206,6 +7206,32 @@ NULL
|
|||||||
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
||||||
#
|
#
|
||||||
drop table t1, t2;
|
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
|
# End of 10.0 tests
|
||||||
#
|
#
|
||||||
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
||||||
|
@ -7221,6 +7221,32 @@ NULL
|
|||||||
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
||||||
#
|
#
|
||||||
drop table t1, t2;
|
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
|
# End of 10.0 tests
|
||||||
#
|
#
|
||||||
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
||||||
|
@ -7206,6 +7206,32 @@ NULL
|
|||||||
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
# SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
||||||
#
|
#
|
||||||
drop table t1, t2;
|
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
|
# End of 10.0 tests
|
||||||
#
|
#
|
||||||
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
|
||||||
|
@ -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
|
24
mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test
Normal file
24
mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test
Normal file
@ -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
|
||||||
|
|
@ -2,3 +2,5 @@
|
|||||||
--default-storage-engine=MyISAM
|
--default-storage-engine=MyISAM
|
||||||
--innodb-strict-mode=0
|
--innodb-strict-mode=0
|
||||||
--innodb-file-per-table=0
|
--innodb-file-per-table=0
|
||||||
|
--loose-innodb-track-changed-pages
|
||||||
|
--loose-innodb-log-archive
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
--source include/not_embedded.inc
|
--source include/not_embedded.inc
|
||||||
|
--source include/have_file_key_management.inc
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-13416 mariabackup fails with EFAULT "Bad Address"
|
--echo # MDEV-13416 mariabackup fails with EFAULT "Bad Address"
|
||||||
|
@ -6076,6 +6076,33 @@ SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
|
|||||||
--echo #
|
--echo #
|
||||||
drop table t1, t2;
|
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 # End of 10.0 tests
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -2701,7 +2701,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
|
|||||||
LooseScan detector in best_access_path)
|
LooseScan detector in best_access_path)
|
||||||
*/
|
*/
|
||||||
remaining_tables &= ~new_join_tab->table->map;
|
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)
|
if (idx == join->const_tables)
|
||||||
dups_producing_tables= 0;
|
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))
|
if ((emb_sj_nest= new_join_tab->emb_sj_nest))
|
||||||
dups_producing_tables |= emb_sj_nest->sj_inner_tables;
|
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)
|
if (idx == join->const_tables)
|
||||||
{
|
{
|
||||||
/* First table, initialize pickers */
|
/* 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.
|
3. We have no clue what to do about fanount of semi-join Y.
|
||||||
*/
|
*/
|
||||||
if ((dups_producing_tables & handled_fanout) ||
|
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)))
|
!(handled_fanout & pos->inner_tables_handled_with_other_sjs)))
|
||||||
{
|
{
|
||||||
/* Mark strategy as used */
|
DBUG_ASSERT(pos->sj_strategy != sj_strategy);
|
||||||
(*strategy)->mark_used();
|
/*
|
||||||
pos->sj_strategy= sj_strategy;
|
If the strategy choosen first time or
|
||||||
if (sj_strategy == SJ_OPT_MATERIALIZE)
|
the strategy replace strategy which was used to exectly the same
|
||||||
join->sjm_lookup_tables |= handled_fanout;
|
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
|
else
|
||||||
join->sjm_lookup_tables &= ~handled_fanout;
|
{
|
||||||
*current_read_time= read_time;
|
/* Conflict fall to most general variant */
|
||||||
*current_record_count= rec_count;
|
(*prev_strategy)->set_empty();
|
||||||
dups_producing_tables &= ~handled_fanout;
|
dups_producing_tables= prev_dups_producing_tables;
|
||||||
//TODO: update bitmap of semi-joins that were handled together with
|
join->sjm_lookup_tables= prev_sjm_lookup_tables;
|
||||||
// others.
|
// mark it 'none' to avpoid loops
|
||||||
if (is_multiple_semi_joins(join, join->positions, idx, handled_fanout))
|
pos->sj_strategy= SJ_OPT_NONE;
|
||||||
pos->inner_tables_handled_with_other_sjs |= handled_fanout;
|
// next skip to last;
|
||||||
|
strategy= pickers +
|
||||||
|
(sizeof(pickers)/sizeof(Semi_join_strategy_picker*) - 3);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
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
|
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
|
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 */
|
frames in the buffer pool, we set this to TRUE */
|
||||||
static bool buf_lru_switched_on_innodb_mon = false;
|
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
|
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
|
||||||
and page_zip_decompress() operations. Based on the statistics,
|
and page_zip_decompress() operations. Based on the statistics,
|
||||||
@ -1079,8 +1083,6 @@ buf_LRU_get_free_block(
|
|||||||
bool freed = false;
|
bool freed = false;
|
||||||
ulint n_iterations = 0;
|
ulint n_iterations = 0;
|
||||||
ulint flush_failures = 0;
|
ulint flush_failures = 0;
|
||||||
bool mon_value_was = false;
|
|
||||||
bool started_monitor = false;
|
|
||||||
|
|
||||||
MONITOR_INC(MONITOR_LRU_GET_FREE_SEARCH);
|
MONITOR_INC(MONITOR_LRU_GET_FREE_SEARCH);
|
||||||
loop:
|
loop:
|
||||||
@ -1088,6 +1090,11 @@ loop:
|
|||||||
|
|
||||||
buf_LRU_check_size_of_non_data_objects(buf_pool);
|
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 */
|
/* If there is a block in the free list, take it */
|
||||||
block = buf_LRU_get_free_only(buf_pool);
|
block = buf_LRU_get_free_only(buf_pool);
|
||||||
|
|
||||||
@ -1097,11 +1104,6 @@ loop:
|
|||||||
ut_ad(buf_pool_from_block(block) == buf_pool);
|
ut_ad(buf_pool_from_block(block) == buf_pool);
|
||||||
memset(&block->page.zip, 0, sizeof block->page.zip);
|
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->skip_flush_check = false;
|
||||||
block->page.flush_observer = NULL;
|
block->page.flush_observer = NULL;
|
||||||
return(block);
|
return(block);
|
||||||
@ -1131,24 +1133,24 @@ loop:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
not_found:
|
||||||
|
#endif
|
||||||
|
|
||||||
buf_pool_mutex_exit(buf_pool);
|
buf_pool_mutex_exit(buf_pool);
|
||||||
|
|
||||||
if (freed) {
|
if (freed) {
|
||||||
goto loop;
|
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) {
|
&& srv_buf_pool_old_size == srv_buf_pool_size) {
|
||||||
|
|
||||||
ib::warn() << "Difficult to find free blocks in the buffer pool"
|
ib::warn() << "Difficult to find free blocks in the buffer pool"
|
||||||
" (" << n_iterations << " search iterations)! "
|
" (" << n_iterations << " search iterations)! "
|
||||||
<< flush_failures << " failed attempts to"
|
<< flush_failures << " failed attempts to"
|
||||||
" flush a page! Consider increasing the buffer pool"
|
" flush a page!"
|
||||||
" size. It is also possible that in your Unix version"
|
" Consider increasing innodb_buffer_pool_size."
|
||||||
" 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."
|
|
||||||
" Pending flushes (fsync) log: "
|
" Pending flushes (fsync) log: "
|
||||||
<< fil_n_pending_log_flushes
|
<< fil_n_pending_log_flushes
|
||||||
<< "; buffer pool: "
|
<< "; buffer pool: "
|
||||||
@ -1156,13 +1158,9 @@ loop:
|
|||||||
<< ". " << os_n_file_reads << " OS file reads, "
|
<< ". " << os_n_file_reads << " OS file reads, "
|
||||||
<< os_n_file_writes << " OS file writes, "
|
<< os_n_file_writes << " OS file writes, "
|
||||||
<< os_n_fsyncs
|
<< os_n_fsyncs
|
||||||
<< " OS fsyncs. Starting InnoDB Monitor to print"
|
<< " OS fsyncs.";
|
||||||
" further diagnostics to the standard output.";
|
|
||||||
|
|
||||||
mon_value_was = srv_print_innodb_monitor;
|
buf_lru_free_blocks_error_printed = true;
|
||||||
started_monitor = true;
|
|
||||||
srv_print_innodb_monitor = true;
|
|
||||||
os_event_set(srv_monitor_event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have scanned the whole LRU and still are unable to
|
/* If we have scanned the whole LRU and still are unable to
|
||||||
|
@ -1162,28 +1162,6 @@ trx_purge_rseg_get_next_history_log(
|
|||||||
|
|
||||||
mutex_exit(&(rseg->mutex));
|
mutex_exit(&(rseg->mutex));
|
||||||
mtr_commit(&mtr);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
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
|
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
|
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 */
|
frames in the buffer pool, we set this to TRUE */
|
||||||
static ibool buf_lru_switched_on_innodb_mon = FALSE;
|
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
|
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
|
||||||
and page_zip_decompress() operations. Based on the statistics,
|
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
|
/** 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
|
@param[in] n_iterations how many buf_LRU_get_free_page iterations
|
||||||
already completed
|
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,
|
@param[in] flush_failures how many times single-page flush, if allowed,
|
||||||
has failed
|
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
|
static
|
||||||
void
|
void
|
||||||
buf_LRU_handle_lack_of_free_blocks(ulint n_iterations, ulint started_ms,
|
buf_LRU_handle_lack_of_free_blocks(
|
||||||
ulint flush_failures,
|
ulint n_iterations,
|
||||||
ibool *mon_value_was,
|
ulint flush_failures)
|
||||||
ibool *started_monitor)
|
|
||||||
{
|
{
|
||||||
static ulint last_printout_ms = 0;
|
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);
|
||||||
|
|
||||||
/* Legacy algorithm started warning after at least 2 seconds, we
|
buf_lru_free_blocks_error_printed = true;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The maximum allowed backoff sleep time duration, microseconds */
|
/** The maximum allowed backoff sleep time duration, microseconds */
|
||||||
@ -1189,9 +1164,6 @@ buf_LRU_get_free_block(
|
|||||||
ibool freed = FALSE;
|
ibool freed = FALSE;
|
||||||
ulint n_iterations = 0;
|
ulint n_iterations = 0;
|
||||||
ulint flush_failures = 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));
|
ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));
|
||||||
|
|
||||||
@ -1199,42 +1171,20 @@ buf_LRU_get_free_block(
|
|||||||
loop:
|
loop:
|
||||||
buf_LRU_check_size_of_non_data_objects(buf_pool);
|
buf_LRU_check_size_of_non_data_objects(buf_pool);
|
||||||
|
|
||||||
/* If there is a block in the free list, take it */
|
DBUG_EXECUTE_IF("ib_lru_force_no_free_page",
|
||||||
if (DBUG_EVALUATE_IF("simulate_lack_of_pages", true, false)) {
|
if (!buf_lru_free_blocks_error_printed) {
|
||||||
|
n_iterations = 21;
|
||||||
|
goto not_found;});
|
||||||
|
|
||||||
block = NULL;
|
block = buf_LRU_get_free_only(buf_pool);
|
||||||
|
|
||||||
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 {
|
|
||||||
|
|
||||||
block = buf_LRU_get_free_only(buf_pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (block) {
|
if (block) {
|
||||||
|
|
||||||
ut_ad(buf_pool_from_block(block) == buf_pool);
|
ut_ad(buf_pool_from_block(block) == buf_pool);
|
||||||
memset(&block->page.zip, 0, sizeof block->page.zip);
|
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);
|
return(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!started_ms)
|
|
||||||
started_ms = ut_time_ms();
|
|
||||||
|
|
||||||
if (srv_empty_free_list_algorithm == SRV_EMPTY_FREE_LIST_BACKOFF
|
if (srv_empty_free_list_algorithm == SRV_EMPTY_FREE_LIST_BACKOFF
|
||||||
&& buf_lru_manager_is_active
|
&& buf_lru_manager_is_active
|
||||||
&& (srv_shutdown_state == SRV_SHUTDOWN_NONE
|
&& (srv_shutdown_state == SRV_SHUTDOWN_NONE
|
||||||
@ -1272,10 +1222,7 @@ loop:
|
|||||||
: FREE_LIST_BACKOFF_LOW_PRIO_DIVIDER));
|
: FREE_LIST_BACKOFF_LOW_PRIO_DIVIDER));
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_LRU_handle_lack_of_free_blocks(n_iterations, started_ms,
|
buf_LRU_handle_lack_of_free_blocks(n_iterations, flush_failures);
|
||||||
flush_failures,
|
|
||||||
&mon_value_was,
|
|
||||||
&started_monitor);
|
|
||||||
|
|
||||||
n_iterations++;
|
n_iterations++;
|
||||||
|
|
||||||
@ -1314,13 +1261,8 @@ loop:
|
|||||||
|
|
||||||
mutex_exit(&buf_pool->flush_state_mutex);
|
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;
|
freed = FALSE;
|
||||||
|
|
||||||
if (buf_pool->try_LRU_scan || n_iterations > 0) {
|
if (buf_pool->try_LRU_scan || n_iterations > 0) {
|
||||||
|
|
||||||
/* If no block was in the free list, search from the
|
/* 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,
|
#ifndef DBUG_OFF
|
||||||
flush_failures, &mon_value_was,
|
not_found:
|
||||||
&started_monitor);
|
#endif
|
||||||
|
|
||||||
|
buf_LRU_handle_lack_of_free_blocks(n_iterations, flush_failures);
|
||||||
|
|
||||||
/* If we have scanned the whole LRU and still are unable to
|
/* If we have scanned the whole LRU and still are unable to
|
||||||
find a free block then we should sleep here to let the
|
find a free block then we should sleep here to let the
|
||||||
|
@ -584,32 +584,6 @@ trx_purge_rseg_get_next_history_log(
|
|||||||
|
|
||||||
mutex_exit(&(rseg->mutex));
|
mutex_exit(&(rseg->mutex));
|
||||||
mtr_commit(&mtr);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user