From eb09580b67ee19f7ac30c1a41c8307b9c7d482d1 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 28 May 2019 14:53:08 -0700 Subject: [PATCH 01/25] MDEV-19588 Wrong results from query, using left join. This bug could happen when queries with nested outer joins were executed employing join buffers. At such an execution if the method JOIN_CACHE::join_records() is called when a join buffer has become full no 'first_unmatched' field should be cleaned up in the JOIN_TAB structure to which the join cache with this buffer is attached. --- mysql-test/r/join_nested.result | 33 +++++++++++++++++++++++++++ mysql-test/r/join_nested_jcl6.result | 33 +++++++++++++++++++++++++++ mysql-test/t/join_nested.test | 34 ++++++++++++++++++++++++++++ sql/sql_join_cache.cc | 3 ++- 4 files changed, 102 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result index 6ddd39cbfec..d618f7c3ac8 100644 --- a/mysql-test/r/join_nested.result +++ b/mysql-test/r/join_nested.result @@ -1966,3 +1966,36 @@ Note 1003 select 1 AS `K1`,'T1Row1' AS `Name`,`t2a`.`K2` AS `K2`,`t2a`.`K1r` AS DROP VIEW v1; DROP TABLE t1,t2; set optimizer_search_depth= @tmp_mdev621; +# +# MDEV-19588: Nested left joins using optimized join cache +# +set optimizer_switch='optimize_join_buffer_size=on'; +set @save_join_cache_level= @@join_cache_level; +set join_cache_level=2; +CREATE TABLE t1 (i1 int, c1 varchar(20), pk int) engine=myisam; +CREATE TABLE t2 (pk int, c1 varchar(20), i1 int) engine=myisam; +INSERT INTO t2 VALUES (7,'a',-912),(8,'a',5); +CREATE TABLE t3 (pk int, c1 varchar(20), i1 int) engine=myisam; +INSERT INTO t3 VALUES +(1,'a',-145),(2,'a',6),(3,'a',1),(7,'a',NULL),(8,'a',889),(9,'a',146), +(10,'a',177),(16,'a',-433),(17,'a',NULL),(18,'a',2),(19,'a',3),(20,'a',5), +(21,'a',-484),(22,'a',369),(23,'a',-192),(24,'a',-163),(25,'a',5),(26,'a',NULL); +SELECT t3.* +FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1 +WHERE t2.pk < 13 OR t3.i1 IS NULL; +pk c1 i1 +7 a NULL +17 a NULL +26 a NULL +explain extended SELECT t3.* +FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1 +WHERE t2.pk < 13 OR t3.i1 IS NULL; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 ALL NULL NULL NULL NULL 18 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 0 0.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t3`.`pk` AS `pk`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`i1` AS `i1` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on((`test`.`t2`.`i1` = `test`.`t3`.`i1`))) on((`test`.`t1`.`i1` = `test`.`t3`.`i1`)) where ((`test`.`t2`.`pk` < 13) or isnull(`test`.`t3`.`i1`)) +DROP TABLE t1,t2,t3; +set join_cache_level= @save_join_cache_level; +set optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/join_nested_jcl6.result b/mysql-test/r/join_nested_jcl6.result index bac8e1cb7db..b99b0200792 100644 --- a/mysql-test/r/join_nested_jcl6.result +++ b/mysql-test/r/join_nested_jcl6.result @@ -1977,6 +1977,39 @@ Note 1003 select 1 AS `K1`,'T1Row1' AS `Name`,`t2a`.`K2` AS `K2`,`t2a`.`K1r` AS DROP VIEW v1; DROP TABLE t1,t2; set optimizer_search_depth= @tmp_mdev621; +# +# MDEV-19588: Nested left joins using optimized join cache +# +set optimizer_switch='optimize_join_buffer_size=on'; +set @save_join_cache_level= @@join_cache_level; +set join_cache_level=2; +CREATE TABLE t1 (i1 int, c1 varchar(20), pk int) engine=myisam; +CREATE TABLE t2 (pk int, c1 varchar(20), i1 int) engine=myisam; +INSERT INTO t2 VALUES (7,'a',-912),(8,'a',5); +CREATE TABLE t3 (pk int, c1 varchar(20), i1 int) engine=myisam; +INSERT INTO t3 VALUES +(1,'a',-145),(2,'a',6),(3,'a',1),(7,'a',NULL),(8,'a',889),(9,'a',146), +(10,'a',177),(16,'a',-433),(17,'a',NULL),(18,'a',2),(19,'a',3),(20,'a',5), +(21,'a',-484),(22,'a',369),(23,'a',-192),(24,'a',-163),(25,'a',5),(26,'a',NULL); +SELECT t3.* +FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1 +WHERE t2.pk < 13 OR t3.i1 IS NULL; +pk c1 i1 +7 a NULL +17 a NULL +26 a NULL +explain extended SELECT t3.* +FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1 +WHERE t2.pk < 13 OR t3.i1 IS NULL; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 ALL NULL NULL NULL NULL 18 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 0 0.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t3`.`pk` AS `pk`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`i1` AS `i1` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on((`test`.`t2`.`i1` = `test`.`t3`.`i1`))) on((`test`.`t1`.`i1` = `test`.`t3`.`i1`)) where ((`test`.`t2`.`pk` < 13) or isnull(`test`.`t3`.`i1`)) +DROP TABLE t1,t2,t3; +set join_cache_level= @save_join_cache_level; +set optimizer_switch=@save_optimizer_switch; CREATE TABLE t5 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b)); CREATE TABLE t6 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b)); CREATE TABLE t7 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b)); diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test index e60b7827f75..cfb24a63304 100644 --- a/mysql-test/t/join_nested.test +++ b/mysql-test/t/join_nested.test @@ -1380,3 +1380,37 @@ DROP VIEW v1; DROP TABLE t1,t2; set optimizer_search_depth= @tmp_mdev621; + +--echo # +--echo # MDEV-19588: Nested left joins using optimized join cache +--echo # + +set optimizer_switch='optimize_join_buffer_size=on'; + +set @save_join_cache_level= @@join_cache_level; +set join_cache_level=2; + +CREATE TABLE t1 (i1 int, c1 varchar(20), pk int) engine=myisam; + +CREATE TABLE t2 (pk int, c1 varchar(20), i1 int) engine=myisam; +INSERT INTO t2 VALUES (7,'a',-912),(8,'a',5); + +CREATE TABLE t3 (pk int, c1 varchar(20), i1 int) engine=myisam; +INSERT INTO t3 VALUES +(1,'a',-145),(2,'a',6),(3,'a',1),(7,'a',NULL),(8,'a',889),(9,'a',146), +(10,'a',177),(16,'a',-433),(17,'a',NULL),(18,'a',2),(19,'a',3),(20,'a',5), +(21,'a',-484),(22,'a',369),(23,'a',-192),(24,'a',-163),(25,'a',5),(26,'a',NULL); + +let $q= +SELECT t3.* +FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1 +WHERE t2.pk < 13 OR t3.i1 IS NULL; + +eval $q; +eval explain extended $q; + +DROP TABLE t1,t2,t3; + +set join_cache_level= @save_join_cache_level; + +set optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 73ee2013811..909eeb84971 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -2150,7 +2150,8 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last) } finish: - if (outer_join_first_inner) + if (outer_join_first_inner && + join_tab->first_inner == join_tab->first_unmatched) { /* All null complemented rows have been already generated for all From cbb90f77cdbf57c02145dc6cd86acf8ebb8a88f0 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 28 May 2019 23:26:36 -0700 Subject: [PATCH 02/25] MDEV-18479 Complement This patch complements the patch that fixes bug MDEV-18479. This patch takes care of possible overflow when calculating the estimated number of rows in a materialized derived table / view. --- include/my_base.h | 1 + mysql-test/r/derived_view.result | 20 ++++++++++---------- mysql-test/t/derived_view.test | 2 +- sql/sql_lex.cc | 5 ++++- sql/sql_select.cc | 21 +++++++++++++-------- 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index 54e8443d86c..86be94399d6 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -586,6 +586,7 @@ typedef ulong ha_rows; #define HA_POS_ERROR (~ (ha_rows) 0) #define HA_OFFSET_ERROR (~ (my_off_t) 0) +#define HA_ROWS_MAX HA_POS_ERROR #if SYSTEM_SIZEOF_OFF_T == 4 #define MAX_FILE_SIZE INT_MAX32 diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index ab363934e8f..d74b532d5e8 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -2641,7 +2641,7 @@ DROP TABLE t1, t2; set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; # -# Bug mdev-12812: EXPLAIN for query with many expensive derived +# Bug mdev-18479: EXPLAIN for query with many expensive derived # CREATE TABLE t1 (id int auto_increment primary key, @@ -2942,15 +2942,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE ALL NULL NULL NULL NULL 50328437500000 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE ALL NULL NULL NULL NULL 27680640625000000 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL 7798774269472204288 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL 7798774269472204288 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) 17 DERIVED t2 system NULL NULL NULL NULL 1 17 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where 17 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test index f6613e2593a..61c4278b43f 100644 --- a/mysql-test/t/derived_view.test +++ b/mysql-test/t/derived_view.test @@ -1936,7 +1936,7 @@ set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; --echo # ---echo # Bug mdev-12812: EXPLAIN for query with many expensive derived +--echo # Bug mdev-18479: EXPLAIN for query with many expensive derived --echo # CREATE TABLE t1 diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 3e20cdb48da..28f56282bad 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -4100,7 +4100,10 @@ void SELECT_LEX::increase_derived_records(ha_rows records) DBUG_ASSERT(unit->derived); select_union *result= (select_union*)unit->result; - result->records+= records; + if (HA_ROWS_MAX - records > result->records) + result->records+= records; + else + result->records= HA_ROWS_MAX; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 961a7dac265..37f8292b563 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3830,7 +3830,7 @@ make_join_statistics(JOIN *join, List &tables_list, DBUG_RETURN(TRUE); /* purecov: inspected */ { - ha_rows records= 1; + double records= 1; SELECT_LEX_UNIT *unit= join->select_lex->master_unit(); /* Find an optimal join order of the non-constant tables. */ @@ -3855,10 +3855,14 @@ make_join_statistics(JOIN *join, List &tables_list, table/view. */ for (i= 0; i < join->table_count ; i++) - records*= join->best_positions[i].records_read ? - (ha_rows)join->best_positions[i].records_read : 1; - set_if_smaller(records, unit->select_limit_cnt); - join->select_lex->increase_derived_records(records); + { + records= COST_MULT(records, + join->best_positions[i].records_read ? + join->best_positions[i].records_read : 1); + } + ha_rows rows= records > HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records; + set_if_smaller(rows, unit->select_limit_cnt); + join->select_lex->increase_derived_records(rows); } } @@ -10795,7 +10799,7 @@ ha_rows JOIN_TAB::get_examined_rows() } } else - examined_rows= (ha_rows) records_read; + examined_rows= (ha_rows) records_read; return examined_rows; } @@ -22924,8 +22928,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, else { ha_rows examined_rows= tab->get_examined_rows(); - - item_list.push_back(new Item_int((longlong) (ulonglong) examined_rows, + ha_rows displ_rows= examined_rows; + set_if_smaller(displ_rows, HA_ROWS_MAX/2); + item_list.push_back(new Item_int((longlong) (ulonglong) displ_rows, MY_INT64_NUM_DECIMAL_DIGITS)); /* Add "filtered" field to item_list. */ From b347396181018cedc946450cb49891f1a0aa4575 Mon Sep 17 00:00:00 2001 From: Sujatha Date: Tue, 28 May 2019 14:20:39 +0530 Subject: [PATCH 03/25] MDEV-11094: Blackhole table updates on slave fail when row annotation is enabled Problem: ======= rpl_blackhole.test fails when executed with following options mysqld=--binlog_annotate_row_events=1, mysqld=--replicate_annotate_row_events=1 Test output: ------------ worker[1] Using MTR_BUILD_THREAD 300, with reserved ports 16000..16019 rpl.rpl_blackhole_bug 'mix' [ pass ] 791 rpl.rpl_blackhole_bug 'row' [ fail ] Replicate_Wild_Ignore_Table Last_Errno 1032 Last_Error Could not execute Update_rows_v1 event on table test.t1; Can't find record in 't1', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log master-bin.000001, end_log_pos 1510 Analysis: ========= Enabling "replicate_annotate_row_events" on slave, Tells the slave to write annotate rows events received from the master to its own binary log. The received annotate events are applied after the Gtid event as shown below. thd->query() will be set to the actual query received from the master, through annotate event. Annotate_rows event should not be deleted after the event is applied as the thd->query will be used to generate new Annotate_rows event during applying the subsequent Rows events. After the last Rows event has been applied, the saved Annotate_rows event (if any) will be deleted. In balckhole engine all the DML operations are noops as they donot store any data. They simply return success without doing any operation. But the existing strictly expects thd->query() to be 'NULL' to identify that row based replication is in use. This assumption will fail when row annotations are enabled as the query is not 'NULL'. Hence various row based operations like 'update', 'delete', 'index lookup' will fail when row annotations are enabled. Fix: === Extend the row based replication check to include row annotations as well. i.e Either the thd->query() is NULL or thd->query() points to query and row annotations are in use. --- mysql-test/extra/rpl_tests/rpl_blackhole.test | 2 +- .../extra/rpl_tests/rpl_blackhole_basic.test | 97 ++++ .../rpl/r/rpl_blackhole_row_annotate.result | 434 ++++++++++++++++++ mysql-test/suite/rpl/t/rpl_blackhole.test | 77 +--- .../t/rpl_blackhole_row_annotate-master.opt | 1 + .../t/rpl_blackhole_row_annotate-slave.opt | 1 + .../rpl/t/rpl_blackhole_row_annotate.test | 49 ++ storage/blackhole/ha_blackhole.cc | 28 +- 8 files changed, 606 insertions(+), 83 deletions(-) create mode 100644 mysql-test/extra/rpl_tests/rpl_blackhole_basic.test create mode 100644 mysql-test/suite/rpl/r/rpl_blackhole_row_annotate.result create mode 100644 mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_blackhole_row_annotate.test diff --git a/mysql-test/extra/rpl_tests/rpl_blackhole.test b/mysql-test/extra/rpl_tests/rpl_blackhole.test index 1a0eeb3cf15..569a24e5252 100644 --- a/mysql-test/extra/rpl_tests/rpl_blackhole.test +++ b/mysql-test/extra/rpl_tests/rpl_blackhole.test @@ -11,7 +11,7 @@ # executing statement. If difference is >0, then something was # written to the binary log on the slave. -connection slave; +# On Connection Slave let $before = query_get_value("SHOW MASTER STATUS", Position, 1); --echo [on master] diff --git a/mysql-test/extra/rpl_tests/rpl_blackhole_basic.test b/mysql-test/extra/rpl_tests/rpl_blackhole_basic.test new file mode 100644 index 00000000000..f3fdc915080 --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_blackhole_basic.test @@ -0,0 +1,97 @@ +# PURPOSE. Test that blackhole works with replication in all three +# modes: STATEMENT, MIXED, and ROW. +# +# METHOD. We start by creating a table on the master and then change +# the engine to use blackhole on the slave. +# +# After insert/update/delete of one or more rows, the test the +# proceeds to check that replication is running after replicating an +# change, that the blackhole engine does not contain anything (which +# is just a check that the correct engine is used), and that something +# is written to the binary log. +# +# Whe check INSERT, UPDATE, and DELETE statement for tables with no +# key (forcing a range search on the slave), primary keys (using a +# primary key lookup), and index/key with multiple matches (forcing an +# index search). + +# We start with no primary key +CREATE TABLE t1 (a INT, b INT, c INT); +CREATE TABLE t2 (a INT, b INT, c INT); + +sync_slave_with_master; +ALTER TABLE t1 ENGINE=BLACKHOLE; + +connection master; +INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4); +sync_slave_with_master; + +# Test insert, no primary key +let $statement = INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4); +source extra/rpl_tests/rpl_blackhole.test; + +# Test update, no primary key +let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1; +source extra/rpl_tests/rpl_blackhole.test; + +# Test delete, no primary key +let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 1; +source extra/rpl_tests/rpl_blackhole.test; + +# Test INSERT-SELECT into Blackhole, no primary key +let $statement = INSERT INTO t1 SELECT * FROM t2; +source extra/rpl_tests/rpl_blackhole.test; + +# +# The MASTER has MyISAM as the engine for both tables. The SLAVE has Blackhole +# on t1 (transactional engine) and MyISAM on t2 (non-transactional engine). +# +# In MIXED mode, the command "INSERT INTO t2 SELECT * FROM t1" is logged as +# statement on the master. On the slave, it is tagged as unsafe because the +# statement mixes both transactional and non-transactional engines and as such +# its changes are logged as rows. However, due to the nature of the blackhole +# engine, no rows are returned and thus any chain replication would make the +# next master on the chain diverge. +# +# Fo this reason, we have disabled the statement. +# +# Test INSERT-SELECT from Blackhole, no primary key +# let $statement = INSERT INTO t2 SELECT * FROM t1; +# source extra/rpl_tests/rpl_blackhole.test; +# + +connection master; +ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a,b); +sync_slave_with_master; + +# Test insert, primary key +let $statement = INSERT INTO t1 VALUES (1,2,1),(2,2,2),(3,2,3),(4,2,4); +source extra/rpl_tests/rpl_blackhole.test; + +# Test update, primary key +let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2; +source extra/rpl_tests/rpl_blackhole.test; + +# Test delete, primary key +let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 2; +source extra/rpl_tests/rpl_blackhole.test; + +connection master; +ALTER TABLE t1 DROP PRIMARY KEY, ADD KEY key_t1 (a); +sync_slave_with_master; + +# Test insert, key +let $statement = INSERT INTO t1 VALUES (1,3,1),(2,3,2),(3,3,3),(4,3,4); +source extra/rpl_tests/rpl_blackhole.test; + +# Test update, key +let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3; +source extra/rpl_tests/rpl_blackhole.test; + +# Test delete, key +let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 3; +source extra/rpl_tests/rpl_blackhole.test; + +connection master; +DROP TABLE t1,t2; +sync_slave_with_master; diff --git a/mysql-test/suite/rpl/r/rpl_blackhole_row_annotate.result b/mysql-test/suite/rpl/r/rpl_blackhole_row_annotate.result new file mode 100644 index 00000000000..20ca37322dc --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_blackhole_row_annotate.result @@ -0,0 +1,434 @@ +include/master-slave.inc +[connection master] +SET timestamp=1000000000; +RESET MASTER; +SET timestamp=1000000000; +RESET MASTER; +CREATE TABLE t1 (a INT, b INT, c INT); +CREATE TABLE t2 (a INT, b INT, c INT); +ALTER TABLE t1 ENGINE=BLACKHOLE; +INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4); +[on master] +INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4); +[on slave] +# Expect 0 +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +>>> Something was written to binary log <<< +[on master] +UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1; +[on slave] +# Expect 0 +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +>>> Something was written to binary log <<< +[on master] +DELETE FROM t1 WHERE a % 2 = 0 AND b = 1; +[on slave] +# Expect 0 +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +>>> Something was written to binary log <<< +[on master] +INSERT INTO t1 SELECT * FROM t2; +[on slave] +# Expect 0 +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +>>> Something was written to binary log <<< +ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a,b); +[on master] +INSERT INTO t1 VALUES (1,2,1),(2,2,2),(3,2,3),(4,2,4); +[on slave] +# Expect 0 +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +>>> Something was written to binary log <<< +[on master] +UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2; +[on slave] +# Expect 0 +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +>>> Something was written to binary log <<< +[on master] +DELETE FROM t1 WHERE a % 2 = 0 AND b = 2; +[on slave] +# Expect 0 +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +>>> Something was written to binary log <<< +ALTER TABLE t1 DROP PRIMARY KEY, ADD KEY key_t1 (a); +[on master] +INSERT INTO t1 VALUES (1,3,1),(2,3,2),(3,3,3),(4,3,4); +[on slave] +# Expect 0 +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +>>> Something was written to binary log <<< +[on master] +UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3; +[on slave] +# Expect 0 +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +>>> Something was written to binary log <<< +[on master] +DELETE FROM t1 WHERE a % 2 = 0 AND b = 3; +[on slave] +# Expect 0 +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +>>> Something was written to binary log <<< +DROP TABLE t1,t2; +FLUSH LOGS; +show binlog events in 'slave-bin.000001' from ; +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid_list 2 # [] +slave-bin.000001 # Binlog_checkpoint 2 # slave-bin.000001 +slave-bin.000001 # Gtid 1 # GTID 0-1-1 +slave-bin.000001 # Query 1 # use `test`; CREATE TABLE t1 (a INT, b INT, c INT) +slave-bin.000001 # Gtid 1 # GTID 0-1-2 +slave-bin.000001 # Query 1 # use `test`; CREATE TABLE t2 (a INT, b INT, c INT) +slave-bin.000001 # Gtid 2 # GTID 0-2-3 +slave-bin.000001 # Query 2 # use `test`; ALTER TABLE t1 ENGINE=BLACKHOLE +slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-3 +slave-bin.000001 # Annotate_rows 1 # INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4) +slave-bin.000001 # Table_map 1 # table_id: # (test.t2) +slave-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F +slave-bin.000001 # Query 1 # COMMIT +slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-4 +slave-bin.000001 # Annotate_rows 1 # INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4) +slave-bin.000001 # Table_map 1 # table_id: # (test.t1) +slave-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F +slave-bin.000001 # Query 1 # COMMIT +slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-5 +slave-bin.000001 # Annotate_rows 1 # UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1 +slave-bin.000001 # Table_map 1 # table_id: # (test.t1) +slave-bin.000001 # Update_rows_v1 1 # table_id: # flags: STMT_END_F +slave-bin.000001 # Query 1 # COMMIT +slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-6 +slave-bin.000001 # Annotate_rows 1 # DELETE FROM t1 WHERE a % 2 = 0 AND b = 1 +slave-bin.000001 # Table_map 1 # table_id: # (test.t1) +slave-bin.000001 # Delete_rows_v1 1 # table_id: # flags: STMT_END_F +slave-bin.000001 # Query 1 # COMMIT +slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-7 +slave-bin.000001 # Annotate_rows 1 # INSERT INTO t1 SELECT * FROM t2 +slave-bin.000001 # Table_map 1 # table_id: # (test.t1) +slave-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F +slave-bin.000001 # Query 1 # COMMIT +slave-bin.000001 # Gtid 1 # GTID 0-1-8 +slave-bin.000001 # Query 1 # use `test`; ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a,b) +slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-9 +slave-bin.000001 # Annotate_rows 1 # INSERT INTO t1 VALUES (1,2,1),(2,2,2),(3,2,3),(4,2,4) +slave-bin.000001 # Table_map 1 # table_id: # (test.t1) +slave-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F +slave-bin.000001 # Query 1 # COMMIT +slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-10 +slave-bin.000001 # Annotate_rows 1 # UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2 +slave-bin.000001 # Table_map 1 # table_id: # (test.t1) +slave-bin.000001 # Update_rows_v1 1 # table_id: # flags: STMT_END_F +slave-bin.000001 # Query 1 # COMMIT +slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-11 +slave-bin.000001 # Annotate_rows 1 # DELETE FROM t1 WHERE a % 2 = 0 AND b = 2 +slave-bin.000001 # Table_map 1 # table_id: # (test.t1) +slave-bin.000001 # Delete_rows_v1 1 # table_id: # flags: STMT_END_F +slave-bin.000001 # Query 1 # COMMIT +slave-bin.000001 # Gtid 1 # GTID 0-1-12 +slave-bin.000001 # Query 1 # use `test`; ALTER TABLE t1 DROP PRIMARY KEY, ADD KEY key_t1 (a) +slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-13 +slave-bin.000001 # Annotate_rows 1 # INSERT INTO t1 VALUES (1,3,1),(2,3,2),(3,3,3),(4,3,4) +slave-bin.000001 # Table_map 1 # table_id: # (test.t1) +slave-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F +slave-bin.000001 # Query 1 # COMMIT +slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-14 +slave-bin.000001 # Annotate_rows 1 # UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3 +slave-bin.000001 # Table_map 1 # table_id: # (test.t1) +slave-bin.000001 # Update_rows_v1 1 # table_id: # flags: STMT_END_F +slave-bin.000001 # Query 1 # COMMIT +slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-15 +slave-bin.000001 # Annotate_rows 1 # DELETE FROM t1 WHERE a % 2 = 0 AND b = 3 +slave-bin.000001 # Table_map 1 # table_id: # (test.t1) +slave-bin.000001 # Delete_rows_v1 1 # table_id: # flags: STMT_END_F +slave-bin.000001 # Query 1 # COMMIT +slave-bin.000001 # Gtid 1 # GTID 0-1-16 +slave-bin.000001 # Query 1 # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by server */ +slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4 +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup +ROLLBACK/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Gtid list [] +# at # +#010909 4:46:40 server id # end_log_pos # Binlog checkpoint slave-bin.000001 +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-1 ddl +/*!100101 SET @@session.skip_parallel_replication=0*//*!*/; +/*!100001 SET @@session.gtid_domain_id=0*//*!*/; +/*!100001 SET @@session.server_id=1*//*!*/; +/*!100001 SET @@session.gtid_seq_no=1*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +use `test`/*!*/; +SET TIMESTAMP=1000000000/*!*/; +SET @@session.pseudo_thread_id=#/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.sql_mode=1342177280/*!*/; +SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +SET @@session.lc_time_names=0/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +CREATE TABLE t1 (a INT, b INT, c INT) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-2 ddl +/*!100001 SET @@session.gtid_seq_no=2*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +CREATE TABLE t2 (a INT, b INT, c INT) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-2-3 ddl +/*!100001 SET @@session.server_id=2*//*!*/; +/*!100001 SET @@session.gtid_seq_no=3*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +ALTER TABLE t1 ENGINE=BLACKHOLE +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-3 trans +/*!100001 SET @@session.server_id=1*//*!*/; +/*!100001 SET @@session.gtid_seq_no=3*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4) +#010909 4:46:40 server id # end_log_pos # Table_map: `test`.`t2` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-4 trans +/*!100001 SET @@session.gtid_seq_no=4*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4) +#010909 4:46:40 server id # end_log_pos # Table_map: `test`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-5 trans +/*!100001 SET @@session.gtid_seq_no=5*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1 +#010909 4:46:40 server id # end_log_pos # Table_map: `test`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Update_rows: table id # flags: STMT_END_F +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-6 trans +/*!100001 SET @@session.gtid_seq_no=6*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> DELETE FROM t1 WHERE a % 2 = 0 AND b = 1 +#010909 4:46:40 server id # end_log_pos # Table_map: `test`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-7 trans +/*!100001 SET @@session.gtid_seq_no=7*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> INSERT INTO t1 SELECT * FROM t2 +#010909 4:46:40 server id # end_log_pos # Table_map: `test`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-8 ddl +/*!100001 SET @@session.gtid_seq_no=8*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a,b) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-9 trans +/*!100001 SET @@session.gtid_seq_no=9*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> INSERT INTO t1 VALUES (1,2,1),(2,2,2),(3,2,3),(4,2,4) +#010909 4:46:40 server id # end_log_pos # Table_map: `test`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-10 trans +/*!100001 SET @@session.gtid_seq_no=10*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2 +#010909 4:46:40 server id # end_log_pos # Table_map: `test`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Update_rows: table id # flags: STMT_END_F +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-11 trans +/*!100001 SET @@session.gtid_seq_no=11*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> DELETE FROM t1 WHERE a % 2 = 0 AND b = 2 +#010909 4:46:40 server id # end_log_pos # Table_map: `test`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-12 ddl +/*!100001 SET @@session.gtid_seq_no=12*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +ALTER TABLE t1 DROP PRIMARY KEY, ADD KEY key_t1 (a) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-13 trans +/*!100001 SET @@session.gtid_seq_no=13*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> INSERT INTO t1 VALUES (1,3,1),(2,3,2),(3,3,3),(4,3,4) +#010909 4:46:40 server id # end_log_pos # Table_map: `test`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-14 trans +/*!100001 SET @@session.gtid_seq_no=14*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3 +#010909 4:46:40 server id # end_log_pos # Table_map: `test`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Update_rows: table id # flags: STMT_END_F +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-15 trans +/*!100001 SET @@session.gtid_seq_no=15*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> DELETE FROM t1 WHERE a % 2 = 0 AND b = 3 +#010909 4:46:40 server id # end_log_pos # Table_map: `test`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-16 ddl +/*!100001 SET @@session.gtid_seq_no=16*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +DROP TABLE IF EXISTS `t1`,`t2` /* generated by server */ +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Rotate to slave-bin.000002 pos: 4 +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_blackhole.test b/mysql-test/suite/rpl/t/rpl_blackhole.test index 76b2e2421c9..9128382d12b 100644 --- a/mysql-test/suite/rpl/t/rpl_blackhole.test +++ b/mysql-test/suite/rpl/t/rpl_blackhole.test @@ -20,81 +20,6 @@ source include/master-slave.inc; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); -# We start with no primary key -CREATE TABLE t1 (a INT, b INT, c INT); -CREATE TABLE t2 (a INT, b INT, c INT); +source extra/rpl_tests/rpl_blackhole_basic.test; -sync_slave_with_master; -ALTER TABLE t1 ENGINE=BLACKHOLE; - -connection master; -INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4); -sync_slave_with_master; - -# Test insert, no primary key -let $statement = INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4); -source extra/rpl_tests/rpl_blackhole.test; - -# Test update, no primary key -let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1; -source extra/rpl_tests/rpl_blackhole.test; - -# Test delete, no primary key -let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 1; -source extra/rpl_tests/rpl_blackhole.test; - -# Test INSERT-SELECT into Blackhole, no primary key -let $statement = INSERT INTO t1 SELECT * FROM t2; -source extra/rpl_tests/rpl_blackhole.test; - -# -# The MASTER has MyISAM as the engine for both tables. The SLAVE has Blackhole -# on t1 (transactional engine) and MyISAM on t2 (non-transactional engine). -# -# In MIXED mode, the command "INSERT INTO t2 SELECT * FROM t1" is logged as -# statement on the master. On the slave, it is tagged as unsafe because the -# statement mixes both transactional and non-transactional engines and as such -# its changes are logged as rows. However, due to the nature of the blackhole -# engine, no rows are returned and thus any chain replication would make the -# next master on the chain diverge. -# -# Fo this reason, we have disabled the statement. -# -# Test INSERT-SELECT from Blackhole, no primary key -# let $statement = INSERT INTO t2 SELECT * FROM t1; -# source extra/rpl_tests/rpl_blackhole.test; -# - -connection master; -ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a,b); - -# Test insert, primary key -let $statement = INSERT INTO t1 VALUES (1,2,1),(2,2,2),(3,2,3),(4,2,4); -source extra/rpl_tests/rpl_blackhole.test; - -# Test update, primary key -let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2; -source extra/rpl_tests/rpl_blackhole.test; - -# Test delete, primary key -let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 2; -source extra/rpl_tests/rpl_blackhole.test; - -connection master; -ALTER TABLE t1 DROP PRIMARY KEY, ADD KEY key_t1 (a); - -# Test insert, key -let $statement = INSERT INTO t1 VALUES (1,3,1),(2,3,2),(3,3,3),(4,3,4); -source extra/rpl_tests/rpl_blackhole.test; - -# Test update, key -let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3; -source extra/rpl_tests/rpl_blackhole.test; - -# Test delete, key -let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 3; -source extra/rpl_tests/rpl_blackhole.test; - -connection master; -DROP TABLE t1,t2; --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-master.opt b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-master.opt new file mode 100644 index 00000000000..91302791099 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-master.opt @@ -0,0 +1 @@ +--binlog_annotate_row_events --timezone=GMT-3 diff --git a/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-slave.opt b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-slave.opt new file mode 100644 index 00000000000..7ac6a84faa7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-slave.opt @@ -0,0 +1 @@ +--binlog_annotate_row_events --replicate_annotate_row_events diff --git a/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate.test b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate.test new file mode 100644 index 00000000000..77384d91475 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate.test @@ -0,0 +1,49 @@ +# ==== Purpose ==== +# +# Test verifies that when "replicate_annotate_row_events" are enabled on slave +# the DML operations on blackhole engine will be successful. It also ensures +# that Annotate events are logged into slave's binary log. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Enable "replicate_annotate_row_events" on slave and do DML operations +# on master. +# 1 - Slave server will successfully apply the DML operations and it is in +# sync with master. +# 2 - Verify that the "show binlog events" prints all annotate events. +# 3 - Stream the slave's binary log using "mysqlbinlog" tool and verify +# that the Annotate events are being displayed. +# +# ==== References ==== +# +# MDEV-11094: Blackhole table updates on slave fail when row annotation is +# enabled + +source include/have_blackhole.inc; +source include/have_binlog_format_row.inc; +source include/binlog_start_pos.inc; +source include/master-slave.inc; + +SET timestamp=1000000000; +RESET MASTER; +connection slave; +SET timestamp=1000000000; +RESET MASTER; + +connection master; +source extra/rpl_tests/rpl_blackhole_basic.test; + +# Verify on slave. +connection slave; +FLUSH LOGS; +--replace_column 2 # 5 # +--replace_result $binlog_start_pos +--replace_regex /table_id: [0-9]+/table_id: #/ /\/\* xid=.* \*\//\/* xid= *\// +--eval show binlog events in 'slave-bin.000001' from $binlog_start_pos + +let $MYSQLD_DATADIR= `select @@datadir`; +--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ +--exec $MYSQL_BINLOG --base64-output=decode-rows $MYSQLD_DATADIR/slave-bin.000001 + +source include/rpl_end.inc; diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index 01aaa9ea15f..43bcdc541a1 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -25,6 +25,16 @@ #include "ha_blackhole.h" #include "sql_class.h" // THD, SYSTEM_THREAD_SLAVE_SQL +static bool is_row_based_replication(THD *thd) +{ + /* + A row event which has its thd->query() == NULL or a row event which has + replicate_annotate_row_events enabled. In the later case the thd->query() + will be pointing to the query, received through replicated annotate event + from master. + */ + return ((thd->query() == NULL) || thd->variables.binlog_annotate_row_events); +} /* Static declarations for handlerton */ static handler *blackhole_create_handler(handlerton *hton, @@ -109,7 +119,8 @@ int ha_blackhole::update_row(const uchar *old_data, uchar *new_data) { DBUG_ENTER("ha_blackhole::update_row"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && + is_row_based_replication(thd)) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -118,7 +129,8 @@ int ha_blackhole::delete_row(const uchar *buf) { DBUG_ENTER("ha_blackhole::delete_row"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && + is_row_based_replication(thd)) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -135,7 +147,8 @@ int ha_blackhole::rnd_next(uchar *buf) int rc; DBUG_ENTER("ha_blackhole::rnd_next"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && + is_row_based_replication(thd)) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -220,7 +233,8 @@ int ha_blackhole::index_read_map(uchar * buf, const uchar * key, int rc; DBUG_ENTER("ha_blackhole::index_read"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && + is_row_based_replication(thd)) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -235,7 +249,8 @@ int ha_blackhole::index_read_idx_map(uchar * buf, uint idx, const uchar * key, int rc; DBUG_ENTER("ha_blackhole::index_read_idx"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && + is_row_based_replication(thd)) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -249,7 +264,8 @@ int ha_blackhole::index_read_last_map(uchar * buf, const uchar * key, int rc; DBUG_ENTER("ha_blackhole::index_read_last"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && + is_row_based_replication(thd)) rc= 0; else rc= HA_ERR_END_OF_FILE; From a47464d1c12d773364e78f50090b08484fe76129 Mon Sep 17 00:00:00 2001 From: Sujatha Date: Wed, 29 May 2019 17:35:29 +0530 Subject: [PATCH 04/25] MDEV-11094: Blackhole table updates on slave fail when row annotation is enabled Post push fix. Simplified the earlier fixes. --- storage/blackhole/ha_blackhole.cc | 40 ++++++++++++++++--------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index 43bcdc541a1..69182676c1e 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -25,15 +25,23 @@ #include "ha_blackhole.h" #include "sql_class.h" // THD, SYSTEM_THREAD_SLAVE_SQL +/** + Checks if the param 'thd' is pointing to slave applier thread and row based + replication is in use. + + A row event will have its thd->query() == NULL except in cases where + replicate_annotate_row_events is enabled. In the later case the thd->query() + will be pointing to the query, received through replicated annotate event + from master. + + @param thd pointer to a THD instance + + @return TRUE if thread is slave applier and row based replication is in use +*/ static bool is_row_based_replication(THD *thd) { - /* - A row event which has its thd->query() == NULL or a row event which has - replicate_annotate_row_events enabled. In the later case the thd->query() - will be pointing to the query, received through replicated annotate event - from master. - */ - return ((thd->query() == NULL) || thd->variables.binlog_annotate_row_events); + return thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && + (thd->query() == NULL || thd->variables.binlog_annotate_row_events); } /* Static declarations for handlerton */ @@ -119,8 +127,7 @@ int ha_blackhole::update_row(const uchar *old_data, uchar *new_data) { DBUG_ENTER("ha_blackhole::update_row"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && - is_row_based_replication(thd)) + if (is_row_based_replication(thd)) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -129,8 +136,7 @@ int ha_blackhole::delete_row(const uchar *buf) { DBUG_ENTER("ha_blackhole::delete_row"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && - is_row_based_replication(thd)) + if (is_row_based_replication(thd)) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -147,8 +153,7 @@ int ha_blackhole::rnd_next(uchar *buf) int rc; DBUG_ENTER("ha_blackhole::rnd_next"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && - is_row_based_replication(thd)) + if (is_row_based_replication(thd)) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -233,8 +238,7 @@ int ha_blackhole::index_read_map(uchar * buf, const uchar * key, int rc; DBUG_ENTER("ha_blackhole::index_read"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && - is_row_based_replication(thd)) + if (is_row_based_replication(thd)) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -249,8 +253,7 @@ int ha_blackhole::index_read_idx_map(uchar * buf, uint idx, const uchar * key, int rc; DBUG_ENTER("ha_blackhole::index_read_idx"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && - is_row_based_replication(thd)) + if (is_row_based_replication(thd)) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -264,8 +267,7 @@ int ha_blackhole::index_read_last_map(uchar * buf, const uchar * key, int rc; DBUG_ENTER("ha_blackhole::index_read_last"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && - is_row_based_replication(thd)) + if (is_row_based_replication(thd)) rc= 0; else rc= HA_ERR_END_OF_FILE; From 78c1be8b6b427e1331bbf0e5d5a24d57dc1477e3 Mon Sep 17 00:00:00 2001 From: Sujatha Date: Thu, 30 May 2019 12:11:57 +0530 Subject: [PATCH 05/25] MDEV-18913: typo in error log Problem: ======== Following typo in error log: 2019-03-13 15:58:10 0 [Note] Reading of all Master_info entries succeded Should be 'succeeded' Fix: === Fixed the typo with the right word 'succeeded'. --- sql/rpl_mi.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 58131ff771c..70e60b1d4ad 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -1233,7 +1233,7 @@ bool Master_info_index::init_all_master_info() if (!err_num) // No Error on read Master_info { if (global_system_variables.log_warnings > 1) - sql_print_information("Reading of all Master_info entries succeded"); + sql_print_information("Reading of all Master_info entries succeeded"); DBUG_RETURN(0); } if (succ_num) // Have some Error and some Success From dd939d6f7e57e418a6f80fb9057eef8823beaff6 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 30 May 2019 19:34:08 +0400 Subject: [PATCH 06/25] MDEV-15734 - calculation inside sizeof() warning Reverted incorrect change introduced by 548d03d7. As result is char**, third qsort() parameter must be sizeof(char*). Not sizeof(result[0] + 2), which is same as sizeof(result[0]). Not even sizeof(result[0]) + 2, which would cause invalid memory access. Proper sorting is responsibility of logfilenamecompare() callback. --- storage/tokudb/PerconaFT/ft/logger/logger.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/storage/tokudb/PerconaFT/ft/logger/logger.cc b/storage/tokudb/PerconaFT/ft/logger/logger.cc index 3f13fe10feb..ddbbdcb25ab 100644 --- a/storage/tokudb/PerconaFT/ft/logger/logger.cc +++ b/storage/tokudb/PerconaFT/ft/logger/logger.cc @@ -667,12 +667,8 @@ int toku_logger_find_logfiles (const char *directory, char ***resultp, int *n_lo snprintf(fname, fnamelen, "%s/%s", directory, de->d_name); result[n_results++] = fname; } - // Return them in increasing order. Set width to allow for newer log file names ("xxx.tokulog13") - // which are one character longer than old log file names ("xxx.tokulog2"). The comparison function - // won't look beyond the terminating NUL, so an extra character in the comparison string doesn't matter. - // Allow room for terminating NUL after "xxx.tokulog13" even if result[0] is of form "xxx.tokulog2." - int width = sizeof(result[0]+2); - qsort(result, n_results, width, logfilenamecompare); + // Return them in increasing order. + qsort(result, n_results, sizeof(result[0]), logfilenamecompare); *resultp = result; *n_logfiles = n_results; result[n_results]=0; // make a trailing null From 5de08a53ef8567d9c316c5a9eb4eda0ed6a2b11e Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Thu, 11 Apr 2019 15:46:39 +0300 Subject: [PATCH 07/25] MDEV-13631 Make use of clang-format Add .clang-format files to a root directory and to storage/innobase --- .clang-format | 18 ++++++++++++++++++ storage/innobase/.clang-format | 10 ++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .clang-format create mode 100644 storage/innobase/.clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000000..3b735b16d74 --- /dev/null +++ b/.clang-format @@ -0,0 +1,18 @@ +SpaceBeforeAssignmentOperators: false +SpaceAfterCStyleCast: true + +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: true + BeforeElse: true + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true diff --git a/storage/innobase/.clang-format b/storage/innobase/.clang-format new file mode 100644 index 00000000000..f7a72f3cf24 --- /dev/null +++ b/storage/innobase/.clang-format @@ -0,0 +1,10 @@ +UseTab: Always +TabWidth: 8 +IndentWidth: 8 +BreakBeforeBinaryOperators: All +PointerAlignment: Left +AlwaysBreakAfterReturnType: TopLevel +BreakBeforeBraces: Custom +BraceWrapping: + AfterFunction: true +AccessModifierOffset: -8 From 5a19908b955a6aeeeb09fb2ce7744d1c52b65a3b Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 31 May 2019 15:24:40 +0400 Subject: [PATCH 08/25] MDEV-19653 Add class Sql_cmd_create_table --- sql/handler.cc | 34 ++++++ sql/sql_alter.cc | 12 ++ sql/sql_alter.h | 5 +- sql/sql_cmd.h | 41 +++++++ sql/sql_parse.cc | 269 +----------------------------------------- sql/sql_table.cc | 300 +++++++++++++++++++++++++++++++++++++++++++++++ sql/sql_yacc.yy | 52 +++----- sql/table.cc | 16 ++- 8 files changed, 425 insertions(+), 304 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 0b7fbc93cb5..3d091401f4b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -211,6 +211,40 @@ redo: } +bool +Storage_engine_name::resolve_storage_engine_with_error(THD *thd, + handlerton **ha, + bool tmp_table) +{ +#if MYSQL_VERSION_ID < 100300 + /* + Please remove tmp_name when merging to 10.3 and pass m_storage_engine_name + directly to ha_resolve_by_name(). + */ + LEX_STRING tmp_name; + tmp_name.str= const_cast(m_storage_engine_name.str); + tmp_name.length= m_storage_engine_name.length; +#endif + if (plugin_ref plugin= ha_resolve_by_name(thd, &tmp_name, tmp_table)) + { + *ha= plugin_hton(plugin); + return false; + } + + *ha= NULL; + if (thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION) + { + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), m_storage_engine_name.str); + return true; + } + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_UNKNOWN_STORAGE_ENGINE, + ER_THD(thd, ER_UNKNOWN_STORAGE_ENGINE), + m_storage_engine_name.str); + return false; +} + + plugin_ref ha_lock_engine(THD *thd, const handlerton *hton) { if (hton) diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index e37d5471f41..8ec68bf4876 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -193,6 +193,18 @@ bool Sql_cmd_alter_table::execute(THD *thd) SELECT_LEX *select_lex= &lex->select_lex; /* first table of first SELECT_LEX */ TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first; + + const bool used_engine= lex->create_info.used_fields & HA_CREATE_USED_ENGINE; + DBUG_ASSERT((m_storage_engine_name.str != NULL) == used_engine); + if (used_engine) + { + if (resolve_storage_engine_with_error(thd, &lex->create_info.db_type, + lex->create_info.tmp_table())) + return true; // Engine not found, substitution is not allowed + if (!lex->create_info.db_type) // Not found, but substitution is allowed + lex->create_info.used_fields&= ~HA_CREATE_USED_ENGINE; + } + /* Code in mysql_alter_table() may modify its HA_CREATE_INFO argument, so we have to use a copy of this structure to make execution diff --git a/sql/sql_alter.h b/sql/sql_alter.h index a503837bfee..473208f0675 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -385,7 +385,8 @@ protected: Sql_cmd_alter_table represents the generic ALTER TABLE statement. @todo move Alter_info and other ALTER specific structures from Lex here. */ -class Sql_cmd_alter_table : public Sql_cmd_common_alter_table +class Sql_cmd_alter_table : public Sql_cmd_common_alter_table, + public Storage_engine_name { public: /** @@ -397,6 +398,8 @@ public: ~Sql_cmd_alter_table() {} + Storage_engine_name *option_storage_engine_name() { return this; } + bool execute(THD *thd); }; diff --git a/sql/sql_cmd.h b/sql/sql_cmd.h index 9583e015499..c237bb9270a 100644 --- a/sql/sql_cmd.h +++ b/sql/sql_cmd.h @@ -102,6 +102,31 @@ enum enum_sql_command { SQLCOM_END }; + +class Storage_engine_name +{ +protected: + LEX_CSTRING m_storage_engine_name; +public: + Storage_engine_name() + { + m_storage_engine_name.str= NULL; + m_storage_engine_name.length= 0; + } + Storage_engine_name(const LEX_CSTRING &name) + :m_storage_engine_name(name) + { } + Storage_engine_name(const LEX_STRING &name) + { + m_storage_engine_name.str= name.str; + m_storage_engine_name.length= name.length; + } + bool resolve_storage_engine_with_error(THD *thd, + handlerton **ha, + bool tmp_table); +}; + + /** @class Sql_cmd - Representation of an SQL command. @@ -145,6 +170,11 @@ public: */ virtual bool execute(THD *thd) = 0; + virtual Storage_engine_name *option_storage_engine_name() + { + return NULL; + } + protected: Sql_cmd() {} @@ -161,4 +191,15 @@ protected: } }; + +class Sql_cmd_create_table: public Sql_cmd, + public Storage_engine_name +{ +public: + enum_sql_command sql_command_code() const { return SQLCOM_CREATE_TABLE; } + Storage_engine_name *option_storage_engine_name() { return this; } + bool execute(THD *thd); +}; + + #endif // SQL_CMD_INCLUDED diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9cb65e82321..c8b9219c280 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3280,274 +3280,6 @@ mysql_execute_command(THD *thd) res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX); break; } - case SQLCOM_CREATE_TABLE: - { - DBUG_ASSERT(first_table == all_tables && first_table != 0); - bool link_to_local; - TABLE_LIST *create_table= first_table; - TABLE_LIST *select_tables= lex->create_last_non_select_table->next_global; - - if (lex->tmp_table()) - { - status_var_decrement(thd->status_var.com_stat[SQLCOM_CREATE_TABLE]); - status_var_increment(thd->status_var.com_create_tmp_table); - } - - /* - Code below (especially in mysql_create_table() and select_create - methods) may modify HA_CREATE_INFO structure in LEX, so we have to - use a copy of this structure to make execution prepared statement- - safe. A shallow copy is enough as this code won't modify any memory - referenced from this structure. - */ - Table_specification_st create_info(lex->create_info); - /* - We need to copy alter_info for the same reasons of re-execution - safety, only in case of Alter_info we have to do (almost) a deep - copy. - */ - Alter_info alter_info(lex->alter_info, thd->mem_root); - - if (thd->is_fatal_error) - { - /* If out of memory when creating a copy of alter_info. */ - res= 1; - goto end_with_restore_list; - } - - /* Check privileges */ - if ((res= create_table_precheck(thd, select_tables, create_table))) - goto end_with_restore_list; - - /* Might have been updated in create_table_precheck */ - create_info.alias= create_table->alias; - - /* Fix names if symlinked or relocated tables */ - if (append_file_to_dir(thd, &create_info.data_file_name, - create_table->table_name) || - append_file_to_dir(thd, &create_info.index_file_name, - create_table->table_name)) - goto end_with_restore_list; - - /* - If no engine type was given, work out the default now - rather than at parse-time. - */ - if (!(create_info.used_fields & HA_CREATE_USED_ENGINE)) - create_info.use_default_db_type(thd); - /* - If we are using SET CHARSET without DEFAULT, add an implicit - DEFAULT to not confuse old users. (This may change). - */ - if ((create_info.used_fields & - (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) == - HA_CREATE_USED_CHARSET) - { - create_info.used_fields&= ~HA_CREATE_USED_CHARSET; - create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; - create_info.default_table_charset= create_info.table_charset; - create_info.table_charset= 0; - } - - /* - If we are a slave, we should add OR REPLACE if we don't have - IF EXISTS. This will help a slave to recover from - CREATE TABLE OR EXISTS failures by dropping the table and - retrying the create. - */ - if (thd->slave_thread && - slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT && - !lex->create_info.if_not_exists()) - { - create_info.add(DDL_options_st::OPT_OR_REPLACE); - create_info.add(DDL_options_st::OPT_OR_REPLACE_SLAVE_GENERATED); - } - -#ifdef WITH_PARTITION_STORAGE_ENGINE - { - partition_info *part_info= thd->lex->part_info; - if (part_info && !(part_info= part_info->get_clone(thd))) - { - res= -1; - goto end_with_restore_list; - } - thd->work_part_info= part_info; - } -#endif - - if (select_lex->item_list.elements) // With select - { - select_result *result; - - /* - CREATE TABLE...IGNORE/REPLACE SELECT... can be unsafe, unless - ORDER BY PRIMARY KEY clause is used in SELECT statement. We therefore - use row based logging if mixed or row based logging is available. - TODO: Check if the order of the output of the select statement is - deterministic. Waiting for BUG#42415 - */ - if(lex->ignore) - lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_IGNORE_SELECT); - - if(lex->duplicates == DUP_REPLACE) - lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_REPLACE_SELECT); - - /* - If: - a) we inside an SP and there was NAME_CONST substitution, - b) binlogging is on (STMT mode), - c) we log the SP as separate statements - raise a warning, as it may cause problems - (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs') - */ - if (thd->query_name_consts && mysql_bin_log.is_open() && - thd->wsrep_binlog_format() == BINLOG_FORMAT_STMT && - !mysql_bin_log.is_query_in_union(thd, thd->query_id)) - { - List_iterator_fast it(select_lex->item_list); - Item *item; - uint splocal_refs= 0; - /* Count SP local vars in the top-level SELECT list */ - while ((item= it++)) - { - if (item->get_item_splocal()) - splocal_refs++; - } - /* - If it differs from number of NAME_CONST substitution applied, - we may have a SOME_FUNC(NAME_CONST()) in the SELECT list, - that may cause a problem with binary log (see BUG#35383), - raise a warning. - */ - if (splocal_refs != thd->query_name_consts) - push_warning(thd, - Sql_condition::WARN_LEVEL_WARN, - ER_UNKNOWN_ERROR, -"Invoked routine ran a statement that may cause problems with " -"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' " -"section of the manual."); - } - - select_lex->options|= SELECT_NO_UNLOCK; - unit->set_limit(select_lex); - - /* - Disable non-empty MERGE tables with CREATE...SELECT. Too - complicated. See Bug #26379. Empty MERGE tables are read-only - and don't allow CREATE...SELECT anyway. - */ - if (create_info.used_fields & HA_CREATE_USED_UNION) - { - my_error(ER_WRONG_OBJECT, MYF(0), create_table->db, - create_table->table_name, "BASE TABLE"); - res= 1; - goto end_with_restore_list; - } - - /* Copy temporarily the statement flags to thd for lock_table_names() */ - uint save_thd_create_info_options= thd->lex->create_info.options; - thd->lex->create_info.options|= create_info.options; - res= open_and_lock_tables(thd, create_info, lex->query_tables, TRUE, 0); - thd->lex->create_info.options= save_thd_create_info_options; - if (res) - { - /* Got error or warning. Set res to 1 if error */ - if (!(res= thd->is_error())) - my_ok(thd); // CREATE ... IF NOT EXISTS - goto end_with_restore_list; - } - - /* Ensure we don't try to create something from which we select from */ - if (create_info.or_replace() && !create_info.tmp_table()) - { - TABLE_LIST *duplicate; - if ((duplicate= unique_table(thd, lex->query_tables, - lex->query_tables->next_global, - CHECK_DUP_FOR_CREATE))) - { - update_non_unique_table_error(lex->query_tables, "CREATE", - duplicate); - res= TRUE; - goto end_with_restore_list; - } - } - { - /* - Remove target table from main select and name resolution - context. This can't be done earlier as it will break view merging in - statements like "CREATE TABLE IF NOT EXISTS existing_view SELECT". - */ - lex->unlink_first_table(&link_to_local); - - /* Store reference to table in case of LOCK TABLES */ - create_info.table= create_table->table; - - /* - select_create is currently not re-execution friendly and - needs to be created for every execution of a PS/SP. - Note: In wsrep-patch, CTAS is handled like a regular transaction. - */ - if ((result= new (thd->mem_root) select_create(thd, create_table, - &create_info, - &alter_info, - select_lex->item_list, - lex->duplicates, - lex->ignore, - select_tables))) - { - /* - CREATE from SELECT give its SELECT_LEX for SELECT, - and item_list belong to SELECT - */ - if (!(res= handle_select(thd, lex, result, 0))) - { - if (create_info.tmp_table()) - thd->variables.option_bits|= OPTION_KEEP_LOG; - } - delete result; - } - lex->link_first_table_back(create_table, link_to_local); - } - } - else - { - /* regular create */ - if (create_info.like()) - { - /* CREATE TABLE ... LIKE ... */ - res= mysql_create_like_table(thd, create_table, select_tables, - &create_info); - } - else - { - /* - In STATEMENT format, we probably have to replicate also temporary - tables, like mysql replication does. Also check if the requested - engine is allowed/supported. - */ - if (WSREP(thd) && - !check_engine(thd, create_table->db, create_table->table_name, - &create_info) && - (!thd->is_current_stmt_binlog_format_row() || - !create_info.tmp_table())) - { - WSREP_TO_ISOLATION_BEGIN(create_table->db, create_table->table_name, NULL) - } - /* Regular CREATE TABLE */ - res= mysql_create_table(thd, create_table, &create_info, &alter_info); - } - if (!res) - { - /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */ - if (create_info.tmp_table()) - thd->variables.option_bits|= OPTION_KEEP_LOG; - my_ok(thd); - } - } - -end_with_restore_list: - break; - } case SQLCOM_CREATE_INDEX: case SQLCOM_DROP_INDEX: /* @@ -5699,6 +5431,7 @@ end_with_restore_list: case SQLCOM_OPTIMIZE: case SQLCOM_REPAIR: case SQLCOM_TRUNCATE: + case SQLCOM_CREATE_TABLE: case SQLCOM_ALTER_TABLE: DBUG_ASSERT(first_table == all_tables && first_table != 0); /* fall through */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ca78c011866..2696513d95f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -10116,3 +10116,303 @@ bool check_engine(THD *thd, const char *db_name, DBUG_RETURN(false); } + + +bool Sql_cmd_create_table::execute(THD *thd) +{ + DBUG_ENTER("Sql_cmd_create_table::execute"); + LEX *lex= thd->lex; + TABLE_LIST *all_tables= lex->query_tables; + SELECT_LEX *select_lex= &lex->select_lex; + TABLE_LIST *first_table= select_lex->table_list.first; + DBUG_ASSERT(first_table == all_tables && first_table != 0); + bool link_to_local; + TABLE_LIST *create_table= first_table; + TABLE_LIST *select_tables= lex->create_last_non_select_table->next_global; + /* most outer SELECT_LEX_UNIT of query */ + SELECT_LEX_UNIT *unit= &lex->unit; + int res= 0; + + const bool used_engine= lex->create_info.used_fields & HA_CREATE_USED_ENGINE; + DBUG_ASSERT((m_storage_engine_name.str != NULL) == used_engine); + if (used_engine) + { + if (resolve_storage_engine_with_error(thd, &lex->create_info.db_type, + lex->create_info.tmp_table())) + DBUG_RETURN(true); // Engine not found, substitution is not allowed + + if (!lex->create_info.db_type) // Not found, but substitution is allowed + { + lex->create_info.use_default_db_type(thd); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WARN_USING_OTHER_HANDLER, + ER_THD(thd, ER_WARN_USING_OTHER_HANDLER), + hton_name(lex->create_info.db_type)->str, + create_table->table_name); + } + } + + if (lex->tmp_table()) + { + status_var_decrement(thd->status_var.com_stat[SQLCOM_CREATE_TABLE]); + status_var_increment(thd->status_var.com_create_tmp_table); + } + + /* + Code below (especially in mysql_create_table() and select_create + methods) may modify HA_CREATE_INFO structure in LEX, so we have to + use a copy of this structure to make execution prepared statement- + safe. A shallow copy is enough as this code won't modify any memory + referenced from this structure. + */ + Table_specification_st create_info(lex->create_info); + /* + We need to copy alter_info for the same reasons of re-execution + safety, only in case of Alter_info we have to do (almost) a deep + copy. + */ + Alter_info alter_info(lex->alter_info, thd->mem_root); + + if (thd->is_fatal_error) + { + /* If out of memory when creating a copy of alter_info. */ + res= 1; + goto end_with_restore_list; + } + + /* Check privileges */ + if ((res= create_table_precheck(thd, select_tables, create_table))) + goto end_with_restore_list; + + /* Might have been updated in create_table_precheck */ + create_info.alias= create_table->alias; + + /* Fix names if symlinked or relocated tables */ + if (append_file_to_dir(thd, &create_info.data_file_name, + create_table->table_name) || + append_file_to_dir(thd, &create_info.index_file_name, + create_table->table_name)) + goto end_with_restore_list; + + /* + If no engine type was given, work out the default now + rather than at parse-time. + */ + if (!(create_info.used_fields & HA_CREATE_USED_ENGINE)) + create_info.use_default_db_type(thd); + /* + If we are using SET CHARSET without DEFAULT, add an implicit + DEFAULT to not confuse old users. (This may change). + */ + if ((create_info.used_fields & + (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) == + HA_CREATE_USED_CHARSET) + { + create_info.used_fields&= ~HA_CREATE_USED_CHARSET; + create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + create_info.default_table_charset= create_info.table_charset; + create_info.table_charset= 0; + } + + /* + If we are a slave, we should add OR REPLACE if we don't have + IF EXISTS. This will help a slave to recover from + CREATE TABLE OR EXISTS failures by dropping the table and + retrying the create. + */ + if (thd->slave_thread && + slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT && + !lex->create_info.if_not_exists()) + { + create_info.add(DDL_options_st::OPT_OR_REPLACE); + create_info.add(DDL_options_st::OPT_OR_REPLACE_SLAVE_GENERATED); + } + +#ifdef WITH_PARTITION_STORAGE_ENGINE + { + partition_info *part_info= thd->lex->part_info; + if (part_info && !(part_info= part_info->get_clone(thd))) + { + res= -1; + goto end_with_restore_list; + } + thd->work_part_info= part_info; + } +#endif + + if (select_lex->item_list.elements) // With select + { + select_result *result; + + /* + CREATE TABLE...IGNORE/REPLACE SELECT... can be unsafe, unless + ORDER BY PRIMARY KEY clause is used in SELECT statement. We therefore + use row based logging if mixed or row based logging is available. + TODO: Check if the order of the output of the select statement is + deterministic. Waiting for BUG#42415 + */ + if(lex->ignore) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_IGNORE_SELECT); + + if(lex->duplicates == DUP_REPLACE) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_REPLACE_SELECT); + + /* + If: + a) we inside an SP and there was NAME_CONST substitution, + b) binlogging is on (STMT mode), + c) we log the SP as separate statements + raise a warning, as it may cause problems + (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs') + */ + if (thd->query_name_consts && mysql_bin_log.is_open() && + thd->wsrep_binlog_format() == BINLOG_FORMAT_STMT && + !mysql_bin_log.is_query_in_union(thd, thd->query_id)) + { + List_iterator_fast it(select_lex->item_list); + Item *item; + uint splocal_refs= 0; + /* Count SP local vars in the top-level SELECT list */ + while ((item= it++)) + { + if (item->get_item_splocal()) + splocal_refs++; + } + /* + If it differs from number of NAME_CONST substitution applied, + we may have a SOME_FUNC(NAME_CONST()) in the SELECT list, + that may cause a problem with binary log (see BUG#35383), + raise a warning. + */ + if (splocal_refs != thd->query_name_consts) + push_warning(thd, + Sql_condition::WARN_LEVEL_WARN, + ER_UNKNOWN_ERROR, +"Invoked routine ran a statement that may cause problems with " +"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' " +"section of the manual."); + } + + select_lex->options|= SELECT_NO_UNLOCK; + unit->set_limit(select_lex); + + /* + Disable non-empty MERGE tables with CREATE...SELECT. Too + complicated. See Bug #26379. Empty MERGE tables are read-only + and don't allow CREATE...SELECT anyway. + */ + if (create_info.used_fields & HA_CREATE_USED_UNION) + { + my_error(ER_WRONG_OBJECT, MYF(0), create_table->db, + create_table->table_name, "BASE TABLE"); + res= 1; + goto end_with_restore_list; + } + + /* Copy temporarily the statement flags to thd for lock_table_names() */ + uint save_thd_create_info_options= thd->lex->create_info.options; + thd->lex->create_info.options|= create_info.options; + res= open_and_lock_tables(thd, create_info, lex->query_tables, TRUE, 0); + thd->lex->create_info.options= save_thd_create_info_options; + if (res) + { + /* Got error or warning. Set res to 1 if error */ + if (!(res= thd->is_error())) + my_ok(thd); // CREATE ... IF NOT EXISTS + goto end_with_restore_list; + } + + /* Ensure we don't try to create something from which we select from */ + if (create_info.or_replace() && !create_info.tmp_table()) + { + TABLE_LIST *duplicate; + if ((duplicate= unique_table(thd, lex->query_tables, + lex->query_tables->next_global, + CHECK_DUP_FOR_CREATE))) + { + update_non_unique_table_error(lex->query_tables, "CREATE", + duplicate); + res= TRUE; + goto end_with_restore_list; + } + } + { + /* + Remove target table from main select and name resolution + context. This can't be done earlier as it will break view merging in + statements like "CREATE TABLE IF NOT EXISTS existing_view SELECT". + */ + lex->unlink_first_table(&link_to_local); + + /* Store reference to table in case of LOCK TABLES */ + create_info.table= create_table->table; + + /* + select_create is currently not re-execution friendly and + needs to be created for every execution of a PS/SP. + Note: In wsrep-patch, CTAS is handled like a regular transaction. + */ + if ((result= new (thd->mem_root) select_create(thd, create_table, + &create_info, + &alter_info, + select_lex->item_list, + lex->duplicates, + lex->ignore, + select_tables))) + { + /* + CREATE from SELECT give its SELECT_LEX for SELECT, + and item_list belong to SELECT + */ + if (!(res= handle_select(thd, lex, result, 0))) + { + if (create_info.tmp_table()) + thd->variables.option_bits|= OPTION_KEEP_LOG; + } + delete result; + } + lex->link_first_table_back(create_table, link_to_local); + } + } + else + { + /* regular create */ + if (create_info.like()) + { + /* CREATE TABLE ... LIKE ... */ + res= mysql_create_like_table(thd, create_table, select_tables, + &create_info); + } + else + { + /* + In STATEMENT format, we probably have to replicate also temporary + tables, like mysql replication does. Also check if the requested + engine is allowed/supported. + */ + if (WSREP(thd) && + !check_engine(thd, create_table->db, create_table->table_name, + &create_info) && + (!thd->is_current_stmt_binlog_format_row() || + !create_info.tmp_table())) + { + WSREP_TO_ISOLATION_BEGIN(create_table->db, create_table->table_name, NULL) + } + /* Regular CREATE TABLE */ + res= mysql_create_table(thd, create_table, &create_info, &alter_info); + } + if (!res) + { + /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */ + if (create_info.tmp_table()) + thd->variables.option_bits|= OPTION_KEEP_LOG; + my_ok(thd); + } + } + +end_with_restore_list: + DBUG_RETURN(res); + +WSREP_ERROR_LABEL: + DBUG_RETURN(true); +} diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 59cc73d88af..fe2c6b50f98 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2454,6 +2454,8 @@ create: create_or_replace opt_temporary TABLE_SYM opt_if_not_exists table_ident { LEX *lex= thd->lex; + if (!(lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_create_table())) + MYSQL_YYABORT; lex->create_info.init(); if (lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2, $1 | $4)) MYSQL_YYABORT; @@ -2475,16 +2477,6 @@ create: { LEX *lex= thd->lex; lex->current_select= &lex->select_lex; - if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) && - !lex->create_info.db_type) - { - lex->create_info.use_default_db_type(thd); - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_WARN_USING_OTHER_HANDLER, - ER_THD(thd, ER_WARN_USING_OTHER_HANDLER), - hton_name(lex->create_info.db_type)->str, - $5->table.str); - } create_table_set_open_action_and_adjust_tables(lex); } | create_or_replace opt_unique INDEX_SYM opt_if_not_exists ident @@ -5515,10 +5507,20 @@ create_table_options: ; create_table_option: - ENGINE_SYM opt_equal storage_engines + ENGINE_SYM opt_equal ident_or_text { - Lex->create_info.db_type= $3; - Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; + LEX *lex= Lex; + if (!lex->m_sql_cmd) + { + DBUG_ASSERT(lex->sql_command == SQLCOM_ALTER_TABLE); + if (!(lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table())) + MYSQL_YYABORT; + } + Storage_engine_name *opt= + lex->m_sql_cmd->option_storage_engine_name(); + DBUG_ASSERT(opt); // Expect a proper Sql_cmd + *opt= Storage_engine_name($3); + lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; } | MAX_ROWS opt_equal ulonglong_num { @@ -5783,21 +5785,10 @@ default_collation: storage_engines: ident_or_text { - plugin_ref plugin= ha_resolve_by_name(thd, &$1, - thd->lex->create_info.tmp_table()); - - if (plugin) - $$= plugin_hton(plugin); - else - { - if (thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION) - my_yyabort_error((ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str)); - $$= 0; - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_UNKNOWN_STORAGE_ENGINE, - ER_THD(thd, ER_UNKNOWN_STORAGE_ENGINE), - $1.str); - } + if (Storage_engine_name($1). + resolve_storage_engine_with_error(thd, &$$, + thd->lex->create_info.tmp_table())) + MYSQL_YYABORT; } ; @@ -7533,11 +7524,6 @@ alter_list_item: { LEX *lex=Lex; lex->alter_info.flags|= Alter_info::ALTER_OPTIONS; - if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) && - !lex->create_info.db_type) - { - lex->create_info.used_fields&= ~HA_CREATE_USED_ENGINE; - } } | FORCE_SYM { diff --git a/sql/table.cc b/sql/table.cc index 414196f2fb1..55b505a0cc0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2177,8 +2177,20 @@ static bool sql_unusable_for_discovery(THD *thd, handlerton *engine, if (create_info->data_file_name || create_info->index_file_name) return 1; // ... engine - if (create_info->db_type && create_info->db_type != engine) - return 1; + DBUG_ASSERT(lex->m_sql_cmd); + if (lex->create_info.used_fields & HA_CREATE_USED_ENGINE) + { + /* + TODO: we could just compare engine names here, without resolving. + But this optimization is too late for 10.1. + */ + Storage_engine_name *opt= lex->m_sql_cmd->option_storage_engine_name(); + DBUG_ASSERT(opt); // lex->m_sql_cmd must be an Sql_cmd_create_table instance + if (opt->resolve_storage_engine_with_error(thd, &create_info->db_type, + false) || + (create_info->db_type && create_info->db_type != engine)) + return 1; + } return 0; } From 1d4ac3d4d3ec3d52284f7260907111618f6cb6d9 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 22 May 2019 22:05:56 +0200 Subject: [PATCH 09/25] cleanup --- mysql-test/r/derived.result | 1 - mysql-test/r/multi_update.result | 4 ++- mysql-test/r/multi_update_innodb.result | 3 ++ mysql-test/t/derived.test | 3 -- mysql-test/t/multi_update.test | 9 ++---- mysql-test/t/multi_update_innodb.test | 4 +++ sql/sql_base.cc | 8 ++--- sql/sql_base.h | 12 +------- sql/sql_update.cc | 41 ++++++++----------------- 9 files changed, 30 insertions(+), 55 deletions(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 5debfaed5e3..2c0d0095678 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2,t3; set @save_derived_optimizer_switch=@@optimizer_switch; set optimizer_switch='derived_merge=off,derived_with_keys=off'; select * from (select 2 from DUAL) b; diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index e04637a3a54..e38d8737355 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -1038,4 +1038,6 @@ triggered triggered drop table t1,t2, t3; drop user foo; -end of 5.5 tests +# +# end of 5.5 tests +# diff --git a/mysql-test/r/multi_update_innodb.result b/mysql-test/r/multi_update_innodb.result index 643287c3a93..1d727f00e3e 100644 --- a/mysql-test/r/multi_update_innodb.result +++ b/mysql-test/r/multi_update_innodb.result @@ -67,3 +67,6 @@ SELECT * FROM t2; col_int_key pk_1 pk_2 col_int 1 2 3 4 DROP TABLE t1,t2; +# +# end of 5.5 tests +# diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index 217203422e0..62b2c43ca12 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -1,7 +1,4 @@ # Initialize ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings set @save_derived_optimizer_switch=@@optimizer_switch; set optimizer_switch='derived_merge=off,derived_with_keys=off'; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 964108b9b99..14c5574f61c 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -371,7 +371,6 @@ drop table t1, t2; # connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); -connection root; --disable_warnings create database mysqltest; --enable_warnings @@ -381,7 +380,6 @@ create table mysqltest.t3 (a int, b int, primary key (a)); grant select on mysqltest.* to mysqltest_1@localhost; grant update on mysqltest.t1 to mysqltest_1@localhost; connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK); -connection user1; update t1, t2 set t1.b=1 where t1.a=t2.a; update t1, t2 set t1.b=(select t3.b from t3 where t1.a=t3.a) where t1.a=t2.a; connection root; @@ -494,15 +492,12 @@ insert into t2 values (10), (20), (30); create view v1 as select a as b, a/10 as a from t2; connect (locker,localhost,root,,test); -connection locker; lock table t1 write; connect (changer,localhost,root,,test); -connection changer; send alter table t1 add column c int default 100 after a; connect (updater,localhost,root,,test); -connection updater; # Wait till "alter table t1 ..." of session changer is in work. # = There is one session waiting. let $wait_condition= select count(*)= 1 from information_schema.processlist @@ -1086,5 +1081,7 @@ select * from t2; drop table t1,t2, t3; drop user foo; ---echo end of 5.5 tests +--echo # +--echo # end of 5.5 tests +--echo # diff --git a/mysql-test/t/multi_update_innodb.test b/mysql-test/t/multi_update_innodb.test index 51757c29553..5807af4f489 100644 --- a/mysql-test/t/multi_update_innodb.test +++ b/mysql-test/t/multi_update_innodb.test @@ -75,3 +75,7 @@ UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_2=10,B.pk_2=11; SELECT * FROM t2; DROP TABLE t1,t2; + +--echo # +--echo # end of 5.5 tests +--echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4cc7b2fe3b9..a98cfbbd5c0 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5003,8 +5003,7 @@ open_tables_check_upgradable_mdl(THD *thd, TABLE_LIST *tables_start, @retval TRUE Error, reported. */ -bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, - Sroutine_hash_entry **sroutine_to_open_list, uint flags, +bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags, Prelocking_strategy *prelocking_strategy) { /* @@ -5053,7 +5052,7 @@ restart: has_prelocking_list= thd->lex->requires_prelocking(); table_to_open= start; - sroutine_to_open= sroutine_to_open_list; + sroutine_to_open= &thd->lex->sroutines_list.first; *counter= 0; thd_proc_info(thd, "Opening tables"); @@ -5112,8 +5111,7 @@ restart: elements in prelocking list/set. */ while (*table_to_open || - (thd->locked_tables_mode <= LTM_LOCK_TABLES && - *sroutine_to_open)) + (thd->locked_tables_mode <= LTM_LOCK_TABLES && *sroutine_to_open)) { /* For every table in the list of tables to open, try to find or open diff --git a/sql/sql_base.h b/sql/sql_base.h index 8a2317d2386..ea92e880db7 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -276,8 +276,7 @@ int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order); bool lock_table_names(THD *thd, TABLE_LIST *table_list, TABLE_LIST *table_list_end, ulong lock_wait_timeout, uint flags); -bool open_tables(THD *thd, TABLE_LIST **tables, uint *counter, - Sroutine_hash_entry **sroutine_to_open, uint flags, +bool open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags, Prelocking_strategy *prelocking_strategy); /* open_and_lock_tables with optional derived handling */ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, @@ -499,15 +498,6 @@ private: }; -inline bool -open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags, - Prelocking_strategy *prelocking_strategy) -{ - return open_tables(thd, tables, counter, &thd->lex->sroutines_list.first, - flags, prelocking_strategy); -} - - inline bool open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags) { diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 38444911523..ac066507042 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1251,9 +1251,8 @@ int mysql_multi_update_prepare(THD *thd) if (setup_tables_and_check_access(thd, &lex->select_lex.context, &lex->select_lex.top_join_list, - table_list, - lex->select_lex.leaf_tables, FALSE, - UPDATE_ACL, SELECT_ACL, FALSE)) + table_list, lex->select_lex.leaf_tables, + FALSE, UPDATE_ACL, SELECT_ACL, FALSE)) DBUG_RETURN(TRUE); if (lex->select_lex.handle_derived(thd->lex, DT_MERGE)) @@ -1272,9 +1271,7 @@ int mysql_multi_update_prepare(THD *thd) } if (update_view && check_fields(thd, *fields)) - { DBUG_RETURN(TRUE); - } thd->table_map_for_update= tables_for_update= get_table_map(fields); @@ -1293,8 +1290,7 @@ int mysql_multi_update_prepare(THD *thd) TABLE *table= tl->table; /* Only set timestamp column if this is not modified */ if (table->timestamp_field && - bitmap_is_set(table->write_set, - table->timestamp_field->field_index)) + bitmap_is_set(table->write_set, table->timestamp_field->field_index)) table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; /* if table will be updated then check that it is unique */ @@ -1355,10 +1351,8 @@ int mysql_multi_update_prepare(THD *thd) if (!tl->is_derived()) { uint want_privilege= tl->updating ? UPDATE_ACL : SELECT_ACL; - if (check_access(thd, want_privilege, tl->db, - &tl->grant.privilege, - &tl->grant.m_internal, - 0, 0) || + if (check_access(thd, want_privilege, tl->db, &tl->grant.privilege, + &tl->grant.m_internal, 0, 0) || check_grant(thd, want_privilege, tl, FALSE, 1, FALSE)) DBUG_RETURN(TRUE); } @@ -1434,25 +1428,18 @@ int mysql_multi_update_prepare(THD *thd) Setup multi-update handling and call SELECT to do the join */ -bool mysql_multi_update(THD *thd, - TABLE_LIST *table_list, - List *fields, - List *values, - COND *conds, - ulonglong options, +bool mysql_multi_update(THD *thd, TABLE_LIST *table_list, List *fields, + List *values, COND *conds, ulonglong options, enum enum_duplicates handle_duplicates, - bool ignore, - SELECT_LEX_UNIT *unit, - SELECT_LEX *select_lex, - multi_update **result) + bool ignore, SELECT_LEX_UNIT *unit, + SELECT_LEX *select_lex, multi_update **result) { bool res; DBUG_ENTER("mysql_multi_update"); if (!(*result= new multi_update(table_list, &thd->lex->select_lex.leaf_tables, - fields, values, - handle_duplicates, ignore))) + fields, values, handle_duplicates, ignore))) { DBUG_RETURN(TRUE); } @@ -1463,11 +1450,9 @@ bool mysql_multi_update(THD *thd, List total_list; - res= mysql_select(thd, &select_lex->ref_pointer_array, - table_list, select_lex->with_wild, - total_list, - conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL, - (ORDER *)NULL, + res= mysql_select(thd, &select_lex->ref_pointer_array, table_list, + select_lex->with_wild, total_list, conds, 0, NULL, NULL, + NULL, NULL, options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | OPTION_SETUP_TABLES_DONE, *result, unit, select_lex); From 6660c072ada63847e0284026598f65f1e6d6bb2e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 22 May 2019 21:56:36 +0200 Subject: [PATCH 10/25] MDEV-19491 update query stopped working after mariadb upgrade 10.2.23 -> 10.2.24 as well as MDEV-19500 Update with join stopped worked if there is a call to a procedure in a trigger MDEV-19521 Update Table Fails with Trigger and Stored Function MDEV-19497 Replication stops because table not found MDEV-19527 UPDATE + JOIN + TRIGGERS = table doesn't exists error Reimplement the fix for (5d510fdbf00) MDEV-18507 can't update temporary table when joined with table with triggers on read-only instead of calling open_tables() twice, put multi-update prepare code inside open_tables() loop. Add a test for a MDL backoff-and-retry loop inside open_tables() across multi-update prepare code. --- mysql-test/r/multi_update.result | 18 ++ mysql-test/r/multi_update_debug.result | 13 ++ mysql-test/r/multi_update_innodb.result | 14 ++ mysql-test/t/multi_update.test | 29 ++++ mysql-test/t/multi_update_debug.test | 27 +++ mysql-test/t/multi_update_innodb.test | 18 ++ sql/sql_base.cc | 3 + sql/sql_base.h | 2 + sql/sql_update.cc | 210 +++++++++++++----------- 9 files changed, 234 insertions(+), 100 deletions(-) create mode 100644 mysql-test/r/multi_update_debug.result create mode 100644 mysql-test/t/multi_update_debug.test diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index e38d8737355..05fc619c50c 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -1038,6 +1038,24 @@ triggered triggered drop table t1,t2, t3; drop user foo; +create table t1 (a int, b int); +create table t2 (c int, d int); +insert t1 values (1,2),(3,4); +insert t2 values (5,6),(7,8); +create table t0 (x int); +insert t0 values (11), (22); +create trigger tr1 before update on t2 for each row insert t0 values (new.c); +lock table t0 write; +update t1 join t2 on (a=c+4) set b=d; +drop table t1, t2, t0; +create table t1 (a int, b varchar(50), c varchar(50)); +insert t1 (a,b) values (1,'1'), (2,'2'), (3,'3'); +create function f1() returns varchar(50) return 'result'; +create trigger tr before update on t1 for each row set new.c = (select f1()); +create table t2 select a, b from t1; +update t1 join t2 using (a) set t1.b = t2.b; +drop table t1, t2; +drop function f1; # # end of 5.5 tests # diff --git a/mysql-test/r/multi_update_debug.result b/mysql-test/r/multi_update_debug.result new file mode 100644 index 00000000000..8bcd813e5b7 --- /dev/null +++ b/mysql-test/r/multi_update_debug.result @@ -0,0 +1,13 @@ +create table t1 (a int, b int); +create table t2 (c int, d int); +insert t1 values (1,2),(3,4); +insert t2 values (5,6),(7,8); +create table t0 (x int); +insert t0 values (11), (22); +create trigger tr1 before update on t1 for each row insert t0 values (new.b); +set debug_sync='open_tables_after_open_and_process_table WAIT_FOR cont'; +update t1 join t2 on (a=c+4) set b=d; +set debug_sync='mdl_acquire_lock_wait SIGNAL cont'; +lock table t1 write, t0 write; +drop table t1, t2, t0; +set debug_sync='reset'; diff --git a/mysql-test/r/multi_update_innodb.result b/mysql-test/r/multi_update_innodb.result index 1d727f00e3e..5da8cf46f5a 100644 --- a/mysql-test/r/multi_update_innodb.result +++ b/mysql-test/r/multi_update_innodb.result @@ -67,6 +67,20 @@ SELECT * FROM t2; col_int_key pk_1 pk_2 col_int 1 2 3 4 DROP TABLE t1,t2; +create table t1 (id serial, size int(11)) engine=innodb; +create table t2 (id serial, size int, account_id int) engine=innodb; +create table t3 (id serial, size int, article_id int) engine=innodb; +create table t4 (id serial, file_id int, article_id int) engine=innodb; +insert t1 values(null, 400); +insert t2 values(null, 0, 1), (null, 1, 1); +insert t3 values(null, 100, 1); +insert t4 values(null, 1, 2); +create trigger file_update_article before update on t3 for each row +update t2 set t2.size = new.size where t2.id = new.article_id; +create trigger article_update_account before update on t2 for each row +update t1 set t1.size = t1.size + new.size where t1.id = new.account_id; +update t3 join t4 on t4.file_id =t3.id and t4.article_id=2 set t3.size=t3.size + 2; +drop table t1, t2, t3, t4; # # end of 5.5 tests # diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 14c5574f61c..26943c347c0 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -1081,6 +1081,35 @@ select * from t2; drop table t1,t2, t3; drop user foo; +# +# Another test on not-opening tables unnecessary +# +create table t1 (a int, b int); +create table t2 (c int, d int); +insert t1 values (1,2),(3,4); +insert t2 values (5,6),(7,8); +create table t0 (x int); +insert t0 values (11), (22); +create trigger tr1 before update on t2 for each row insert t0 values (new.c); +connect con1, localhost, root; +lock table t0 write; +connection default; +update t1 join t2 on (a=c+4) set b=d; +disconnect con1; +drop table t1, t2, t0; + +# +# MDEV-19521 Update Table Fails with Trigger and Stored Function +# +create table t1 (a int, b varchar(50), c varchar(50)); +insert t1 (a,b) values (1,'1'), (2,'2'), (3,'3'); +create function f1() returns varchar(50) return 'result'; +create trigger tr before update on t1 for each row set new.c = (select f1()); +create table t2 select a, b from t1; +update t1 join t2 using (a) set t1.b = t2.b; +drop table t1, t2; +drop function f1; + --echo # --echo # end of 5.5 tests --echo # diff --git a/mysql-test/t/multi_update_debug.test b/mysql-test/t/multi_update_debug.test new file mode 100644 index 00000000000..2da376e1b87 --- /dev/null +++ b/mysql-test/t/multi_update_debug.test @@ -0,0 +1,27 @@ +# +# test MDL backoff-and-retry during multi-update +# +source include/have_debug_sync.inc; +create table t1 (a int, b int); +create table t2 (c int, d int); +insert t1 values (1,2),(3,4); +insert t2 values (5,6),(7,8); +create table t0 (x int); +insert t0 values (11), (22); +create trigger tr1 before update on t1 for each row insert t0 values (new.b); + +set debug_sync='open_tables_after_open_and_process_table WAIT_FOR cont'; +send update t1 join t2 on (a=c+4) set b=d; + +connect con1, localhost, root; +let $wait_condition= select count(*) from information_schema.processlist where state = ' debug sync point: open_tables_after_open_and_process_table' +source include/wait_condition.inc; +set debug_sync='mdl_acquire_lock_wait SIGNAL cont'; +lock table t1 write, t0 write; +let $wait_condition= select count(*) from information_schema.processlist where state = 'Waiting for table metadata lock' +source include/wait_condition.inc; +disconnect con1; +connection default; +reap; +drop table t1, t2, t0; +set debug_sync='reset'; diff --git a/mysql-test/t/multi_update_innodb.test b/mysql-test/t/multi_update_innodb.test index 5807af4f489..9042f267c66 100644 --- a/mysql-test/t/multi_update_innodb.test +++ b/mysql-test/t/multi_update_innodb.test @@ -76,6 +76,24 @@ SELECT * FROM t2; DROP TABLE t1,t2; +# +# MDEV-19491 update query stopped working after mariadb upgrade 10.2.23 -> 10.2.24 +# +create table t1 (id serial, size int(11)) engine=innodb; +create table t2 (id serial, size int, account_id int) engine=innodb; +create table t3 (id serial, size int, article_id int) engine=innodb; +create table t4 (id serial, file_id int, article_id int) engine=innodb; +insert t1 values(null, 400); +insert t2 values(null, 0, 1), (null, 1, 1); +insert t3 values(null, 100, 1); +insert t4 values(null, 1, 2); +create trigger file_update_article before update on t3 for each row + update t2 set t2.size = new.size where t2.id = new.article_id; +create trigger article_update_account before update on t2 for each row + update t1 set t1.size = t1.size + new.size where t1.id = new.account_id; +update t3 join t4 on t4.file_id =t3.id and t4.article_id=2 set t3.size=t3.size + 2; +drop table t1, t2, t3, t4; + --echo # --echo # end of 5.5 tests --echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index a98cfbbd5c0..27ee8957b25 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5055,6 +5055,7 @@ restart: sroutine_to_open= &thd->lex->sroutines_list.first; *counter= 0; thd_proc_info(thd, "Opening tables"); + prelocking_strategy->reset(thd); /* If we are executing LOCK TABLES statement or a DDL statement @@ -5218,6 +5219,8 @@ restart: } } } + if ((error= prelocking_strategy->handle_end(thd))) + goto err; } /* diff --git a/sql/sql_base.h b/sql/sql_base.h index ea92e880db7..439052a28f5 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -426,6 +426,7 @@ class Prelocking_strategy public: virtual ~Prelocking_strategy() { } + virtual void reset(THD *thd) { }; virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx, Sroutine_hash_entry *rt, sp_head *sp, bool *need_prelocking) = 0; @@ -433,6 +434,7 @@ public: TABLE_LIST *table_list, bool *need_prelocking) = 0; virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx, TABLE_LIST *table_list, bool *need_prelocking)= 0; + virtual bool handle_end(THD *thd) { return 0; }; }; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index ac066507042..e01fe0926dd 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1188,103 +1188,81 @@ bool unsafe_key_update(List leaves, table_map tables_for_update) } -/* - make update specific preparation and checks after opening tables - - SYNOPSIS - mysql_multi_update_prepare() - thd thread handler - - RETURN - FALSE OK - TRUE Error -*/ - -int mysql_multi_update_prepare(THD *thd) +class Multiupdate_prelocking_strategy : public DML_prelocking_strategy { + bool done; + bool has_prelocking_list; +public: + void reset(THD *thd); + bool handle_end(THD *thd); +}; + +void Multiupdate_prelocking_strategy::reset(THD *thd) +{ + done= false; + has_prelocking_list= thd->lex->requires_prelocking(); +} + +/** + Determine what tables could be updated in the multi-update + + For these tables we'll need to open triggers and continue prelocking + until all is open. +*/ +bool Multiupdate_prelocking_strategy::handle_end(THD *thd) +{ + DBUG_ENTER("Multiupdate_prelocking_strategy::handle_end"); + if (done) + DBUG_RETURN(0); + LEX *lex= thd->lex; - TABLE_LIST *table_list= lex->query_tables; - TABLE_LIST *tl; - List *fields= &lex->select_lex.item_list; - table_map tables_for_update; - bool update_view= 0; - DML_prelocking_strategy prelocking_strategy; - bool has_prelocking_list= thd->lex->requires_prelocking(); + SELECT_LEX *select_lex= &lex->select_lex; + TABLE_LIST *table_list= lex->query_tables, *tl; - /* - if this multi-update was converted from usual update, here is table - counter else junk will be assigned here, but then replaced with real - count in open_tables() - */ - uint table_count= lex->table_count; - const bool using_lock_tables= thd->locked_tables_mode != LTM_NONE; - bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI); - DBUG_ENTER("mysql_multi_update_prepare"); + done= true; - /* following need for prepared statements, to run next time multi-update */ - thd->lex->sql_command= SQLCOM_UPDATE_MULTI; + if (mysql_handle_derived(lex, DT_INIT) || + mysql_handle_derived(lex, DT_MERGE_FOR_INSERT) || + mysql_handle_derived(lex, DT_PREPARE)) + DBUG_RETURN(1); - /* - Open tables and create derived ones, but do not lock and fill them yet. - - During prepare phase acquire only S metadata locks instead of SW locks to - keep prepare of multi-UPDATE compatible with concurrent LOCK TABLES WRITE - and global read lock. - */ - if ((original_multiupdate && open_tables(thd, &table_list, &table_count, - thd->stmt_arena->is_stmt_prepare() - ? MYSQL_OPEN_FORCE_SHARED_MDL : 0, - &prelocking_strategy)) || - mysql_handle_derived(lex, DT_INIT)) - DBUG_RETURN(TRUE); /* setup_tables() need for VIEWs. JOIN::prepare() will call setup_tables() second time, but this call will do nothing (there are check for second call in setup_tables()). */ - //We need to merge for insert prior to prepare. - if (mysql_handle_derived(lex, DT_MERGE_FOR_INSERT)) - DBUG_RETURN(TRUE); - if (mysql_handle_derived(lex, DT_PREPARE)) - DBUG_RETURN(TRUE); + if (setup_tables_and_check_access(thd, &select_lex->context, + &select_lex->top_join_list, table_list, select_lex->leaf_tables, + FALSE, UPDATE_ACL, SELECT_ACL, FALSE)) + DBUG_RETURN(1); - if (setup_tables_and_check_access(thd, &lex->select_lex.context, - &lex->select_lex.top_join_list, - table_list, lex->select_lex.leaf_tables, - FALSE, UPDATE_ACL, SELECT_ACL, FALSE)) - DBUG_RETURN(TRUE); - - if (lex->select_lex.handle_derived(thd->lex, DT_MERGE)) - DBUG_RETURN(TRUE); + if (select_lex->handle_derived(thd->lex, DT_MERGE)) + DBUG_RETURN(1); + List *fields= &lex->select_lex.item_list; if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0)) - DBUG_RETURN(TRUE); + DBUG_RETURN(1); for (tl= table_list; tl ; tl= tl->next_local) - { if (tl->view) { - update_view= 1; - break; + if (check_fields(thd, *fields)) + DBUG_RETURN(1); + else + break; } - } - if (update_view && check_fields(thd, *fields)) - DBUG_RETURN(TRUE); + table_map tables_for_update= thd->table_map_for_update= get_table_map(fields); - thd->table_map_for_update= tables_for_update= get_table_map(fields); - - if (unsafe_key_update(lex->select_lex.leaf_tables, tables_for_update)) - DBUG_RETURN(true); - - TABLE_LIST **new_tables= lex->query_tables_last; - DBUG_ASSERT(*new_tables== NULL); + if (unsafe_key_update(select_lex->leaf_tables, tables_for_update)) + DBUG_RETURN(1); /* Setup timestamp handling and locking mode */ - List_iterator ti(lex->select_lex.leaf_tables); + List_iterator ti(select_lex->leaf_tables); + const bool using_lock_tables= thd->locked_tables_mode != LTM_NONE; while ((tl= ti++)) { TABLE *table= tl->table; @@ -1299,7 +1277,7 @@ int mysql_multi_update_prepare(THD *thd) if (!tl->single_table_updatable() || check_key_in_view(thd, tl)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), tl->alias, "UPDATE"); - DBUG_RETURN(TRUE); + DBUG_RETURN(1); } DBUG_PRINT("info",("setting table `%s` for update", tl->alias)); @@ -1310,8 +1288,8 @@ int mysql_multi_update_prepare(THD *thd) tl->updating= 1; if (tl->belong_to_view) tl->belong_to_view->updating= 1; - if (extend_table_list(thd, tl, &prelocking_strategy, has_prelocking_list)) - DBUG_RETURN(TRUE); + if (extend_table_list(thd, tl, this, has_prelocking_list)) + DBUG_RETURN(1); } else { @@ -1333,15 +1311,62 @@ int mysql_multi_update_prepare(THD *thd) } } - uint addon_table_count= 0; - if (*new_tables) + /* check single table update for view compound from several tables */ + for (tl= table_list; tl; tl= tl->next_local) { - Sroutine_hash_entry **new_routines= thd->lex->sroutines_list.next; - DBUG_ASSERT(*new_routines == NULL); - if (open_tables(thd, new_tables, &addon_table_count, new_routines, - thd->stmt_arena->is_stmt_prepare() - ? MYSQL_OPEN_FORCE_SHARED_MDL : 0, - &prelocking_strategy)) + TABLE_LIST *for_update= 0; + if (tl->is_merged_derived() && + tl->check_single_table(&for_update, tables_for_update, tl)) + { + my_error(ER_VIEW_MULTIUPDATE, MYF(0), tl->view_db.str, tl->view_name.str); + DBUG_RETURN(1); + } + } + + DBUG_RETURN(0); +} + +/* + make update specific preparation and checks after opening tables + + SYNOPSIS + mysql_multi_update_prepare() + thd thread handler + + RETURN + FALSE OK + TRUE Error +*/ + +int mysql_multi_update_prepare(THD *thd) +{ + LEX *lex= thd->lex; + TABLE_LIST *table_list= lex->query_tables; + TABLE_LIST *tl; + Multiupdate_prelocking_strategy prelocking_strategy; + uint table_count= lex->table_count; + DBUG_ENTER("mysql_multi_update_prepare"); + + /* + Open tables and create derived ones, but do not lock and fill them yet. + + During prepare phase acquire only S metadata locks instead of SW locks to + keep prepare of multi-UPDATE compatible with concurrent LOCK TABLES WRITE + and global read lock. + */ + if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI) + { + if (open_tables(thd, &table_list, &table_count, + thd->stmt_arena->is_stmt_prepare() ? MYSQL_OPEN_FORCE_SHARED_MDL : 0, + &prelocking_strategy)) + DBUG_RETURN(TRUE); + } + else + { + /* following need for prepared statements, to run next time multi-update */ + thd->lex->sql_command= SQLCOM_UPDATE_MULTI; + prelocking_strategy.reset(thd); + if (prelocking_strategy.handle_end(thd)) DBUG_RETURN(TRUE); } @@ -1358,24 +1383,9 @@ int mysql_multi_update_prepare(THD *thd) } } - /* check single table update for view compound from several tables */ - for (tl= table_list; tl; tl= tl->next_local) - { - if (tl->is_merged_derived()) - { - TABLE_LIST *for_update= 0; - if (tl->check_single_table(&for_update, tables_for_update, tl)) - { - my_error(ER_VIEW_MULTIUPDATE, MYF(0), - tl->view_db.str, tl->view_name.str); - DBUG_RETURN(-1); - } - } - } - /* now lock and fill tables */ if (!thd->stmt_arena->is_stmt_prepare() && - lock_tables(thd, table_list, table_count + addon_table_count, 0)) + lock_tables(thd, table_list, table_count, 0)) { DBUG_RETURN(TRUE); } @@ -1387,7 +1397,7 @@ int mysql_multi_update_prepare(THD *thd) */ lex->select_lex.exclude_from_table_unique_test= TRUE; /* We only need SELECT privilege for columns in the values list */ - ti.rewind(); + List_iterator ti(lex->select_lex.leaf_tables); while ((tl= ti++)) { TABLE *table= tl->table; From b003b0c934cf6b59358e31144c4f69cf34622fb8 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 3 Jun 2019 12:42:36 +0400 Subject: [PATCH 11/25] MDEV-19675 Wrong charset is chosen when opening a pre-4.1 table --- mysql-test/r/ctype_utf8_def_upgrade.result | 99 ++++++++++++++++++++++ mysql-test/t/ctype_utf8_def_upgrade.opt | 1 + mysql-test/t/ctype_utf8_def_upgrade.test | 61 +++++++++++++ sql/table.cc | 5 +- 4 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/ctype_utf8_def_upgrade.result create mode 100644 mysql-test/t/ctype_utf8_def_upgrade.opt create mode 100644 mysql-test/t/ctype_utf8_def_upgrade.test diff --git a/mysql-test/r/ctype_utf8_def_upgrade.result b/mysql-test/r/ctype_utf8_def_upgrade.result new file mode 100644 index 00000000000..1b921289af6 --- /dev/null +++ b/mysql-test/r/ctype_utf8_def_upgrade.result @@ -0,0 +1,99 @@ +# +# Start of 10.1 tests +# +# +# MDEV-19675 Wrong charset is chosen when opening a pre-4.1 table +# +# Test with a saved table from 3.23 +SELECT @@character_set_database; +@@character_set_database +utf8 +SET @@character_set_database="latin1"; +SELECT COUNT(*) FROM t1; +ERROR HY000: Got error 190 "Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine. You have to dump an" from storage engine MyISAM +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check Error Got error 190 "Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine. You have to dump an" from storage engine MyISAM +test.t1 check error Corrupt +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair Error Got error 190 "Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine. You have to dump an" from storage engine MyISAM +test.t1 repair error Corrupt +REPAIR TABLE t1 USE_FRM; +Table Op Msg_type Msg_text +test.t1 repair status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `Host` char(60) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', + `Db` char(64) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', + `Select_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Insert_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Update_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Delete_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Create_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Drop_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Grant_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `References_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Index_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Alter_priv` enum('N','Y') NOT NULL DEFAULT 'N', + PRIMARY KEY (`Host`,`Db`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Host privileges; Merged with database privileges' +DROP TABLE t1; +SET @@character_set_database=DEFAULT; +# Now do the same, but doing 'ALTER DATABASE' to create the db.opt file, +# instead of setting variables directly. +# Emulate a pre-4.1 database without db.opt +SHOW CREATE DATABASE db1; +Database Create Database +db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8 */ +USE db1; +SELECT @@character_set_database, 'taken from defaults' AS comment; +@@character_set_database comment +utf8 taken from defaults +USE test; +ALTER DATABASE db1 DEFAULT CHARACTER SET latin1; +USE db1; +SELECT @@character_set_database, 'taken from db.opt' AS comment; +@@character_set_database comment +latin1 taken from db.opt +SELECT COUNT(*) FROM t1; +ERROR HY000: Got error 190 "Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine. You have to dump an" from storage engine MyISAM +REPAIR TABLE t1 USE_FRM; +Table Op Msg_type Msg_text +db1.t1 repair status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +CHECK TABLE t1; +Table Op Msg_type Msg_text +db1.t1 check status OK +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `Host` char(60) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', + `Db` char(64) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', + `Select_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Insert_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Update_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Delete_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Create_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Drop_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Grant_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `References_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Index_priv` enum('N','Y') NOT NULL DEFAULT 'N', + `Alter_priv` enum('N','Y') NOT NULL DEFAULT 'N', + PRIMARY KEY (`Host`,`Db`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Host privileges; Merged with database privileges' +DROP TABLE t1; +DROP DATABASE db1; +USE test; +# +# End of 10.1 tests +# diff --git a/mysql-test/t/ctype_utf8_def_upgrade.opt b/mysql-test/t/ctype_utf8_def_upgrade.opt new file mode 100644 index 00000000000..61a472b45c5 --- /dev/null +++ b/mysql-test/t/ctype_utf8_def_upgrade.opt @@ -0,0 +1 @@ +--character-set-server=utf8 diff --git a/mysql-test/t/ctype_utf8_def_upgrade.test b/mysql-test/t/ctype_utf8_def_upgrade.test new file mode 100644 index 00000000000..4751faa0622 --- /dev/null +++ b/mysql-test/t/ctype_utf8_def_upgrade.test @@ -0,0 +1,61 @@ +let $MYSQLD_DATADIR= `select @@datadir`; + +--echo # +--echo # Start of 10.1 tests +--echo # + +--echo # +--echo # MDEV-19675 Wrong charset is chosen when opening a pre-4.1 table +--echo # + +--echo # Test with a saved table from 3.23 + +SELECT @@character_set_database; +SET @@character_set_database="latin1"; +--copy_file std_data/host_old.frm $MYSQLD_DATADIR/test/t1.frm +--copy_file std_data/host_old.MYD $MYSQLD_DATADIR/test/t1.MYD +--copy_file std_data/host_old.MYI $MYSQLD_DATADIR/test/t1.MYI + +--error ER_GET_ERRNO +SELECT COUNT(*) FROM t1; +CHECK TABLE t1; +REPAIR TABLE t1; +REPAIR TABLE t1 USE_FRM; +SELECT COUNT(*) FROM t1; +CHECK TABLE t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; +SET @@character_set_database=DEFAULT; + + +--echo # Now do the same, but doing 'ALTER DATABASE' to create the db.opt file, +--echo # instead of setting variables directly. + +--echo # Emulate a pre-4.1 database without db.opt +--mkdir $MYSQLD_DATADIR/db1 +SHOW CREATE DATABASE db1; +USE db1; +SELECT @@character_set_database, 'taken from defaults' AS comment; +USE test; +ALTER DATABASE db1 DEFAULT CHARACTER SET latin1; +USE db1; +SELECT @@character_set_database, 'taken from db.opt' AS comment; + +--copy_file std_data/host_old.frm $MYSQLD_DATADIR/db1/t1.frm +--copy_file std_data/host_old.MYD $MYSQLD_DATADIR/db1/t1.MYD +--copy_file std_data/host_old.MYI $MYSQLD_DATADIR/db1/t1.MYI + +--error ER_GET_ERRNO +SELECT COUNT(*) FROM t1; +REPAIR TABLE t1 USE_FRM; +SELECT COUNT(*) FROM t1; +CHECK TABLE t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +DROP DATABASE db1; +USE test; + +--echo # +--echo # End of 10.1 tests +--echo # diff --git a/sql/table.cc b/sql/table.cc index 55b505a0cc0..12b23304acd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1104,8 +1104,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } if (!share->table_charset) { + const CHARSET_INFO *cs= thd->variables.collation_database; /* unknown charset in frm_image[38] or pre-3.23 frm */ - if (use_mb(default_charset_info)) + if (use_mb(cs)) { /* Warn that we may be changing the size of character columns */ sql_print_warning("'%s' had no or invalid character set, " @@ -1113,7 +1114,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, "so character column sizes may have changed", share->path.str); } - share->table_charset= default_charset_info; + share->table_charset= cs; } share->db_record_offset= 1; From c97c8c28b5c8b33d9b1b8563f4ce015c1668b7f1 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 5 Jun 2019 19:42:21 +0200 Subject: [PATCH 12/25] MDEV-17103 MY_CHECK_{C,CXX}_COMPILER_FLAG do not work on with localized gcc messages Force LANG=C for MY_CHECK_{C,CXX}_COMPILER_FLAG --- cmake/check_compiler_flag.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/check_compiler_flag.cmake b/cmake/check_compiler_flag.cmake index 673361ab8fe..547325e4fa2 100644 --- a/cmake/check_compiler_flag.cmake +++ b/cmake/check_compiler_flag.cmake @@ -13,7 +13,8 @@ SET(fail_patterns FAIL_REGEX "warning:.*redefined" FAIL_REGEX "[Ww]arning: [Oo]ption" ) - +#The regex patterns above are not localized, thus LANG=C +SET(ENV{LANG} C) MACRO (MY_CHECK_C_COMPILER_FLAG flag) STRING(REGEX REPLACE "[-,= +]" "_" result "HAVE_C_${flag}") SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") From e7695f95ae714f3168ce953fd022ddfb40f03e67 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 7 Jun 2019 12:24:27 +0400 Subject: [PATCH 13/25] MDEV-19360 - Disable _FORTIFY_SOURCE for ASAN builds Those two may work incorrectly together. Namely, ASAN may produce false positives or false negatives. For details see https://github.com/google/sanitizers/wiki/AddressSanitizer#faq Make SECURITY_HARDENED disabled by default if WITH_ASAN=ON Based on contribution by Eugene Kosov. --- CMakeLists.txt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 32e9b1e9498..083fa753b88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,6 +191,8 @@ INCLUDE(check_compiler_flag) OPTION(WITH_ASAN "Enable address sanitizer" OFF) IF (WITH_ASAN) + # this flag might be set by default on some OS + MY_CHECK_AND_SET_COMPILER_FLAG("-U_FORTIFY_SOURCE" DEBUG RELWITHDEBINFO) # gcc 4.8.1 and new versions of clang MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=address -O1 -Wno-error -fPIC" DEBUG RELWITHDEBINFO) @@ -216,22 +218,22 @@ ENDIF() OPTION(WITH_UBSAN "Enable undefined behavior sanitizer" OFF) IF (WITH_UBSAN) - IF(SECURITY_HARDENED) - MESSAGE(FATAL_ERROR "WITH_UBSAN and SECURITY_HARDENED are mutually exclusive") - ENDIF() - MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=undefined" DEBUG RELWITHDEBINFO) + MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=undefined -U_FORTIFY_SOURCE" DEBUG RELWITHDEBINFO) ENDIF() # enable security hardening features, like most distributions do # in our benchmarks that costs about ~1% of performance, depending on the load -IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "4.6") +IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "4.6" OR WITH_ASAN OR WITH_UBSAN) SET(security_default OFF) ELSE() SET(security_default ON) ENDIF() OPTION(SECURITY_HARDENED "Use security-enhancing compiler features (stack protector, relro, etc)" ${security_default}) IF(SECURITY_HARDENED) + IF(WITH_ASAN OR WITH_UBSAN) + MESSAGE(FATAL_ERROR "WITH_ASAN/WITH_UBSAN and SECURITY_HARDENED are mutually exclusive") + ENDIF() # security-enhancing flags MY_CHECK_AND_SET_COMPILER_FLAG("-pie -fPIC") MY_CHECK_AND_SET_COMPILER_FLAG("-Wl,-z,relro,-z,now") From 6db2ebbb2a63994ef2b43d42a11dbacb8b55c207 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 9 Jun 2019 10:39:52 -0700 Subject: [PATCH 14/25] MDEV-19580 Unrelated JOINs corrupt usage of 'WHERE function() IN (subquery)' Handling of top level conjuncts in WHERE whose used_tables() contained RAND_TABLE_BIT in the function make_join_select() was incorrect. As a result if such a conjunct referred to fields non of which belonged to the last joined table it was pushed twice. (This could be seen for a test case from subselect.test whose output was changed after this patch had been applied. In 10.1 when running EXPLAIN FORMAT=JSON for the query from this test case we clearly see that one of the conjuncts is pushed twice.) This fact by itself was not good. Besides, if such a conjunct was pushed to a table that was the result of materialization of a semi-join the query could return a wrong result set. In particular we could watch it for queries with semi-join subqueries whose left parts used stored functions without "deterministic' specifier. --- mysql-test/r/subselect.result | 2 +- mysql-test/r/subselect_mat.result | 89 +++++++++++++++++++++++ mysql-test/r/subselect_no_mat.result | 2 +- mysql-test/r/subselect_no_opts.result | 2 +- mysql-test/r/subselect_no_scache.result | 2 +- mysql-test/r/subselect_no_semijoin.result | 2 +- mysql-test/r/subselect_sj_mat.result | 89 +++++++++++++++++++++++ mysql-test/t/subselect_sj_mat.test | 75 +++++++++++++++++++ sql/sql_select.cc | 87 ++++++++++++++++++---- 9 files changed, 331 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index cdedc02f825..2999f4cfc8f 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -6939,7 +6939,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where -1 PRIMARY t3 ref d d 5 test.t2.b 2 Using where; Using index +1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @tmp_mdev410=@@global.userstat; set global userstat=on; diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index efc348a26ce..0e10800331a 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -2453,6 +2453,95 @@ SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); 1 drop table t1,t2; drop view v1; +# +# MDEV-19580: function invocation in the left part of IN subquery +# +create table t1 (id int, a varchar(50), b int); +insert into t1 values +(1,'mrs',2), (2,'joe',2), (3,'paul',1), (4,'art',1); +create table t2 (id int, a varchar(50), x int); +insert into t2 values +(1,'grand',1),(2,'average',1),(3,'serf',0); +create table t3 (d1 date, d2 date, t1_id int, t2_id int ); +insert into t3 values +('1972-01-01','1988-12-31',3,1), ('1972-01-01','1988-12-31',4,1), +('1972-01-01','1988-12-31',1,2), ('1972-01-01','1988-12-31',2,3); +create table t4 ( id int, a varchar(50) ); +insert into t4 values +(1,'songwriter'),(2,'song character'); +create function f1(who int, dt date) returns int +deterministic +begin +declare result int; +select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who; +return result; +end$$ +create function f2(who int, dt date) returns int +begin +declare result int; +select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who; +return result; +end$$ +# Deterministic function in left part of IN subquery: semi-join is OK +select * from t1 +left join t4 on t1.b = t4.id +where f1(t1.id, '1980-01-01') in (select id from t2 where x=1); +id a b id a +3 paul 1 1 songwriter +4 art 1 1 songwriter +1 mrs 2 2 song character +explain extended select * from t1 +left join t4 on t1.b = t4.id +where f1(t1.id, '1980-01-01') in (select id from t2 where x=1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on((`test`.`t4`.`id` = `test`.`t1`.`b`)) where ((`test`.`t2`.`x` = 1) and (`f1`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`)) +# Non-deterministic function in left part of IN subq: semi-join is OK +select * from t1 +left join t4 on t1.b = t4.id +where f2(t1.id, '1980-01-01') in (select id from t2 where x=1); +id a b id a +3 paul 1 1 songwriter +4 art 1 1 songwriter +1 mrs 2 2 song character +explain extended select * from t1 +left join t4 on t1.b = t4.id +where f2(t1.id, '1980-01-01') in (select id from t2 where x=1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on((`test`.`t4`.`id` = `test`.`t1`.`b`)) where ((`test`.`t2`.`x` = 1) and (`f2`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`)) +select t1.*, t4.*, +(select max(t4.id) from t4 where t4.id=t1.b and sleep(0) = 0) as s +from t1 left join t4 on t1.b = t4.id +where f2(t1.id, '1980-01-01') in (select id from t2 where x=1); +id a b id a s +3 paul 1 1 songwriter 1 +4 art 1 1 songwriter 1 +1 mrs 2 2 song character 2 +explain extended select t1.*, t4.*, +(select max(t4.id) from t4 where t4.id=t1.b and sleep(0) = 0) as s +from t1 left join t4 on t1.b = t4.id +where f2(t1.id, '1980-01-01') in (select id from t2 where x=1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where +2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1276 Field or reference 'test.t1.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a`,(select max(`test`.`t4`.`id`) from `test`.`t4` where ((`test`.`t4`.`id` = `test`.`t1`.`b`) and (sleep(0) = 0))) AS `s` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on((`test`.`t4`.`id` = `test`.`t1`.`b`)) where ((`test`.`t2`.`x` = 1) and (`f2`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`)) +drop function f1; +drop function f2; +drop table t1,t2,t3,t4; # End of 5.5 tests set @subselect_mat_test_optimizer_switch_value=null; set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off'; diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index a7291297e7c..5c21e746b60 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -6937,7 +6937,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where -1 PRIMARY t3 ref d d 5 test.t2.b 2 Using where; Using index +1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @tmp_mdev410=@@global.userstat; set global userstat=on; diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index c41fa1be47b..8ab1f1bd3f9 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -6934,7 +6934,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where -1 PRIMARY t3 ref d d 5 test.t2.b 2 Using where; Using index +1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @tmp_mdev410=@@global.userstat; set global userstat=on; diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index 1c181357050..f0afa7ef19c 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -6945,7 +6945,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where -1 PRIMARY t3 ref d d 5 test.t2.b 2 Using where; Using index +1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @tmp_mdev410=@@global.userstat; set global userstat=on; diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index 89c671252ff..0d5fbc3498a 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -6934,7 +6934,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where -1 PRIMARY t3 ref d d 5 test.t2.b 2 Using where; Using index +1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @tmp_mdev410=@@global.userstat; set global userstat=on; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index fd9435e8a39..cb4b63047e5 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -2493,4 +2493,93 @@ SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); 1 drop table t1,t2; drop view v1; +# +# MDEV-19580: function invocation in the left part of IN subquery +# +create table t1 (id int, a varchar(50), b int); +insert into t1 values +(1,'mrs',2), (2,'joe',2), (3,'paul',1), (4,'art',1); +create table t2 (id int, a varchar(50), x int); +insert into t2 values +(1,'grand',1),(2,'average',1),(3,'serf',0); +create table t3 (d1 date, d2 date, t1_id int, t2_id int ); +insert into t3 values +('1972-01-01','1988-12-31',3,1), ('1972-01-01','1988-12-31',4,1), +('1972-01-01','1988-12-31',1,2), ('1972-01-01','1988-12-31',2,3); +create table t4 ( id int, a varchar(50) ); +insert into t4 values +(1,'songwriter'),(2,'song character'); +create function f1(who int, dt date) returns int +deterministic +begin +declare result int; +select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who; +return result; +end$$ +create function f2(who int, dt date) returns int +begin +declare result int; +select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who; +return result; +end$$ +# Deterministic function in left part of IN subquery: semi-join is OK +select * from t1 +left join t4 on t1.b = t4.id +where f1(t1.id, '1980-01-01') in (select id from t2 where x=1); +id a b id a +3 paul 1 1 songwriter +4 art 1 1 songwriter +1 mrs 2 2 song character +explain extended select * from t1 +left join t4 on t1.b = t4.id +where f1(t1.id, '1980-01-01') in (select id from t2 where x=1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on((`test`.`t4`.`id` = `test`.`t1`.`b`)) where ((`test`.`t2`.`x` = 1) and (`f1`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`)) +# Non-deterministic function in left part of IN subq: semi-join is OK +select * from t1 +left join t4 on t1.b = t4.id +where f2(t1.id, '1980-01-01') in (select id from t2 where x=1); +id a b id a +3 paul 1 1 songwriter +4 art 1 1 songwriter +1 mrs 2 2 song character +explain extended select * from t1 +left join t4 on t1.b = t4.id +where f2(t1.id, '1980-01-01') in (select id from t2 where x=1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on((`test`.`t4`.`id` = `test`.`t1`.`b`)) where ((`test`.`t2`.`x` = 1) and (`f2`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`)) +select t1.*, t4.*, +(select max(t4.id) from t4 where t4.id=t1.b and sleep(0) = 0) as s +from t1 left join t4 on t1.b = t4.id +where f2(t1.id, '1980-01-01') in (select id from t2 where x=1); +id a b id a s +3 paul 1 1 songwriter 1 +4 art 1 1 songwriter 1 +1 mrs 2 2 song character 2 +explain extended select t1.*, t4.*, +(select max(t4.id) from t4 where t4.id=t1.b and sleep(0) = 0) as s +from t1 left join t4 on t1.b = t4.id +where f2(t1.id, '1980-01-01') in (select id from t2 where x=1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where +2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1276 Field or reference 'test.t1.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a`,(select max(`test`.`t4`.`id`) from `test`.`t4` where ((`test`.`t4`.`id` = `test`.`t1`.`b`) and (sleep(0) = 0))) AS `s` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on((`test`.`t4`.`id` = `test`.`t1`.`b`)) where ((`test`.`t2`.`x` = 1) and (`f2`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`)) +drop function f1; +drop function f2; +drop table t1,t2,t3,t4; # End of 5.5 tests diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index c82c1e7acec..9c3788a1cd9 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -2230,4 +2230,79 @@ explain SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); drop table t1,t2; drop view v1; + + +--echo # +--echo # MDEV-19580: function invocation in the left part of IN subquery +--echo # + +create table t1 (id int, a varchar(50), b int); +insert into t1 values +(1,'mrs',2), (2,'joe',2), (3,'paul',1), (4,'art',1); + +create table t2 (id int, a varchar(50), x int); +insert into t2 values +(1,'grand',1),(2,'average',1),(3,'serf',0); + +create table t3 (d1 date, d2 date, t1_id int, t2_id int ); +insert into t3 values +('1972-01-01','1988-12-31',3,1), ('1972-01-01','1988-12-31',4,1), +('1972-01-01','1988-12-31',1,2), ('1972-01-01','1988-12-31',2,3); + +create table t4 ( id int, a varchar(50) ); +insert into t4 values +(1,'songwriter'),(2,'song character'); + +delimiter $$; + +create function f1(who int, dt date) returns int +deterministic +begin + declare result int; + select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who; + return result; +end$$ + +create function f2(who int, dt date) returns int +begin + declare result int; + select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who; + return result; +end$$ + +delimiter ;$$ + +--echo # Deterministic function in left part of IN subquery: semi-join is OK + +let $q1= +select * from t1 + left join t4 on t1.b = t4.id + where f1(t1.id, '1980-01-01') in (select id from t2 where x=1); + +eval $q1; +eval explain extended $q1; + +--echo # Non-deterministic function in left part of IN subq: semi-join is OK + +let $q2= +select * from t1 + left join t4 on t1.b = t4.id + where f2(t1.id, '1980-01-01') in (select id from t2 where x=1); + +eval $q2; +eval explain extended $q2; + +let $q3= +select t1.*, t4.*, + (select max(t4.id) from t4 where t4.id=t1.b and sleep(0) = 0) as s + from t1 left join t4 on t1.b = t4.id + where f2(t1.id, '1980-01-01') in (select id from t2 where x=1); + +eval $q3; +eval explain extended $q3; + +drop function f1; +drop function f2; +drop table t1,t2,t3,t4; + --echo # End of 5.5 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 37f8292b563..d7ff92a5100 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -204,7 +204,8 @@ static COND *make_cond_for_table_from_pred(THD *thd, Item *root_cond, table_map used_table, int join_tab_idx_arg, bool exclude_expensive_cond, - bool retain_ref_cond); + bool retain_ref_cond, + bool is_top_and_level); static Item* part_of_refkey(TABLE *form,Field *field); uint find_shortest_key(TABLE *table, const key_map *usable_keys); @@ -8922,12 +8923,6 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) RAND_TABLE_BIT; } - /* - Following force including random expression in last table condition. - It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5 - */ - if (tab == join->join_tab + last_top_base_tab_idx) - current_map|= RAND_TABLE_BIT; used_tables|=current_map; if (tab->type == JT_REF && tab->quick && @@ -8968,6 +8963,20 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { tmp= make_cond_for_table(thd, cond, used_tables, current_map, i, FALSE, FALSE); + if (tab == join->join_tab + last_top_base_tab_idx) + { + /* + This pushes conjunctive conditions of WHERE condition such that: + - their used_tables() contain RAND_TABLE_BIT + - the conditions does not refer to any fields + (such like rand() > 0.5) + */ + table_map rand_table_bit= (table_map) RAND_TABLE_BIT; + COND *rand_cond= make_cond_for_table(thd, cond, used_tables, + rand_table_bit, -1, + FALSE, FALSE); + add_cond_and_fix(thd, &tmp, rand_cond); + } } /* Add conditions added by add_not_null_conds(). */ if (tab->select_cond) @@ -9283,8 +9292,24 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) psergey: have put the -1 below. It's bad, will need to fix it. */ COND *tmp_cond= make_cond_for_table(thd, on_expr, used_tables2, - current_map, /*(tab - first_tab)*/ -1, - FALSE, FALSE); + current_map, + /*(tab - first_tab)*/ -1, + FALSE, FALSE); + if (tab == last_tab) + { + /* + This pushes conjunctive conditions of ON expression of an outer + join such that: + - their used_tables() contain RAND_TABLE_BIT + - the conditions does not refer to any fields + (such like rand() > 0.5) + */ + table_map rand_table_bit= (table_map) RAND_TABLE_BIT; + COND *rand_cond= make_cond_for_table(thd, on_expr, used_tables2, + rand_table_bit, -1, + FALSE, FALSE); + add_cond_and_fix(thd, &tmp_cond, rand_cond); + } bool is_sjm_lookup_tab= FALSE; if (tab->bush_children) { @@ -18824,7 +18849,7 @@ make_cond_for_table(THD *thd, Item *cond, table_map tables, return make_cond_for_table_from_pred(thd, cond, cond, tables, used_table, join_tab_idx_arg, exclude_expensive_cond, - retain_ref_cond); + retain_ref_cond, true); } @@ -18834,9 +18859,12 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond, int join_tab_idx_arg, bool exclude_expensive_cond __attribute__ ((unused)), - bool retain_ref_cond) + bool retain_ref_cond, + bool is_top_and_level) { + table_map rand_table_bit= (table_map) RAND_TABLE_BIT; + if (used_table && !(cond->used_tables() & used_table)) return (COND*) 0; // Already checked @@ -18852,11 +18880,28 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond, Item *item; while ((item=li++)) { + /* + Special handling of top level conjuncts with RAND_TABLE_BIT: + if such a conjunct contains a reference to a field that is not + an outer field then it is pushed to the corresponding table by + the same rule as all other conjuncts. Otherwise, if the conjunct + is used in WHERE is is pushed to the last joined table, if is it + is used in ON condition of an outer join it is pushed into the + last inner table of the outer join. Such conjuncts are pushed in + a call of make_cond_for_table_from_pred() with the + parameter 'used_table' equal to PSEUDO_TABLE_BITS. + */ + if (is_top_and_level && used_table == rand_table_bit && + (item->used_tables() & ~OUTER_REF_TABLE_BIT) != rand_table_bit) + { + /* The conjunct with RAND_TABLE_BIT has been allready pushed */ + continue; + } Item *fix=make_cond_for_table_from_pred(thd, root_cond, item, tables, used_table, - join_tab_idx_arg, + join_tab_idx_arg, exclude_expensive_cond, - retain_ref_cond); + retain_ref_cond, false); if (fix) new_cond->argument_list()->push_back(fix); } @@ -18880,6 +18925,13 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond, } else { // Or list + if (is_top_and_level && used_table == rand_table_bit && + (cond->used_tables() & ~OUTER_REF_TABLE_BIT) != rand_table_bit) + { + /* This top level formula with RAND_TABLE_BIT has been already pushed */ + return (COND*) 0; + } + Item_cond_or *new_cond=new Item_cond_or; if (!new_cond) return (COND*) 0; // OOM /* purecov: inspected */ @@ -18891,7 +18943,7 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond, tables, 0L, join_tab_idx_arg, exclude_expensive_cond, - retain_ref_cond); + retain_ref_cond, false); if (!fix) return (COND*) 0; // Always true new_cond->argument_list()->push_back(fix); @@ -18908,6 +18960,13 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond, } } + if (is_top_and_level && used_table == rand_table_bit && + (cond->used_tables() & ~OUTER_REF_TABLE_BIT) != rand_table_bit) + { + /* This top level formula with RAND_TABLE_BIT has been already pushed */ + return (COND*) 0; + } + /* Because the following test takes a while and it can be done table_count times, we mark each item that we have examined with the result From 96ee9ea02e69fb45f369815ace2187dd73398ac4 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 10 Jun 2019 22:38:55 -0700 Subject: [PATCH 15/25] MDEV-18479 Another complement This patch complements the patch that fixes bug MDEV-18479. This patch takes care of possible overflow in JOIN::get_examined_rows(). --- mysql-test/r/derived_view.result | 18 +++++++++--------- sql/sql_select.cc | 17 ++++++++++------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index d74b532d5e8..f8cf9190126 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -2942,15 +2942,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE ALL NULL NULL NULL NULL 50328437500000 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE ALL NULL NULL NULL NULL 27680640625000000 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 18446744073709551615 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 18446744073709551615 Using where; Using join buffer (incremental, BNL join) 17 DERIVED t2 system NULL NULL NULL NULL 1 17 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where 17 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d7ff92a5100..a273aae5425 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6894,17 +6894,22 @@ double JOIN::get_examined_rows() { ha_rows examined_rows; double prev_fanout= 1; + double records; JOIN_TAB *tab= first_breadth_first_tab(this, WALK_OPTIMIZATION_TABS); JOIN_TAB *prev_tab= tab; - examined_rows= tab->get_examined_rows(); + records= tab->get_examined_rows(); while ((tab= next_breadth_first_tab(this, WALK_OPTIMIZATION_TABS, tab))) { - prev_fanout *= prev_tab->records_read; - examined_rows+= (ha_rows) (tab->get_examined_rows() * prev_fanout); + prev_fanout= COST_MULT(prev_fanout, prev_tab->records_read); + records= + COST_ADD(records, + COST_MULT((double) (tab->get_examined_rows()), prev_fanout)); prev_tab= tab; } + examined_rows= + records > (double) HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records; return examined_rows; } @@ -10824,7 +10829,7 @@ ha_rows JOIN_TAB::get_examined_rows() } } else - examined_rows= (ha_rows) records_read; + examined_rows= records_read; return examined_rows; } @@ -22987,9 +22992,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, else { ha_rows examined_rows= tab->get_examined_rows(); - ha_rows displ_rows= examined_rows; - set_if_smaller(displ_rows, HA_ROWS_MAX/2); - item_list.push_back(new Item_int((longlong) (ulonglong) displ_rows, + item_list.push_back(new Item_int((ulonglong) examined_rows, MY_INT64_NUM_DECIMAL_DIGITS)); /* Add "filtered" field to item_list. */ From 7a7d9904e12335ee8b1eea9671138b3c469a3829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 11 Jun 2019 12:02:26 +0300 Subject: [PATCH 16/25] MDEV-18479: Avoid COST_MULT(records, 1) --- sql/sql_select.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a273aae5425..0d94ba2f293 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3856,11 +3856,8 @@ make_join_statistics(JOIN *join, List &tables_list, table/view. */ for (i= 0; i < join->table_count ; i++) - { - records= COST_MULT(records, - join->best_positions[i].records_read ? - join->best_positions[i].records_read : 1); - } + if (double rr= join->best_positions[i].records_read) + records= COST_MULT(records, rr); ha_rows rows= records > HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records; set_if_smaller(rows, unit->select_limit_cnt); join->select_lex->increase_derived_records(rows); From c5fe1b8fc1ba401791d0c0e0c38ec5082fa97891 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 12 Jun 2019 12:17:13 +0530 Subject: [PATCH 17/25] MDEV-16866 InnoDB fails to start upon crash recovery with "[ERROR] InnoDB: Redo log crypto: failed to decrypt log block" - If InnoDB encounters garbage or incomplete written log block during recovery then don't throw the error. Treat it as end of the log. - This kind of incomplete or empty block can be result of killing InnoDB when writing the redo log. --- storage/innobase/log/log0recv.cc | 38 +++++++++++++++---------------- storage/xtradb/log/log0recv.cc | 39 ++++++++++++++++---------------- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index a8a5f7b79e3..a86fd9fd8fd 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2631,30 +2631,30 @@ recv_scan_log_recs( fprintf(stderr, "Scanned lsn no %lu\n", log_block_convert_lsn_to_no(scanned_lsn)); */ - if (no != log_block_convert_lsn_to_no(scanned_lsn) - || !log_block_checksum_is_ok_or_old_format(log_block, true)) { + if (no != log_block_convert_lsn_to_no(scanned_lsn)) { + /* Garbage or an incompletely written log block. + We will not report any error; because this can happen + when InnoDB was killed while it was writing + redo log. We simply treat this as an abrupt end of the + redo log. */ + finished = true; + break; + } else if (!log_block_checksum_is_ok_or_old_format( + log_block, true)) { - if (no == log_block_convert_lsn_to_no(scanned_lsn) - && !log_block_checksum_is_ok_or_old_format( - log_block, true)) { - fprintf(stderr, - "InnoDB: Log block no %lu at" - " lsn " LSN_PF " has\n" - "InnoDB: ok header, but checksum field" - " contains %lu, should be %lu\n", - (ulong) no, - scanned_lsn, - (ulong) log_block_get_checksum( - log_block), - (ulong) log_block_calc_checksum( - log_block)); - } + fprintf(stderr, + "InnoDB: Log block no %lu at" + " lsn " LSN_PF " has\n" + "InnoDB: ok header, but checksum field" + " contains %lu, should be %lu\n", + (ulong) no, + scanned_lsn, + (ulong) log_block_get_checksum(log_block), + (ulong) log_block_calc_checksum(log_block)); maybe_encrypted = log_crypt_block_maybe_encrypted(log_block, &log_crypt_err); - /* Garbage or an incompletely written log block */ - /* Print checkpoint encryption keys if present */ log_crypt_print_checkpoint_keys(log_block); finished = TRUE; diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index 2f43a1a42a8..91a8424ebf1 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -2720,30 +2720,30 @@ recv_scan_log_recs( log_block_convert_lsn_to_no(scanned_lsn)); */ - if (no != log_block_convert_lsn_to_no(scanned_lsn) - || !log_block_checksum_is_ok_or_old_format(log_block, true)) { + if (no != log_block_convert_lsn_to_no(scanned_lsn)) { + /* Garbage or an incompletely written log block. + We will not report any error; because this can happen + when InnoDB was killed while it was writing + redo log. We simply treat this as an abrupt end of the + redo log. */ + finished = true; + break; + } else if (!log_block_checksum_is_ok_or_old_format( + log_block, true)) { - if (no == log_block_convert_lsn_to_no(scanned_lsn) - && !log_block_checksum_is_ok_or_old_format( - log_block, true)) { - fprintf(stderr, - "InnoDB: Log block no %lu at" - " lsn " LSN_PF " has\n" - "InnoDB: ok header, but checksum field" - " contains %lu, should be %lu\n", - (ulong) no, - scanned_lsn, - (ulong) log_block_get_checksum( - log_block), - (ulong) log_block_calc_checksum( - log_block)); - } + fprintf(stderr, + "InnoDB: Log block no %lu at" + " lsn " LSN_PF " has\n" + "InnoDB: ok header, but checksum field" + " contains %lu, should be %lu\n", + (ulong) no, + scanned_lsn, + (ulong) log_block_get_checksum(log_block), + (ulong) log_block_calc_checksum(log_block)); maybe_encrypted = log_crypt_block_maybe_encrypted(log_block, &log_crypt_err); - /* Garbage or an incompletely written log block */ - /* Print checkpoint encryption keys if present */ log_crypt_print_checkpoint_keys(log_block); finished = TRUE; @@ -2764,7 +2764,6 @@ recv_scan_log_recs( } break; - } if (log_block_get_flush_bit(log_block)) { From b2f76bac035b62899207d443c48da8cd614cd05b Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 12 Jun 2019 12:25:00 +0530 Subject: [PATCH 18/25] MDEV-16866 InnoDB fails to start upon crash recovery with "[ERROR] InnoDB: Redo log crypto: failed to decrypt log block" - Post-push fix to change the copyright of both xtradb and innodb file. --- storage/innobase/log/log0recv.cc | 2 +- storage/xtradb/log/log0recv.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index a86fd9fd8fd..d68f9236610 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2,7 +2,7 @@ Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2019, 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 diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index 91a8424ebf1..0bec6f9577d 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -2,7 +2,7 @@ Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2019, 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 From 9d886de499f54f2516be86a4f0f76ce57310cc2a Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 12 Jun 2019 13:09:41 +0400 Subject: [PATCH 19/25] MDEV-16467 - MariaDB crashes because of "long semaphore wait"after migrating from 10.1 to 10.3 This patch fixes 10.2 issue reported in MDEV-16467 by partial backport of c2118a0. Specifically "Remove not needed LOCK_thread_count from thd_get_error_context_description()". --- sql/sql_show.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4cc4c949118..71bfc644441 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -9839,8 +9839,6 @@ char *thd_get_error_context_description(THD *thd, char *buffer, char header[256]; int len; - mysql_mutex_lock(&LOCK_thread_count); - len= my_snprintf(header, sizeof(header), "MySQL thread id %lu, OS thread handle 0x%lx, query id %lu", thd->thread_id, (ulong) thd->real_id, (ulong) thd->query_id); @@ -9885,7 +9883,6 @@ char *thd_get_error_context_description(THD *thd, char *buffer, } mysql_mutex_unlock(&thd->LOCK_thd_data); } - mysql_mutex_unlock(&LOCK_thread_count); if (str.c_ptr_safe() == buffer) return buffer; From efc3cb9322df26e957f55dcd42f679251e273c68 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Wed, 12 Jun 2019 12:50:19 +0300 Subject: [PATCH 20/25] MDEV-19563 Removed references to deprecated option innodb_locks_unsafe_for_binlog innodb_locks_unsafe_for_binlog variabe removed from wsrep_info test configuration and recommendation to use this variable in README-wsrep was removed as well Also relates to issue: MDEV-19544 --- Docs/README-wsrep | 3 --- plugin/wsrep_info/mysql-test/wsrep_info/my.cnf | 1 - 2 files changed, 4 deletions(-) diff --git a/Docs/README-wsrep b/Docs/README-wsrep index 2058e1eb14d..542567e7592 100644 --- a/Docs/README-wsrep +++ b/Docs/README-wsrep @@ -269,9 +269,6 @@ innodb_autoinc_lock_mode=2 autoinc lock modes 0 and 1 can cause unresolved deadlock, and make the system unresponsive. -innodb_locks_unsafe_for_binlog=1 - This option is required for parallel applying. - 5.2 WSREP OPTIONS All options are optional except for wsrep_provider, wsrep_cluster_address, and diff --git a/plugin/wsrep_info/mysql-test/wsrep_info/my.cnf b/plugin/wsrep_info/mysql-test/wsrep_info/my.cnf index 70682178ca1..52c7789e9f7 100644 --- a/plugin/wsrep_info/mysql-test/wsrep_info/my.cnf +++ b/plugin/wsrep_info/mysql-test/wsrep_info/my.cnf @@ -5,7 +5,6 @@ wsrep-on=1 binlog-format=row innodb-autoinc-lock-mode=2 -innodb-locks-unsafe-for-binlog=1 wsrep-cluster-address=gcomm:// wsrep_provider=@ENV.WSREP_PROVIDER From 94e665596d13191da49c12469178a44d9ebae82a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 12 Jun 2019 16:17:23 +0300 Subject: [PATCH 21/25] MDEV-19740: Remove some broken InnoDB systemd code GCC 9.1.1 noticed that sd_notifyf() was always being invoked with str=NULL argument for "%s". This code was added in commit 2e814d4702d71a04388386a9f591d14a35980bfe but not mentioned in the commit comment. The STATUS messages for systemd matter during startup and shutdown, and should not be emitted during normal operation. ib_senderrf(): Remove the potentially harmful sd_notifyf() calls. --- storage/innobase/handler/ha_innodb.cc | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a511a3d175e..26a138046b4 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -21946,7 +21946,6 @@ ib_senderrf( ...) /*!< Args */ { va_list args; - char* str = NULL; const char* format = innobase_get_err_msg(code); /* If the caller wants to push a message to the client then @@ -21959,7 +21958,7 @@ ib_senderrf( va_start(args, code); - myf l = Sql_condition::WARN_LEVEL_NOTE; + myf l; switch (level) { case IB_LOG_LEVEL_INFO: @@ -21968,14 +21967,6 @@ ib_senderrf( case IB_LOG_LEVEL_WARN: l = ME_JUST_WARNING; break; - case IB_LOG_LEVEL_ERROR: - sd_notifyf(0, "STATUS=InnoDB: Error: %s", str); - l = 0; - break; - case IB_LOG_LEVEL_FATAL: - l = 0; - sd_notifyf(0, "STATUS=InnoDB: Fatal: %s", str); - break; default: l = 0; break; @@ -21984,7 +21975,6 @@ ib_senderrf( my_printv_error(code, format, MYF(l), args); va_end(args); - free(str); if (level == IB_LOG_LEVEL_FATAL) { ut_error; From 56c60b2fc5d006206f54b93be401570837f2f312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 12 Jun 2019 19:02:08 +0300 Subject: [PATCH 22/25] MDEV-16111 encryption.innodb_lotoftables failed in buildbot with wrong result Remove the test, because it easily fails with a result difference. Analysis by Thirunarayanan Balathandayuthapani: By default, innodb_encrypt_tables=0. 1) Test case creates 100 tables in innodb_encrypt_1. 2) creates another 100 unencrypted tables (encryption=off) in innodb_encrypt_2 3) creates another 100 encrypted tables (encryption=on) in innodb_encrypt_3 4) enabling innodb_encrypt_tables=1 and checking that only 100 encrypted tables exist. (already we have 100 in dictionary) 5) opening all tables again (no idea why) 6) After that, set innodb_encrypt_tables=0 and wait for 100 tables to be decrypted (already we have 100 unencrypted tables) 7) dropping all databases Sporadic failure happens because after step 4, it could encrypt the normal table too, because innodb_encryption_threads=4. This test was added in MDEV-9931, which was about InnoDB startup being slow due to all .ibd files being opened. There have been a number of later fixes to this problem. Currently the latest one is commit cad56fbabaea7b5dab0ccfbabb98d0a9c61f3dc3, in which some tests (in particular the test innodb.alter_kill) could fail if all InnoDB .ibd files are read during startup. That could make this test redundant. Let us remove the test, because it is big, slow, unreliable, and does not seem to reliably catch the problem that all files are being read on InnoDB startup. --- .../encryption/r/innodb_lotoftables.result | 1235 ----------------- .../suite/encryption/t/innodb_lotoftables.opt | 3 - .../encryption/t/innodb_lotoftables.test | 240 ---- mysql-test/unstable-tests | 1 - 4 files changed, 1479 deletions(-) delete mode 100644 mysql-test/suite/encryption/r/innodb_lotoftables.result delete mode 100644 mysql-test/suite/encryption/t/innodb_lotoftables.opt delete mode 100644 mysql-test/suite/encryption/t/innodb_lotoftables.test diff --git a/mysql-test/suite/encryption/r/innodb_lotoftables.result b/mysql-test/suite/encryption/r/innodb_lotoftables.result deleted file mode 100644 index c8b6e1a368e..00000000000 --- a/mysql-test/suite/encryption/r/innodb_lotoftables.result +++ /dev/null @@ -1,1235 +0,0 @@ -SET GLOBAL innodb_fast_shutdown=0; -SET GLOBAL innodb_file_format = `Barracuda`; -SET GLOBAL innodb_file_per_table = ON; -SHOW VARIABLES LIKE 'innodb_encrypt%'; -Variable_name Value -innodb_encrypt_log OFF -innodb_encrypt_tables OFF -innodb_encryption_rotate_key_age 1 -innodb_encryption_rotation_iops 100 -innodb_encryption_threads 0 -create database innodb_encrypted_1; -use innodb_encrypted_1; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -set autocommit=0; -set autocommit=1; -commit work; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -# should be empty -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE NAME LIKE 'innodb_encrypted%'; -NAME -create database innodb_encrypted_2; -use innodb_encrypted_2; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -set autocommit=0; -commit work; -set autocommit=1; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -# should contain 100 tables -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -innodb_encrypted_2/t_1 -innodb_encrypted_2/t_10 -innodb_encrypted_2/t_100 -innodb_encrypted_2/t_11 -innodb_encrypted_2/t_12 -innodb_encrypted_2/t_13 -innodb_encrypted_2/t_14 -innodb_encrypted_2/t_15 -innodb_encrypted_2/t_16 -innodb_encrypted_2/t_17 -innodb_encrypted_2/t_18 -innodb_encrypted_2/t_19 -innodb_encrypted_2/t_2 -innodb_encrypted_2/t_20 -innodb_encrypted_2/t_21 -innodb_encrypted_2/t_22 -innodb_encrypted_2/t_23 -innodb_encrypted_2/t_24 -innodb_encrypted_2/t_25 -innodb_encrypted_2/t_26 -innodb_encrypted_2/t_27 -innodb_encrypted_2/t_28 -innodb_encrypted_2/t_29 -innodb_encrypted_2/t_3 -innodb_encrypted_2/t_30 -innodb_encrypted_2/t_31 -innodb_encrypted_2/t_32 -innodb_encrypted_2/t_33 -innodb_encrypted_2/t_34 -innodb_encrypted_2/t_35 -innodb_encrypted_2/t_36 -innodb_encrypted_2/t_37 -innodb_encrypted_2/t_38 -innodb_encrypted_2/t_39 -innodb_encrypted_2/t_4 -innodb_encrypted_2/t_40 -innodb_encrypted_2/t_41 -innodb_encrypted_2/t_42 -innodb_encrypted_2/t_43 -innodb_encrypted_2/t_44 -innodb_encrypted_2/t_45 -innodb_encrypted_2/t_46 -innodb_encrypted_2/t_47 -innodb_encrypted_2/t_48 -innodb_encrypted_2/t_49 -innodb_encrypted_2/t_5 -innodb_encrypted_2/t_50 -innodb_encrypted_2/t_51 -innodb_encrypted_2/t_52 -innodb_encrypted_2/t_53 -innodb_encrypted_2/t_54 -innodb_encrypted_2/t_55 -innodb_encrypted_2/t_56 -innodb_encrypted_2/t_57 -innodb_encrypted_2/t_58 -innodb_encrypted_2/t_59 -innodb_encrypted_2/t_6 -innodb_encrypted_2/t_60 -innodb_encrypted_2/t_61 -innodb_encrypted_2/t_62 -innodb_encrypted_2/t_63 -innodb_encrypted_2/t_64 -innodb_encrypted_2/t_65 -innodb_encrypted_2/t_66 -innodb_encrypted_2/t_67 -innodb_encrypted_2/t_68 -innodb_encrypted_2/t_69 -innodb_encrypted_2/t_7 -innodb_encrypted_2/t_70 -innodb_encrypted_2/t_71 -innodb_encrypted_2/t_72 -innodb_encrypted_2/t_73 -innodb_encrypted_2/t_74 -innodb_encrypted_2/t_75 -innodb_encrypted_2/t_76 -innodb_encrypted_2/t_77 -innodb_encrypted_2/t_78 -innodb_encrypted_2/t_79 -innodb_encrypted_2/t_8 -innodb_encrypted_2/t_80 -innodb_encrypted_2/t_81 -innodb_encrypted_2/t_82 -innodb_encrypted_2/t_83 -innodb_encrypted_2/t_84 -innodb_encrypted_2/t_85 -innodb_encrypted_2/t_86 -innodb_encrypted_2/t_87 -innodb_encrypted_2/t_88 -innodb_encrypted_2/t_89 -innodb_encrypted_2/t_9 -innodb_encrypted_2/t_90 -innodb_encrypted_2/t_91 -innodb_encrypted_2/t_92 -innodb_encrypted_2/t_93 -innodb_encrypted_2/t_94 -innodb_encrypted_2/t_95 -innodb_encrypted_2/t_96 -innodb_encrypted_2/t_97 -innodb_encrypted_2/t_98 -innodb_encrypted_2/t_99 -# should contain 0 tables -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -create database innodb_encrypted_3; -use innodb_encrypted_3; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -set autocommit=0; -commit work; -set autocommit=1; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -# should contain 100 tables -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -innodb_encrypted_2/t_1 -innodb_encrypted_2/t_10 -innodb_encrypted_2/t_100 -innodb_encrypted_2/t_11 -innodb_encrypted_2/t_12 -innodb_encrypted_2/t_13 -innodb_encrypted_2/t_14 -innodb_encrypted_2/t_15 -innodb_encrypted_2/t_16 -innodb_encrypted_2/t_17 -innodb_encrypted_2/t_18 -innodb_encrypted_2/t_19 -innodb_encrypted_2/t_2 -innodb_encrypted_2/t_20 -innodb_encrypted_2/t_21 -innodb_encrypted_2/t_22 -innodb_encrypted_2/t_23 -innodb_encrypted_2/t_24 -innodb_encrypted_2/t_25 -innodb_encrypted_2/t_26 -innodb_encrypted_2/t_27 -innodb_encrypted_2/t_28 -innodb_encrypted_2/t_29 -innodb_encrypted_2/t_3 -innodb_encrypted_2/t_30 -innodb_encrypted_2/t_31 -innodb_encrypted_2/t_32 -innodb_encrypted_2/t_33 -innodb_encrypted_2/t_34 -innodb_encrypted_2/t_35 -innodb_encrypted_2/t_36 -innodb_encrypted_2/t_37 -innodb_encrypted_2/t_38 -innodb_encrypted_2/t_39 -innodb_encrypted_2/t_4 -innodb_encrypted_2/t_40 -innodb_encrypted_2/t_41 -innodb_encrypted_2/t_42 -innodb_encrypted_2/t_43 -innodb_encrypted_2/t_44 -innodb_encrypted_2/t_45 -innodb_encrypted_2/t_46 -innodb_encrypted_2/t_47 -innodb_encrypted_2/t_48 -innodb_encrypted_2/t_49 -innodb_encrypted_2/t_5 -innodb_encrypted_2/t_50 -innodb_encrypted_2/t_51 -innodb_encrypted_2/t_52 -innodb_encrypted_2/t_53 -innodb_encrypted_2/t_54 -innodb_encrypted_2/t_55 -innodb_encrypted_2/t_56 -innodb_encrypted_2/t_57 -innodb_encrypted_2/t_58 -innodb_encrypted_2/t_59 -innodb_encrypted_2/t_6 -innodb_encrypted_2/t_60 -innodb_encrypted_2/t_61 -innodb_encrypted_2/t_62 -innodb_encrypted_2/t_63 -innodb_encrypted_2/t_64 -innodb_encrypted_2/t_65 -innodb_encrypted_2/t_66 -innodb_encrypted_2/t_67 -innodb_encrypted_2/t_68 -innodb_encrypted_2/t_69 -innodb_encrypted_2/t_7 -innodb_encrypted_2/t_70 -innodb_encrypted_2/t_71 -innodb_encrypted_2/t_72 -innodb_encrypted_2/t_73 -innodb_encrypted_2/t_74 -innodb_encrypted_2/t_75 -innodb_encrypted_2/t_76 -innodb_encrypted_2/t_77 -innodb_encrypted_2/t_78 -innodb_encrypted_2/t_79 -innodb_encrypted_2/t_8 -innodb_encrypted_2/t_80 -innodb_encrypted_2/t_81 -innodb_encrypted_2/t_82 -innodb_encrypted_2/t_83 -innodb_encrypted_2/t_84 -innodb_encrypted_2/t_85 -innodb_encrypted_2/t_86 -innodb_encrypted_2/t_87 -innodb_encrypted_2/t_88 -innodb_encrypted_2/t_89 -innodb_encrypted_2/t_9 -innodb_encrypted_2/t_90 -innodb_encrypted_2/t_91 -innodb_encrypted_2/t_92 -innodb_encrypted_2/t_93 -innodb_encrypted_2/t_94 -innodb_encrypted_2/t_95 -innodb_encrypted_2/t_96 -innodb_encrypted_2/t_97 -innodb_encrypted_2/t_98 -innodb_encrypted_2/t_99 -# should contain 100 tables -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -innodb_encrypted_3/t_1 -innodb_encrypted_3/t_10 -innodb_encrypted_3/t_100 -innodb_encrypted_3/t_11 -innodb_encrypted_3/t_12 -innodb_encrypted_3/t_13 -innodb_encrypted_3/t_14 -innodb_encrypted_3/t_15 -innodb_encrypted_3/t_16 -innodb_encrypted_3/t_17 -innodb_encrypted_3/t_18 -innodb_encrypted_3/t_19 -innodb_encrypted_3/t_2 -innodb_encrypted_3/t_20 -innodb_encrypted_3/t_21 -innodb_encrypted_3/t_22 -innodb_encrypted_3/t_23 -innodb_encrypted_3/t_24 -innodb_encrypted_3/t_25 -innodb_encrypted_3/t_26 -innodb_encrypted_3/t_27 -innodb_encrypted_3/t_28 -innodb_encrypted_3/t_29 -innodb_encrypted_3/t_3 -innodb_encrypted_3/t_30 -innodb_encrypted_3/t_31 -innodb_encrypted_3/t_32 -innodb_encrypted_3/t_33 -innodb_encrypted_3/t_34 -innodb_encrypted_3/t_35 -innodb_encrypted_3/t_36 -innodb_encrypted_3/t_37 -innodb_encrypted_3/t_38 -innodb_encrypted_3/t_39 -innodb_encrypted_3/t_4 -innodb_encrypted_3/t_40 -innodb_encrypted_3/t_41 -innodb_encrypted_3/t_42 -innodb_encrypted_3/t_43 -innodb_encrypted_3/t_44 -innodb_encrypted_3/t_45 -innodb_encrypted_3/t_46 -innodb_encrypted_3/t_47 -innodb_encrypted_3/t_48 -innodb_encrypted_3/t_49 -innodb_encrypted_3/t_5 -innodb_encrypted_3/t_50 -innodb_encrypted_3/t_51 -innodb_encrypted_3/t_52 -innodb_encrypted_3/t_53 -innodb_encrypted_3/t_54 -innodb_encrypted_3/t_55 -innodb_encrypted_3/t_56 -innodb_encrypted_3/t_57 -innodb_encrypted_3/t_58 -innodb_encrypted_3/t_59 -innodb_encrypted_3/t_6 -innodb_encrypted_3/t_60 -innodb_encrypted_3/t_61 -innodb_encrypted_3/t_62 -innodb_encrypted_3/t_63 -innodb_encrypted_3/t_64 -innodb_encrypted_3/t_65 -innodb_encrypted_3/t_66 -innodb_encrypted_3/t_67 -innodb_encrypted_3/t_68 -innodb_encrypted_3/t_69 -innodb_encrypted_3/t_7 -innodb_encrypted_3/t_70 -innodb_encrypted_3/t_71 -innodb_encrypted_3/t_72 -innodb_encrypted_3/t_73 -innodb_encrypted_3/t_74 -innodb_encrypted_3/t_75 -innodb_encrypted_3/t_76 -innodb_encrypted_3/t_77 -innodb_encrypted_3/t_78 -innodb_encrypted_3/t_79 -innodb_encrypted_3/t_8 -innodb_encrypted_3/t_80 -innodb_encrypted_3/t_81 -innodb_encrypted_3/t_82 -innodb_encrypted_3/t_83 -innodb_encrypted_3/t_84 -innodb_encrypted_3/t_85 -innodb_encrypted_3/t_86 -innodb_encrypted_3/t_87 -innodb_encrypted_3/t_88 -innodb_encrypted_3/t_89 -innodb_encrypted_3/t_9 -innodb_encrypted_3/t_90 -innodb_encrypted_3/t_91 -innodb_encrypted_3/t_92 -innodb_encrypted_3/t_93 -innodb_encrypted_3/t_94 -innodb_encrypted_3/t_95 -innodb_encrypted_3/t_96 -innodb_encrypted_3/t_97 -innodb_encrypted_3/t_98 -innodb_encrypted_3/t_99 -use test; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -innodb_encrypted_2/t_1 -innodb_encrypted_2/t_10 -innodb_encrypted_2/t_100 -innodb_encrypted_2/t_11 -innodb_encrypted_2/t_12 -innodb_encrypted_2/t_13 -innodb_encrypted_2/t_14 -innodb_encrypted_2/t_15 -innodb_encrypted_2/t_16 -innodb_encrypted_2/t_17 -innodb_encrypted_2/t_18 -innodb_encrypted_2/t_19 -innodb_encrypted_2/t_2 -innodb_encrypted_2/t_20 -innodb_encrypted_2/t_21 -innodb_encrypted_2/t_22 -innodb_encrypted_2/t_23 -innodb_encrypted_2/t_24 -innodb_encrypted_2/t_25 -innodb_encrypted_2/t_26 -innodb_encrypted_2/t_27 -innodb_encrypted_2/t_28 -innodb_encrypted_2/t_29 -innodb_encrypted_2/t_3 -innodb_encrypted_2/t_30 -innodb_encrypted_2/t_31 -innodb_encrypted_2/t_32 -innodb_encrypted_2/t_33 -innodb_encrypted_2/t_34 -innodb_encrypted_2/t_35 -innodb_encrypted_2/t_36 -innodb_encrypted_2/t_37 -innodb_encrypted_2/t_38 -innodb_encrypted_2/t_39 -innodb_encrypted_2/t_4 -innodb_encrypted_2/t_40 -innodb_encrypted_2/t_41 -innodb_encrypted_2/t_42 -innodb_encrypted_2/t_43 -innodb_encrypted_2/t_44 -innodb_encrypted_2/t_45 -innodb_encrypted_2/t_46 -innodb_encrypted_2/t_47 -innodb_encrypted_2/t_48 -innodb_encrypted_2/t_49 -innodb_encrypted_2/t_5 -innodb_encrypted_2/t_50 -innodb_encrypted_2/t_51 -innodb_encrypted_2/t_52 -innodb_encrypted_2/t_53 -innodb_encrypted_2/t_54 -innodb_encrypted_2/t_55 -innodb_encrypted_2/t_56 -innodb_encrypted_2/t_57 -innodb_encrypted_2/t_58 -innodb_encrypted_2/t_59 -innodb_encrypted_2/t_6 -innodb_encrypted_2/t_60 -innodb_encrypted_2/t_61 -innodb_encrypted_2/t_62 -innodb_encrypted_2/t_63 -innodb_encrypted_2/t_64 -innodb_encrypted_2/t_65 -innodb_encrypted_2/t_66 -innodb_encrypted_2/t_67 -innodb_encrypted_2/t_68 -innodb_encrypted_2/t_69 -innodb_encrypted_2/t_7 -innodb_encrypted_2/t_70 -innodb_encrypted_2/t_71 -innodb_encrypted_2/t_72 -innodb_encrypted_2/t_73 -innodb_encrypted_2/t_74 -innodb_encrypted_2/t_75 -innodb_encrypted_2/t_76 -innodb_encrypted_2/t_77 -innodb_encrypted_2/t_78 -innodb_encrypted_2/t_79 -innodb_encrypted_2/t_8 -innodb_encrypted_2/t_80 -innodb_encrypted_2/t_81 -innodb_encrypted_2/t_82 -innodb_encrypted_2/t_83 -innodb_encrypted_2/t_84 -innodb_encrypted_2/t_85 -innodb_encrypted_2/t_86 -innodb_encrypted_2/t_87 -innodb_encrypted_2/t_88 -innodb_encrypted_2/t_89 -innodb_encrypted_2/t_9 -innodb_encrypted_2/t_90 -innodb_encrypted_2/t_91 -innodb_encrypted_2/t_92 -innodb_encrypted_2/t_93 -innodb_encrypted_2/t_94 -innodb_encrypted_2/t_95 -innodb_encrypted_2/t_96 -innodb_encrypted_2/t_97 -innodb_encrypted_2/t_98 -innodb_encrypted_2/t_99 -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -innodb_encrypted_3/t_1 -innodb_encrypted_3/t_10 -innodb_encrypted_3/t_100 -innodb_encrypted_3/t_11 -innodb_encrypted_3/t_12 -innodb_encrypted_3/t_13 -innodb_encrypted_3/t_14 -innodb_encrypted_3/t_15 -innodb_encrypted_3/t_16 -innodb_encrypted_3/t_17 -innodb_encrypted_3/t_18 -innodb_encrypted_3/t_19 -innodb_encrypted_3/t_2 -innodb_encrypted_3/t_20 -innodb_encrypted_3/t_21 -innodb_encrypted_3/t_22 -innodb_encrypted_3/t_23 -innodb_encrypted_3/t_24 -innodb_encrypted_3/t_25 -innodb_encrypted_3/t_26 -innodb_encrypted_3/t_27 -innodb_encrypted_3/t_28 -innodb_encrypted_3/t_29 -innodb_encrypted_3/t_3 -innodb_encrypted_3/t_30 -innodb_encrypted_3/t_31 -innodb_encrypted_3/t_32 -innodb_encrypted_3/t_33 -innodb_encrypted_3/t_34 -innodb_encrypted_3/t_35 -innodb_encrypted_3/t_36 -innodb_encrypted_3/t_37 -innodb_encrypted_3/t_38 -innodb_encrypted_3/t_39 -innodb_encrypted_3/t_4 -innodb_encrypted_3/t_40 -innodb_encrypted_3/t_41 -innodb_encrypted_3/t_42 -innodb_encrypted_3/t_43 -innodb_encrypted_3/t_44 -innodb_encrypted_3/t_45 -innodb_encrypted_3/t_46 -innodb_encrypted_3/t_47 -innodb_encrypted_3/t_48 -innodb_encrypted_3/t_49 -innodb_encrypted_3/t_5 -innodb_encrypted_3/t_50 -innodb_encrypted_3/t_51 -innodb_encrypted_3/t_52 -innodb_encrypted_3/t_53 -innodb_encrypted_3/t_54 -innodb_encrypted_3/t_55 -innodb_encrypted_3/t_56 -innodb_encrypted_3/t_57 -innodb_encrypted_3/t_58 -innodb_encrypted_3/t_59 -innodb_encrypted_3/t_6 -innodb_encrypted_3/t_60 -innodb_encrypted_3/t_61 -innodb_encrypted_3/t_62 -innodb_encrypted_3/t_63 -innodb_encrypted_3/t_64 -innodb_encrypted_3/t_65 -innodb_encrypted_3/t_66 -innodb_encrypted_3/t_67 -innodb_encrypted_3/t_68 -innodb_encrypted_3/t_69 -innodb_encrypted_3/t_7 -innodb_encrypted_3/t_70 -innodb_encrypted_3/t_71 -innodb_encrypted_3/t_72 -innodb_encrypted_3/t_73 -innodb_encrypted_3/t_74 -innodb_encrypted_3/t_75 -innodb_encrypted_3/t_76 -innodb_encrypted_3/t_77 -innodb_encrypted_3/t_78 -innodb_encrypted_3/t_79 -innodb_encrypted_3/t_8 -innodb_encrypted_3/t_80 -innodb_encrypted_3/t_81 -innodb_encrypted_3/t_82 -innodb_encrypted_3/t_83 -innodb_encrypted_3/t_84 -innodb_encrypted_3/t_85 -innodb_encrypted_3/t_86 -innodb_encrypted_3/t_87 -innodb_encrypted_3/t_88 -innodb_encrypted_3/t_89 -innodb_encrypted_3/t_9 -innodb_encrypted_3/t_90 -innodb_encrypted_3/t_91 -innodb_encrypted_3/t_92 -innodb_encrypted_3/t_93 -innodb_encrypted_3/t_94 -innodb_encrypted_3/t_95 -innodb_encrypted_3/t_96 -innodb_encrypted_3/t_97 -innodb_encrypted_3/t_98 -innodb_encrypted_3/t_99 -SET GLOBAL innodb_encrypt_tables = on; -SET GLOBAL innodb_encryption_threads=4; -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -innodb_encrypted_2/t_1 -innodb_encrypted_2/t_10 -innodb_encrypted_2/t_100 -innodb_encrypted_2/t_11 -innodb_encrypted_2/t_12 -innodb_encrypted_2/t_13 -innodb_encrypted_2/t_14 -innodb_encrypted_2/t_15 -innodb_encrypted_2/t_16 -innodb_encrypted_2/t_17 -innodb_encrypted_2/t_18 -innodb_encrypted_2/t_19 -innodb_encrypted_2/t_2 -innodb_encrypted_2/t_20 -innodb_encrypted_2/t_21 -innodb_encrypted_2/t_22 -innodb_encrypted_2/t_23 -innodb_encrypted_2/t_24 -innodb_encrypted_2/t_25 -innodb_encrypted_2/t_26 -innodb_encrypted_2/t_27 -innodb_encrypted_2/t_28 -innodb_encrypted_2/t_29 -innodb_encrypted_2/t_3 -innodb_encrypted_2/t_30 -innodb_encrypted_2/t_31 -innodb_encrypted_2/t_32 -innodb_encrypted_2/t_33 -innodb_encrypted_2/t_34 -innodb_encrypted_2/t_35 -innodb_encrypted_2/t_36 -innodb_encrypted_2/t_37 -innodb_encrypted_2/t_38 -innodb_encrypted_2/t_39 -innodb_encrypted_2/t_4 -innodb_encrypted_2/t_40 -innodb_encrypted_2/t_41 -innodb_encrypted_2/t_42 -innodb_encrypted_2/t_43 -innodb_encrypted_2/t_44 -innodb_encrypted_2/t_45 -innodb_encrypted_2/t_46 -innodb_encrypted_2/t_47 -innodb_encrypted_2/t_48 -innodb_encrypted_2/t_49 -innodb_encrypted_2/t_5 -innodb_encrypted_2/t_50 -innodb_encrypted_2/t_51 -innodb_encrypted_2/t_52 -innodb_encrypted_2/t_53 -innodb_encrypted_2/t_54 -innodb_encrypted_2/t_55 -innodb_encrypted_2/t_56 -innodb_encrypted_2/t_57 -innodb_encrypted_2/t_58 -innodb_encrypted_2/t_59 -innodb_encrypted_2/t_6 -innodb_encrypted_2/t_60 -innodb_encrypted_2/t_61 -innodb_encrypted_2/t_62 -innodb_encrypted_2/t_63 -innodb_encrypted_2/t_64 -innodb_encrypted_2/t_65 -innodb_encrypted_2/t_66 -innodb_encrypted_2/t_67 -innodb_encrypted_2/t_68 -innodb_encrypted_2/t_69 -innodb_encrypted_2/t_7 -innodb_encrypted_2/t_70 -innodb_encrypted_2/t_71 -innodb_encrypted_2/t_72 -innodb_encrypted_2/t_73 -innodb_encrypted_2/t_74 -innodb_encrypted_2/t_75 -innodb_encrypted_2/t_76 -innodb_encrypted_2/t_77 -innodb_encrypted_2/t_78 -innodb_encrypted_2/t_79 -innodb_encrypted_2/t_8 -innodb_encrypted_2/t_80 -innodb_encrypted_2/t_81 -innodb_encrypted_2/t_82 -innodb_encrypted_2/t_83 -innodb_encrypted_2/t_84 -innodb_encrypted_2/t_85 -innodb_encrypted_2/t_86 -innodb_encrypted_2/t_87 -innodb_encrypted_2/t_88 -innodb_encrypted_2/t_89 -innodb_encrypted_2/t_9 -innodb_encrypted_2/t_90 -innodb_encrypted_2/t_91 -innodb_encrypted_2/t_92 -innodb_encrypted_2/t_93 -innodb_encrypted_2/t_94 -innodb_encrypted_2/t_95 -innodb_encrypted_2/t_96 -innodb_encrypted_2/t_97 -innodb_encrypted_2/t_98 -innodb_encrypted_2/t_99 -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -innodb_encrypted_3/t_1 -innodb_encrypted_3/t_10 -innodb_encrypted_3/t_100 -innodb_encrypted_3/t_11 -innodb_encrypted_3/t_12 -innodb_encrypted_3/t_13 -innodb_encrypted_3/t_14 -innodb_encrypted_3/t_15 -innodb_encrypted_3/t_16 -innodb_encrypted_3/t_17 -innodb_encrypted_3/t_18 -innodb_encrypted_3/t_19 -innodb_encrypted_3/t_2 -innodb_encrypted_3/t_20 -innodb_encrypted_3/t_21 -innodb_encrypted_3/t_22 -innodb_encrypted_3/t_23 -innodb_encrypted_3/t_24 -innodb_encrypted_3/t_25 -innodb_encrypted_3/t_26 -innodb_encrypted_3/t_27 -innodb_encrypted_3/t_28 -innodb_encrypted_3/t_29 -innodb_encrypted_3/t_3 -innodb_encrypted_3/t_30 -innodb_encrypted_3/t_31 -innodb_encrypted_3/t_32 -innodb_encrypted_3/t_33 -innodb_encrypted_3/t_34 -innodb_encrypted_3/t_35 -innodb_encrypted_3/t_36 -innodb_encrypted_3/t_37 -innodb_encrypted_3/t_38 -innodb_encrypted_3/t_39 -innodb_encrypted_3/t_4 -innodb_encrypted_3/t_40 -innodb_encrypted_3/t_41 -innodb_encrypted_3/t_42 -innodb_encrypted_3/t_43 -innodb_encrypted_3/t_44 -innodb_encrypted_3/t_45 -innodb_encrypted_3/t_46 -innodb_encrypted_3/t_47 -innodb_encrypted_3/t_48 -innodb_encrypted_3/t_49 -innodb_encrypted_3/t_5 -innodb_encrypted_3/t_50 -innodb_encrypted_3/t_51 -innodb_encrypted_3/t_52 -innodb_encrypted_3/t_53 -innodb_encrypted_3/t_54 -innodb_encrypted_3/t_55 -innodb_encrypted_3/t_56 -innodb_encrypted_3/t_57 -innodb_encrypted_3/t_58 -innodb_encrypted_3/t_59 -innodb_encrypted_3/t_6 -innodb_encrypted_3/t_60 -innodb_encrypted_3/t_61 -innodb_encrypted_3/t_62 -innodb_encrypted_3/t_63 -innodb_encrypted_3/t_64 -innodb_encrypted_3/t_65 -innodb_encrypted_3/t_66 -innodb_encrypted_3/t_67 -innodb_encrypted_3/t_68 -innodb_encrypted_3/t_69 -innodb_encrypted_3/t_7 -innodb_encrypted_3/t_70 -innodb_encrypted_3/t_71 -innodb_encrypted_3/t_72 -innodb_encrypted_3/t_73 -innodb_encrypted_3/t_74 -innodb_encrypted_3/t_75 -innodb_encrypted_3/t_76 -innodb_encrypted_3/t_77 -innodb_encrypted_3/t_78 -innodb_encrypted_3/t_79 -innodb_encrypted_3/t_8 -innodb_encrypted_3/t_80 -innodb_encrypted_3/t_81 -innodb_encrypted_3/t_82 -innodb_encrypted_3/t_83 -innodb_encrypted_3/t_84 -innodb_encrypted_3/t_85 -innodb_encrypted_3/t_86 -innodb_encrypted_3/t_87 -innodb_encrypted_3/t_88 -innodb_encrypted_3/t_89 -innodb_encrypted_3/t_9 -innodb_encrypted_3/t_90 -innodb_encrypted_3/t_91 -innodb_encrypted_3/t_92 -innodb_encrypted_3/t_93 -innodb_encrypted_3/t_94 -innodb_encrypted_3/t_95 -innodb_encrypted_3/t_96 -innodb_encrypted_3/t_97 -innodb_encrypted_3/t_98 -innodb_encrypted_3/t_99 -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -# Success! -# Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 -# Restart Success! -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -use test; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -use innodb_encrypted_1; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -use innodb_encrypted_2; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -use innodb_encrypted_3; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -use innodb_encrypted_1; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 3 -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 103 -use innodb_encrypted_2; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 103 -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 203 -use innodb_encrypted_3; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 203 -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 303 -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -innodb_encrypted_3/t_1 -innodb_encrypted_3/t_10 -innodb_encrypted_3/t_100 -innodb_encrypted_3/t_11 -innodb_encrypted_3/t_12 -innodb_encrypted_3/t_13 -innodb_encrypted_3/t_14 -innodb_encrypted_3/t_15 -innodb_encrypted_3/t_16 -innodb_encrypted_3/t_17 -innodb_encrypted_3/t_18 -innodb_encrypted_3/t_19 -innodb_encrypted_3/t_2 -innodb_encrypted_3/t_20 -innodb_encrypted_3/t_21 -innodb_encrypted_3/t_22 -innodb_encrypted_3/t_23 -innodb_encrypted_3/t_24 -innodb_encrypted_3/t_25 -innodb_encrypted_3/t_26 -innodb_encrypted_3/t_27 -innodb_encrypted_3/t_28 -innodb_encrypted_3/t_29 -innodb_encrypted_3/t_3 -innodb_encrypted_3/t_30 -innodb_encrypted_3/t_31 -innodb_encrypted_3/t_32 -innodb_encrypted_3/t_33 -innodb_encrypted_3/t_34 -innodb_encrypted_3/t_35 -innodb_encrypted_3/t_36 -innodb_encrypted_3/t_37 -innodb_encrypted_3/t_38 -innodb_encrypted_3/t_39 -innodb_encrypted_3/t_4 -innodb_encrypted_3/t_40 -innodb_encrypted_3/t_41 -innodb_encrypted_3/t_42 -innodb_encrypted_3/t_43 -innodb_encrypted_3/t_44 -innodb_encrypted_3/t_45 -innodb_encrypted_3/t_46 -innodb_encrypted_3/t_47 -innodb_encrypted_3/t_48 -innodb_encrypted_3/t_49 -innodb_encrypted_3/t_5 -innodb_encrypted_3/t_50 -innodb_encrypted_3/t_51 -innodb_encrypted_3/t_52 -innodb_encrypted_3/t_53 -innodb_encrypted_3/t_54 -innodb_encrypted_3/t_55 -innodb_encrypted_3/t_56 -innodb_encrypted_3/t_57 -innodb_encrypted_3/t_58 -innodb_encrypted_3/t_59 -innodb_encrypted_3/t_6 -innodb_encrypted_3/t_60 -innodb_encrypted_3/t_61 -innodb_encrypted_3/t_62 -innodb_encrypted_3/t_63 -innodb_encrypted_3/t_64 -innodb_encrypted_3/t_65 -innodb_encrypted_3/t_66 -innodb_encrypted_3/t_67 -innodb_encrypted_3/t_68 -innodb_encrypted_3/t_69 -innodb_encrypted_3/t_7 -innodb_encrypted_3/t_70 -innodb_encrypted_3/t_71 -innodb_encrypted_3/t_72 -innodb_encrypted_3/t_73 -innodb_encrypted_3/t_74 -innodb_encrypted_3/t_75 -innodb_encrypted_3/t_76 -innodb_encrypted_3/t_77 -innodb_encrypted_3/t_78 -innodb_encrypted_3/t_79 -innodb_encrypted_3/t_8 -innodb_encrypted_3/t_80 -innodb_encrypted_3/t_81 -innodb_encrypted_3/t_82 -innodb_encrypted_3/t_83 -innodb_encrypted_3/t_84 -innodb_encrypted_3/t_85 -innodb_encrypted_3/t_86 -innodb_encrypted_3/t_87 -innodb_encrypted_3/t_88 -innodb_encrypted_3/t_89 -innodb_encrypted_3/t_9 -innodb_encrypted_3/t_90 -innodb_encrypted_3/t_91 -innodb_encrypted_3/t_92 -innodb_encrypted_3/t_93 -innodb_encrypted_3/t_94 -innodb_encrypted_3/t_95 -innodb_encrypted_3/t_96 -innodb_encrypted_3/t_97 -innodb_encrypted_3/t_98 -innodb_encrypted_3/t_99 -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -innodb_encrypted_2/t_1 -innodb_encrypted_2/t_10 -innodb_encrypted_2/t_100 -innodb_encrypted_2/t_11 -innodb_encrypted_2/t_12 -innodb_encrypted_2/t_13 -innodb_encrypted_2/t_14 -innodb_encrypted_2/t_15 -innodb_encrypted_2/t_16 -innodb_encrypted_2/t_17 -innodb_encrypted_2/t_18 -innodb_encrypted_2/t_19 -innodb_encrypted_2/t_2 -innodb_encrypted_2/t_20 -innodb_encrypted_2/t_21 -innodb_encrypted_2/t_22 -innodb_encrypted_2/t_23 -innodb_encrypted_2/t_24 -innodb_encrypted_2/t_25 -innodb_encrypted_2/t_26 -innodb_encrypted_2/t_27 -innodb_encrypted_2/t_28 -innodb_encrypted_2/t_29 -innodb_encrypted_2/t_3 -innodb_encrypted_2/t_30 -innodb_encrypted_2/t_31 -innodb_encrypted_2/t_32 -innodb_encrypted_2/t_33 -innodb_encrypted_2/t_34 -innodb_encrypted_2/t_35 -innodb_encrypted_2/t_36 -innodb_encrypted_2/t_37 -innodb_encrypted_2/t_38 -innodb_encrypted_2/t_39 -innodb_encrypted_2/t_4 -innodb_encrypted_2/t_40 -innodb_encrypted_2/t_41 -innodb_encrypted_2/t_42 -innodb_encrypted_2/t_43 -innodb_encrypted_2/t_44 -innodb_encrypted_2/t_45 -innodb_encrypted_2/t_46 -innodb_encrypted_2/t_47 -innodb_encrypted_2/t_48 -innodb_encrypted_2/t_49 -innodb_encrypted_2/t_5 -innodb_encrypted_2/t_50 -innodb_encrypted_2/t_51 -innodb_encrypted_2/t_52 -innodb_encrypted_2/t_53 -innodb_encrypted_2/t_54 -innodb_encrypted_2/t_55 -innodb_encrypted_2/t_56 -innodb_encrypted_2/t_57 -innodb_encrypted_2/t_58 -innodb_encrypted_2/t_59 -innodb_encrypted_2/t_6 -innodb_encrypted_2/t_60 -innodb_encrypted_2/t_61 -innodb_encrypted_2/t_62 -innodb_encrypted_2/t_63 -innodb_encrypted_2/t_64 -innodb_encrypted_2/t_65 -innodb_encrypted_2/t_66 -innodb_encrypted_2/t_67 -innodb_encrypted_2/t_68 -innodb_encrypted_2/t_69 -innodb_encrypted_2/t_7 -innodb_encrypted_2/t_70 -innodb_encrypted_2/t_71 -innodb_encrypted_2/t_72 -innodb_encrypted_2/t_73 -innodb_encrypted_2/t_74 -innodb_encrypted_2/t_75 -innodb_encrypted_2/t_76 -innodb_encrypted_2/t_77 -innodb_encrypted_2/t_78 -innodb_encrypted_2/t_79 -innodb_encrypted_2/t_8 -innodb_encrypted_2/t_80 -innodb_encrypted_2/t_81 -innodb_encrypted_2/t_82 -innodb_encrypted_2/t_83 -innodb_encrypted_2/t_84 -innodb_encrypted_2/t_85 -innodb_encrypted_2/t_86 -innodb_encrypted_2/t_87 -innodb_encrypted_2/t_88 -innodb_encrypted_2/t_89 -innodb_encrypted_2/t_9 -innodb_encrypted_2/t_90 -innodb_encrypted_2/t_91 -innodb_encrypted_2/t_92 -innodb_encrypted_2/t_93 -innodb_encrypted_2/t_94 -innodb_encrypted_2/t_95 -innodb_encrypted_2/t_96 -innodb_encrypted_2/t_97 -innodb_encrypted_2/t_98 -innodb_encrypted_2/t_99 -SET GLOBAL innodb_encrypt_tables = off; -SET GLOBAL innodb_encryption_threads=4; -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -innodb_encrypted_2/t_1 -innodb_encrypted_2/t_10 -innodb_encrypted_2/t_100 -innodb_encrypted_2/t_11 -innodb_encrypted_2/t_12 -innodb_encrypted_2/t_13 -innodb_encrypted_2/t_14 -innodb_encrypted_2/t_15 -innodb_encrypted_2/t_16 -innodb_encrypted_2/t_17 -innodb_encrypted_2/t_18 -innodb_encrypted_2/t_19 -innodb_encrypted_2/t_2 -innodb_encrypted_2/t_20 -innodb_encrypted_2/t_21 -innodb_encrypted_2/t_22 -innodb_encrypted_2/t_23 -innodb_encrypted_2/t_24 -innodb_encrypted_2/t_25 -innodb_encrypted_2/t_26 -innodb_encrypted_2/t_27 -innodb_encrypted_2/t_28 -innodb_encrypted_2/t_29 -innodb_encrypted_2/t_3 -innodb_encrypted_2/t_30 -innodb_encrypted_2/t_31 -innodb_encrypted_2/t_32 -innodb_encrypted_2/t_33 -innodb_encrypted_2/t_34 -innodb_encrypted_2/t_35 -innodb_encrypted_2/t_36 -innodb_encrypted_2/t_37 -innodb_encrypted_2/t_38 -innodb_encrypted_2/t_39 -innodb_encrypted_2/t_4 -innodb_encrypted_2/t_40 -innodb_encrypted_2/t_41 -innodb_encrypted_2/t_42 -innodb_encrypted_2/t_43 -innodb_encrypted_2/t_44 -innodb_encrypted_2/t_45 -innodb_encrypted_2/t_46 -innodb_encrypted_2/t_47 -innodb_encrypted_2/t_48 -innodb_encrypted_2/t_49 -innodb_encrypted_2/t_5 -innodb_encrypted_2/t_50 -innodb_encrypted_2/t_51 -innodb_encrypted_2/t_52 -innodb_encrypted_2/t_53 -innodb_encrypted_2/t_54 -innodb_encrypted_2/t_55 -innodb_encrypted_2/t_56 -innodb_encrypted_2/t_57 -innodb_encrypted_2/t_58 -innodb_encrypted_2/t_59 -innodb_encrypted_2/t_6 -innodb_encrypted_2/t_60 -innodb_encrypted_2/t_61 -innodb_encrypted_2/t_62 -innodb_encrypted_2/t_63 -innodb_encrypted_2/t_64 -innodb_encrypted_2/t_65 -innodb_encrypted_2/t_66 -innodb_encrypted_2/t_67 -innodb_encrypted_2/t_68 -innodb_encrypted_2/t_69 -innodb_encrypted_2/t_7 -innodb_encrypted_2/t_70 -innodb_encrypted_2/t_71 -innodb_encrypted_2/t_72 -innodb_encrypted_2/t_73 -innodb_encrypted_2/t_74 -innodb_encrypted_2/t_75 -innodb_encrypted_2/t_76 -innodb_encrypted_2/t_77 -innodb_encrypted_2/t_78 -innodb_encrypted_2/t_79 -innodb_encrypted_2/t_8 -innodb_encrypted_2/t_80 -innodb_encrypted_2/t_81 -innodb_encrypted_2/t_82 -innodb_encrypted_2/t_83 -innodb_encrypted_2/t_84 -innodb_encrypted_2/t_85 -innodb_encrypted_2/t_86 -innodb_encrypted_2/t_87 -innodb_encrypted_2/t_88 -innodb_encrypted_2/t_89 -innodb_encrypted_2/t_9 -innodb_encrypted_2/t_90 -innodb_encrypted_2/t_91 -innodb_encrypted_2/t_92 -innodb_encrypted_2/t_93 -innodb_encrypted_2/t_94 -innodb_encrypted_2/t_95 -innodb_encrypted_2/t_96 -innodb_encrypted_2/t_97 -innodb_encrypted_2/t_98 -innodb_encrypted_2/t_99 -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -NAME -innodb_encrypted_3/t_1 -innodb_encrypted_3/t_10 -innodb_encrypted_3/t_100 -innodb_encrypted_3/t_11 -innodb_encrypted_3/t_12 -innodb_encrypted_3/t_13 -innodb_encrypted_3/t_14 -innodb_encrypted_3/t_15 -innodb_encrypted_3/t_16 -innodb_encrypted_3/t_17 -innodb_encrypted_3/t_18 -innodb_encrypted_3/t_19 -innodb_encrypted_3/t_2 -innodb_encrypted_3/t_20 -innodb_encrypted_3/t_21 -innodb_encrypted_3/t_22 -innodb_encrypted_3/t_23 -innodb_encrypted_3/t_24 -innodb_encrypted_3/t_25 -innodb_encrypted_3/t_26 -innodb_encrypted_3/t_27 -innodb_encrypted_3/t_28 -innodb_encrypted_3/t_29 -innodb_encrypted_3/t_3 -innodb_encrypted_3/t_30 -innodb_encrypted_3/t_31 -innodb_encrypted_3/t_32 -innodb_encrypted_3/t_33 -innodb_encrypted_3/t_34 -innodb_encrypted_3/t_35 -innodb_encrypted_3/t_36 -innodb_encrypted_3/t_37 -innodb_encrypted_3/t_38 -innodb_encrypted_3/t_39 -innodb_encrypted_3/t_4 -innodb_encrypted_3/t_40 -innodb_encrypted_3/t_41 -innodb_encrypted_3/t_42 -innodb_encrypted_3/t_43 -innodb_encrypted_3/t_44 -innodb_encrypted_3/t_45 -innodb_encrypted_3/t_46 -innodb_encrypted_3/t_47 -innodb_encrypted_3/t_48 -innodb_encrypted_3/t_49 -innodb_encrypted_3/t_5 -innodb_encrypted_3/t_50 -innodb_encrypted_3/t_51 -innodb_encrypted_3/t_52 -innodb_encrypted_3/t_53 -innodb_encrypted_3/t_54 -innodb_encrypted_3/t_55 -innodb_encrypted_3/t_56 -innodb_encrypted_3/t_57 -innodb_encrypted_3/t_58 -innodb_encrypted_3/t_59 -innodb_encrypted_3/t_6 -innodb_encrypted_3/t_60 -innodb_encrypted_3/t_61 -innodb_encrypted_3/t_62 -innodb_encrypted_3/t_63 -innodb_encrypted_3/t_64 -innodb_encrypted_3/t_65 -innodb_encrypted_3/t_66 -innodb_encrypted_3/t_67 -innodb_encrypted_3/t_68 -innodb_encrypted_3/t_69 -innodb_encrypted_3/t_7 -innodb_encrypted_3/t_70 -innodb_encrypted_3/t_71 -innodb_encrypted_3/t_72 -innodb_encrypted_3/t_73 -innodb_encrypted_3/t_74 -innodb_encrypted_3/t_75 -innodb_encrypted_3/t_76 -innodb_encrypted_3/t_77 -innodb_encrypted_3/t_78 -innodb_encrypted_3/t_79 -innodb_encrypted_3/t_8 -innodb_encrypted_3/t_80 -innodb_encrypted_3/t_81 -innodb_encrypted_3/t_82 -innodb_encrypted_3/t_83 -innodb_encrypted_3/t_84 -innodb_encrypted_3/t_85 -innodb_encrypted_3/t_86 -innodb_encrypted_3/t_87 -innodb_encrypted_3/t_88 -innodb_encrypted_3/t_89 -innodb_encrypted_3/t_9 -innodb_encrypted_3/t_90 -innodb_encrypted_3/t_91 -innodb_encrypted_3/t_92 -innodb_encrypted_3/t_93 -innodb_encrypted_3/t_94 -innodb_encrypted_3/t_95 -innodb_encrypted_3/t_96 -innodb_encrypted_3/t_97 -innodb_encrypted_3/t_98 -innodb_encrypted_3/t_99 -use test; -drop database innodb_encrypted_1; -drop database innodb_encrypted_2; -drop database innodb_encrypted_3; diff --git a/mysql-test/suite/encryption/t/innodb_lotoftables.opt b/mysql-test/suite/encryption/t/innodb_lotoftables.opt deleted file mode 100644 index ffb5a2957f8..00000000000 --- a/mysql-test/suite/encryption/t/innodb_lotoftables.opt +++ /dev/null @@ -1,3 +0,0 @@ ---innodb-tablespaces-encryption ---innodb-encrypt-tables=off ---innodb-encryption-threads=0 diff --git a/mysql-test/suite/encryption/t/innodb_lotoftables.test b/mysql-test/suite/encryption/t/innodb_lotoftables.test deleted file mode 100644 index e204de3bb7b..00000000000 --- a/mysql-test/suite/encryption/t/innodb_lotoftables.test +++ /dev/null @@ -1,240 +0,0 @@ --- source include/have_innodb.inc --- source include/have_example_key_management_plugin.inc --- source include/big_test.inc - -# embedded does not support restart --- source include/not_embedded.inc - ---disable_query_log -let $innodb_file_format_orig = `SELECT @@innodb_file_format`; -let $innodb_file_per_table_orig = `SELECT @@innodb_file_per_table`; -let $innodb_encryption_threads_orig = `SELECT @@global.innodb_encryption_threads`; ---enable_query_log - -# empty the change buffer and the undo logs to avoid extra reads -SET GLOBAL innodb_fast_shutdown=0; ---source include/restart_mysqld.inc - -SET GLOBAL innodb_file_format = `Barracuda`; -SET GLOBAL innodb_file_per_table = ON; - -SHOW VARIABLES LIKE 'innodb_encrypt%'; - -# -# This will create 100 tables where that could be -# encrypted an unencrypt -# -create database innodb_encrypted_1; -use innodb_encrypted_1; -show status like 'innodb_pages0_read%'; -set autocommit=0; -let $tables = 100; - ---disable_query_log -while ($tables) -{ - eval create table t_$tables (a int not null primary key, b varchar(200)) engine=innodb - stats_persistent=0; - commit; - let $rows = 100; - while($rows) - { - eval insert into t_$tables values ($rows, substring(MD5(RAND()), -64)); - dec $rows; - } - commit; - dec $tables; -} ---enable_query_log - -set autocommit=1; -commit work; -show status like 'innodb_pages0_read%'; -# -# Verify -# ---echo # should be empty -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE NAME LIKE 'innodb_encrypted%'; - -# -# This will create 100 tables that are encrypted always -# -create database innodb_encrypted_2; -use innodb_encrypted_2; -show status like 'innodb_pages0_read%'; -set autocommit=0; - ---disable_query_log -let $tables = 100; -while ($tables) -{ - eval create table t_$tables (a int not null primary key, b varchar(200)) engine=innodb - stats_persistent=0 encrypted=yes; - commit; - let $rows = 100; - while($rows) - { - eval insert into t_$tables values ($rows, substring(MD5(RAND()), -64)); - dec $rows; - } - commit; - dec $tables; -} ---enable_query_log - -commit work; -set autocommit=1; -show status like 'innodb_pages0_read%'; -# -# Verify -# ---echo # should contain 100 tables -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; ---echo # should contain 0 tables -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; - -# -# This will create 100 tables that are not encrypted -# -create database innodb_encrypted_3; -use innodb_encrypted_3; -show status like 'innodb_pages0_read%'; -set autocommit=0; - ---disable_query_log -let $tables = 100; -while ($tables) -{ - eval create table t_$tables (a int not null primary key, b varchar(200)) engine=innodb - stats_persistent=0 encrypted=no; - commit; - let $rows = 100; - while($rows) - { - eval insert into t_$tables values ($rows, substring(MD5(RAND()), -64)); - dec $rows; - } - commit; - dec $tables; -} ---enable_query_log - -commit work; -set autocommit=1; -show status like 'innodb_pages0_read%'; -# -# Verify -# ---echo # should contain 100 tables -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; ---echo # should contain 100 tables -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; - -use test; -show status like 'innodb_pages0_read%'; - -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; - -SET GLOBAL innodb_encrypt_tables = on; -SET GLOBAL innodb_encryption_threads=4; - ---let $wait_timeout= 600 ---let $wait_condition=SELECT COUNT(*) = 100 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; ---source include/wait_condition.inc - -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -show status like 'innodb_pages0_read%'; - ---echo # Success! ---echo # Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 --- let $restart_parameters=--innodb_encrypt_tables=0 --innodb_encryption_threads=0 --- source include/restart_mysqld.inc - ---echo # Restart Success! -show status like 'innodb_pages0_read%'; - -show status like 'innodb_pages0_read%'; -use test; -show status like 'innodb_pages0_read%'; -use innodb_encrypted_1; -show status like 'innodb_pages0_read%'; -use innodb_encrypted_2; -show status like 'innodb_pages0_read%'; -use innodb_encrypted_3; -show status like 'innodb_pages0_read%'; - -use innodb_encrypted_1; -show status like 'innodb_pages0_read%'; ---disable_result_log ---disable_query_log -let $tables = 100; -while ($tables) -{ - eval select * from t_$tables; - dec $tables; -} ---enable_query_log ---enable_result_log - -show status like 'innodb_pages0_read%'; - -use innodb_encrypted_2; -show status like 'innodb_pages0_read%'; - ---disable_result_log ---disable_query_log -let $tables = 100; -while ($tables) -{ - eval select * from t_$tables; - dec $tables; -} ---enable_query_log ---enable_result_log - -show status like 'innodb_pages0_read%'; - -use innodb_encrypted_3; -show status like 'innodb_pages0_read%'; ---disable_result_log ---disable_query_log -let $tables = 100; -while ($tables) -{ - eval select * from t_$tables; - dec $tables; -} ---enable_query_log ---enable_result_log - -show status like 'innodb_pages0_read%'; - -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; - -SET GLOBAL innodb_encrypt_tables = off; -SET GLOBAL innodb_encryption_threads=4; - ---let $wait_timeout= 600 ---let $wait_condition=SELECT COUNT(*) = 100 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; ---source include/wait_condition.inc - - -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; -SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; - -# -# Cleanup -# -use test; -drop database innodb_encrypted_1; -drop database innodb_encrypted_2; -drop database innodb_encrypted_3; - ---disable_query_log -EVAL SET GLOBAL innodb_file_per_table = $innodb_file_per_table_orig; -EVAL SET GLOBAL innodb_file_format = $innodb_file_format_orig; -EVAL SET GLOBAL innodb_encryption_threads = $innodb_encryption_threads_orig; ---enable_query_log diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests index b400c4e971e..87f836a84e1 100644 --- a/mysql-test/unstable-tests +++ b/mysql-test/unstable-tests @@ -213,7 +213,6 @@ encryption.innodb_encryption_row_compressed : MDEV-16113 - Crash encryption.innodb_first_page : MDEV-10689 - Crash encryption.innodb-first-page-read : MDEV-14356 - Timeout on wait condition encryption.innodb-force-corrupt : Modified in 10.1.38 -encryption.innodb_lotoftables : MDEV-16111 - Wrong result encryption.innodb-page_encryption : MDEV-10641 - mutex problem encryption.innodb-read-only : MDEV-14728 - Unable to get certificate; MDEV-16563 - Crash on startup encryption.innodb-redo-badkey : MDEV-12898 - Server hang on startup From 06be8cd38faf6faa35e0166226e6e178ce2819d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 12 Jun 2019 19:18:47 +0300 Subject: [PATCH 23/25] Clean up the test innodb.innodb-64k-crash Before killing the server, ensure that the incomplete state of the transaction will be made durable and will be applied and rolled back on recovery, so that each time, roughly the same amount of work will be done. Remove DML statements after the recovery, and execute CHECK TABLE instead. --- .../suite/innodb/r/innodb-64k-crash.result | 324 +----------------- .../suite/innodb/t/innodb-64k-crash.test | 83 +---- 2 files changed, 16 insertions(+), 391 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-64k-crash.result b/mysql-test/suite/innodb/r/innodb-64k-crash.result index 138ad5345ed..80beef92162 100644 --- a/mysql-test/suite/innodb/r/innodb-64k-crash.result +++ b/mysql-test/suite/innodb/r/innodb-64k-crash.result @@ -271,319 +271,13 @@ vb=@c,wb=@c,xb=@c,yb=@c,zb=@c, ac=@c,bc=@c,cc=@c,dc=@c,ec=@c,fc=@c,gc=@c,hc=@c,ic=@c,jc=@c, kc=@c,lc=@c,mc=@c,nc=@c,oc=@c,pc=@c,qc=@c,rc=@c,sc=@c,tc=@c,uc=@c, vc=@c,wc=@c,xc=@c,yc=@c,zc=@c; -UPDATE t1 SET a=@e,b=@e,c=@e,d=@e,e=@e,f=@e,g=@e,h=@e,i=@e,j=@e, -k=@e,l=@e,m=@e,n=@e,o=@e,p=@e,q=@e,r=@e,s=@e,t=@e,u=@e, -v=@e,w=@e,x=@e,y=@e,z=@e, -aa=@e,ba=@e,ca=@e,da=@e,ea=@e,fa=@e,ga=@e,ha=@e,ia=@e,ja=@e, -ka=@e,la=@e,ma=@e,na=@e,oa=@e,pa=@e,qa=@e,ra=@e,sa=@e,ta=@e,ua=@e, -va=@e,wa=@e,xa=@e,ya=@e,za=@e, -ab=@e,bb=@e,cb=@e,db=@e,eb=@e,fb=@e,gb=@e,hb=@e,ib=@e,jb=@e, -kb=@e,lb=@e,mb=@e,nb=@e,ob=@e,pb=@e,qb=@e,rb=@e,sb=@e,tb=@e,ub=@e, -vb=@e,wb=@e,xb=@e,yb=@e,zb=@e, -ac=@e,bc=@e,cc=@e,dc=@e,ec=@e,fc=@e,gc=@e,hc=@e,ic=@e,jc=@e, -kc=@e,lc=@e,mc=@e,nc=@e,oc=@e,pc=@e,qc=@e,rc=@e,sc=@e,tc=@e,uc=@e, -vc=@e,wc=@e,xc=@e,yc=@e,zc=@e; -UPDATE t2 SET a=@l,b=@l,c=@l,d=@l,e=@l,f=@l,g=@l,h=@l,i=@l,j=@l, -k=@l,l=@l,m=@l,n=@l,o=@l,p=@l,q=@l,r=@l,s=@l,t=@l,u=@l, -v=@l,w=@l,x=@l,y=@l,z=@l, -aa=@l,ba=@l,ca=@l,da=@l,ea=@l,fa=@l,ga=@l,ha=@l,ia=@l,ja=@l, -ka=@l,la=@l,ma=@l,na=@l,oa=@l,pa=@l,qa=@l,ra=@l,sa=@l,ta=@l,ua=@l, -va=@l,wa=@l,xa=@l,ya=@l,za=@l, -ab=@l,bb=@l,cb=@l,db=@l,eb=@l,fb=@l,gb=@l,hb=@l,ib=@l,jb=@l, -kb=@l,lb=@l,mb=@l,nb=@l,ob=@l,pb=@l,qb=@l,rb=@l,sb=@l,tb=@l,ub=@l, -vb=@l,wb=@l,xb=@l,yb=@l,zb=@l, -ac=@l,bc=@l,cc=@l,dc=@l,ec=@l,fc=@l,gc=@l,hc=@l,ic=@l,jc=@l, -kc=@l,lc=@l,mc=@l,nc=@l,oc=@l,pc=@l,qc=@l,rc=@l,sc=@l,tc=@l,uc=@l, -vc=@l,wc=@l,xc=@l,yc=@l,zc=@l; -COMMIT; -BEGIN; -UPDATE t1 SET a=@f,b=@f,c=@f,d=@f,e=@f; -UPDATE t1 SET f=@f,g=@f,h=@f,i=@f,j=@f; -UPDATE t1 SET k=@f,l=@f,m=@f,n=@f,o=@f; -UPDATE t1 SET p=@f,q=@f,r=@f,s=@f,t=@f,u=@f; -UPDATE t1 SET v=@f,w=@f,x=@f,y=@f,z=@f; -UPDATE t1 SET aa=@f,ba=@f,ca=@f,da=@f; -UPDATE t1 SET ea=@f,fa=@f,ga=@f,ha=@f,ia=@f,ja=@f; -UPDATE t1 SET ka=@f,la=@f,ma=@f,na=@f,oa=@f,pa=@f; -UPDATE t1 SET qa=@f,ra=@f,sa=@f,ta=@f,ua=@f; -UPDATE t1 SET va=@f,wa=@f,xa=@f,ya=@f,za=@f; -UPDATE t1 SET ab=@f,bb=@f,cb=@f,db=@f; -UPDATE t1 SET eb=@f,fb=@f,gb=@f,hb=@f,ib=@f,ja=@f; -UPDATE t1 SET kb=@f,lb=@f,mb=@f,nb=@f,ob=@f,pa=@f; -UPDATE t1 SET qb=@f,rb=@f,sb=@f,tb=@f,ub=@f; -UPDATE t1 SET vb=@f,wb=@f,xb=@f,yb=@f,zb=@f; -UPDATE t1 SET ac=@f,bc=@f,cc=@f,dc=@f; -UPDATE t1 SET ec=@f,fc=@f,gc=@f,hc=@f,ic=@f,jc=@f; -UPDATE t1 SET kc=@f,lc=@f,mc=@f,nc=@f,oc=@f,pc=@f; -UPDATE t1 SET qc=@f,rc=@f,sc=@f,tc=@f,uc=@f; -UPDATE t1 SET vc=@f,wc=@f,xc=@f,yc=@f,zc=@f; -COMMIT; -BEGIN; -UPDATE t2 SET a=@f,b=@f,c=@f,d=@f,e=@f; -UPDATE t2 SET f=@f,g=@f,h=@f,i=@f,j=@f; -UPDATE t2 SET k=@f,l=@f,m=@f,n=@f,o=@f; -UPDATE t2 SET p=@f,q=@f,r=@f,s=@f,t=@f,u=@f; -UPDATE t2 SET v=@f,w=@f,x=@f,y=@f,z=@f; -UPDATE t2 SET aa=@f,ba=@f,ca=@f,da=@f; -UPDATE t2 SET ea=@f,fa=@f,ga=@f,ha=@f,ia=@f,ja=@f; -UPDATE t2 SET ka=@f,la=@f,ma=@f,na=@f,oa=@f,pa=@f; -UPDATE t2 SET qa=@f,ra=@f,sa=@f,ta=@f,ua=@f; -UPDATE t2 SET va=@f,wa=@f,xa=@f,ya=@f,za=@f; -UPDATE t2 SET ab=@f,bb=@f,cb=@f,db=@f; -UPDATE t2 SET eb=@f,fb=@f,gb=@f,hb=@f,ib=@f,ja=@f; -UPDATE t2 SET kb=@f,lb=@f,mb=@f,nb=@f,ob=@f,pa=@f; -UPDATE t2 SET qb=@f,rb=@f,sb=@f,tb=@f,ub=@f; -UPDATE t2 SET vb=@f,wb=@f,xb=@f,yb=@f,zb=@f; -UPDATE t2 SET ac=@f,bc=@f,cc=@f,dc=@f; -UPDATE t2 SET ec=@f,fc=@f,gc=@f,hc=@f,ic=@f,jc=@f; -UPDATE t2 SET kc=@f,lc=@f,mc=@f,nc=@f,oc=@f,pc=@f; -UPDATE t2 SET qc=@f,rc=@f,sc=@f,tc=@f,uc=@f; -UPDATE t2 SET vc=@f,wc=@f,xc=@f,yc=@f,zc=@f; -COMMIT; -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` blob DEFAULT NULL, - `b` blob DEFAULT NULL, - `c` blob DEFAULT NULL, - `d` blob DEFAULT NULL, - `e` blob DEFAULT NULL, - `f` blob DEFAULT NULL, - `g` blob DEFAULT NULL, - `h` blob DEFAULT NULL, - `i` blob DEFAULT NULL, - `j` blob DEFAULT NULL, - `k` blob DEFAULT NULL, - `l` blob DEFAULT NULL, - `m` blob DEFAULT NULL, - `n` blob DEFAULT NULL, - `o` blob DEFAULT NULL, - `p` blob DEFAULT NULL, - `q` blob DEFAULT NULL, - `r` blob DEFAULT NULL, - `s` blob DEFAULT NULL, - `t` blob DEFAULT NULL, - `u` blob DEFAULT NULL, - `v` blob DEFAULT NULL, - `w` blob DEFAULT NULL, - `x` blob DEFAULT NULL, - `y` blob DEFAULT NULL, - `z` blob DEFAULT NULL, - `aa` blob DEFAULT NULL, - `ba` blob DEFAULT NULL, - `ca` blob DEFAULT NULL, - `da` blob DEFAULT NULL, - `ea` blob DEFAULT NULL, - `fa` blob DEFAULT NULL, - `ga` blob DEFAULT NULL, - `ha` blob DEFAULT NULL, - `ia` blob DEFAULT NULL, - `ja` blob DEFAULT NULL, - `ka` blob DEFAULT NULL, - `la` blob DEFAULT NULL, - `ma` blob DEFAULT NULL, - `na` blob DEFAULT NULL, - `oa` blob DEFAULT NULL, - `pa` blob DEFAULT NULL, - `qa` blob DEFAULT NULL, - `ra` blob DEFAULT NULL, - `sa` blob DEFAULT NULL, - `ta` blob DEFAULT NULL, - `ua` blob DEFAULT NULL, - `va` blob DEFAULT NULL, - `wa` blob DEFAULT NULL, - `xa` blob DEFAULT NULL, - `ya` blob DEFAULT NULL, - `za` blob DEFAULT NULL, - `ab` blob DEFAULT NULL, - `bb` blob DEFAULT NULL, - `cb` blob DEFAULT NULL, - `db` blob DEFAULT NULL, - `eb` blob DEFAULT NULL, - `fb` blob DEFAULT NULL, - `gb` blob DEFAULT NULL, - `hb` blob DEFAULT NULL, - `ib` blob DEFAULT NULL, - `jb` blob DEFAULT NULL, - `kb` blob DEFAULT NULL, - `lb` blob DEFAULT NULL, - `mb` blob DEFAULT NULL, - `nb` blob DEFAULT NULL, - `ob` blob DEFAULT NULL, - `pb` blob DEFAULT NULL, - `qb` blob DEFAULT NULL, - `rb` blob DEFAULT NULL, - `sb` blob DEFAULT NULL, - `tb` blob DEFAULT NULL, - `ub` blob DEFAULT NULL, - `vb` blob DEFAULT NULL, - `wb` blob DEFAULT NULL, - `xb` blob DEFAULT NULL, - `yb` blob DEFAULT NULL, - `zb` blob DEFAULT NULL, - `ac` blob DEFAULT NULL, - `bc` blob DEFAULT NULL, - `cc` blob DEFAULT NULL, - `dc` blob DEFAULT NULL, - `ec` blob DEFAULT NULL, - `fc` blob DEFAULT NULL, - `gc` blob DEFAULT NULL, - `hc` blob DEFAULT NULL, - `ic` blob DEFAULT NULL, - `jc` blob DEFAULT NULL, - `kc` blob DEFAULT NULL, - `lc` blob DEFAULT NULL, - `mc` blob DEFAULT NULL, - `nc` blob DEFAULT NULL, - `oc` blob DEFAULT NULL, - `pc` blob DEFAULT NULL, - `qc` blob DEFAULT NULL, - `rc` blob DEFAULT NULL, - `sc` blob DEFAULT NULL, - `tc` blob DEFAULT NULL, - `uc` blob DEFAULT NULL, - `vc` blob DEFAULT NULL, - `wc` blob DEFAULT NULL, - `xc` blob DEFAULT NULL, - `yc` blob DEFAULT NULL, - `zc` blob DEFAULT NULL, - KEY `t1a` (`a`(767),`b`(767)), - KEY `t1c` (`c`(767),`d`(767)), - KEY `t1e` (`e`(767),`f`(767)), - KEY `t1f2` (`g`(767),`h`(767)), - KEY `t1f4` (`i`(767),`j`(767)), - KEY `t1k` (`k`(767),`m`(767)), - KEY `t1f8` (`n`(767),`o`(767)), - KEY `t1f11` (`p`(767),`q`(767)), - KEY `t1f13` (`r`(767),`s`(767)), - KEY `t1f15` (`t`(767),`u`(767)), - KEY `t1f18` (`w`(767),`x`(767)), - KEY `t1f20` (`y`(767),`z`(767)), - KEY `ta1a6` (`aa`(767),`ba`(767)), - KEY `tc1c6` (`ca`(767),`da`(767)), - KEY `te1e6` (`ea`(767),`fa`(767)) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `a` blob DEFAULT NULL, - `b` blob DEFAULT NULL, - `c` blob DEFAULT NULL, - `d` blob DEFAULT NULL, - `e` blob DEFAULT NULL, - `f` blob DEFAULT NULL, - `g` blob DEFAULT NULL, - `h` blob DEFAULT NULL, - `i` blob DEFAULT NULL, - `j` blob DEFAULT NULL, - `k` blob DEFAULT NULL, - `l` blob DEFAULT NULL, - `m` blob DEFAULT NULL, - `n` blob DEFAULT NULL, - `o` blob DEFAULT NULL, - `p` blob DEFAULT NULL, - `q` blob DEFAULT NULL, - `r` blob DEFAULT NULL, - `s` blob DEFAULT NULL, - `t` blob DEFAULT NULL, - `u` blob DEFAULT NULL, - `v` blob DEFAULT NULL, - `w` blob DEFAULT NULL, - `x` blob DEFAULT NULL, - `y` blob DEFAULT NULL, - `z` blob DEFAULT NULL, - `aa` blob DEFAULT NULL, - `ba` blob DEFAULT NULL, - `ca` blob DEFAULT NULL, - `da` blob DEFAULT NULL, - `ea` blob DEFAULT NULL, - `fa` blob DEFAULT NULL, - `ga` blob DEFAULT NULL, - `ha` blob DEFAULT NULL, - `ia` blob DEFAULT NULL, - `ja` blob DEFAULT NULL, - `ka` blob DEFAULT NULL, - `la` blob DEFAULT NULL, - `ma` blob DEFAULT NULL, - `na` blob DEFAULT NULL, - `oa` blob DEFAULT NULL, - `pa` blob DEFAULT NULL, - `qa` blob DEFAULT NULL, - `ra` blob DEFAULT NULL, - `sa` blob DEFAULT NULL, - `ta` blob DEFAULT NULL, - `ua` blob DEFAULT NULL, - `va` blob DEFAULT NULL, - `wa` blob DEFAULT NULL, - `xa` blob DEFAULT NULL, - `ya` blob DEFAULT NULL, - `za` blob DEFAULT NULL, - `ab` blob DEFAULT NULL, - `bb` blob DEFAULT NULL, - `cb` blob DEFAULT NULL, - `db` blob DEFAULT NULL, - `eb` blob DEFAULT NULL, - `fb` blob DEFAULT NULL, - `gb` blob DEFAULT NULL, - `hb` blob DEFAULT NULL, - `ib` blob DEFAULT NULL, - `jb` blob DEFAULT NULL, - `kb` blob DEFAULT NULL, - `lb` blob DEFAULT NULL, - `mb` blob DEFAULT NULL, - `nb` blob DEFAULT NULL, - `ob` blob DEFAULT NULL, - `pb` blob DEFAULT NULL, - `qb` blob DEFAULT NULL, - `rb` blob DEFAULT NULL, - `sb` blob DEFAULT NULL, - `tb` blob DEFAULT NULL, - `ub` blob DEFAULT NULL, - `vb` blob DEFAULT NULL, - `wb` blob DEFAULT NULL, - `xb` blob DEFAULT NULL, - `yb` blob DEFAULT NULL, - `zb` blob DEFAULT NULL, - `ac` blob DEFAULT NULL, - `bc` blob DEFAULT NULL, - `cc` blob DEFAULT NULL, - `dc` blob DEFAULT NULL, - `ec` blob DEFAULT NULL, - `fc` blob DEFAULT NULL, - `gc` blob DEFAULT NULL, - `hc` blob DEFAULT NULL, - `ic` blob DEFAULT NULL, - `jc` blob DEFAULT NULL, - `kc` blob DEFAULT NULL, - `lc` blob DEFAULT NULL, - `mc` blob DEFAULT NULL, - `nc` blob DEFAULT NULL, - `oc` blob DEFAULT NULL, - `pc` blob DEFAULT NULL, - `qc` blob DEFAULT NULL, - `rc` blob DEFAULT NULL, - `sc` blob DEFAULT NULL, - `tc` blob DEFAULT NULL, - `uc` blob DEFAULT NULL, - `vc` blob DEFAULT NULL, - `wc` blob DEFAULT NULL, - `xc` blob DEFAULT NULL, - `yc` blob DEFAULT NULL, - `zc` blob DEFAULT NULL, - KEY `t2a` (`a`(767),`b`(767)), - KEY `t2c` (`c`(767),`d`(767)), - KEY `t2e` (`e`(767),`f`(767)), - KEY `t2f2` (`g`(767),`h`(767)), - KEY `t2f4` (`i`(767),`j`(767)), - KEY `t2k` (`k`(767),`m`(767)), - KEY `t2f8` (`n`(767),`o`(767)), - KEY `t2f11` (`p`(767),`q`(767)), - KEY `t2f13` (`r`(767),`s`(767)), - KEY `t2f15` (`t`(767),`u`(767)), - KEY `t2f18` (`w`(767),`x`(767)), - KEY `t2f20` (`y`(767),`z`(767)), - KEY `ta2a6` (`aa`(767),`ba`(767)), - KEY `tc2c6` (`ca`(767),`da`(767)), - KEY `te2e6` (`ea`(767),`fa`(767)) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +connect con1,localhost,root,,; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +DELETE FROM t2 LIMIT 1; +disconnect con1; +connection default; +check table t1,t2; +Table Op Msg_type Msg_text +test.t1 check status OK +test.t2 check status OK drop table t1,t2; diff --git a/mysql-test/suite/innodb/t/innodb-64k-crash.test b/mysql-test/suite/innodb/t/innodb-64k-crash.test index 8139b7ce4e4..950c1752ccd 100644 --- a/mysql-test/suite/innodb/t/innodb-64k-crash.test +++ b/mysql-test/suite/innodb/t/innodb-64k-crash.test @@ -300,84 +300,15 @@ UPDATE t1 SET a=@c,b=@c,c=@c,d=@c,e=@c,f=@c,g=@c,h=@c,i=@c,j=@c, kc=@c,lc=@c,mc=@c,nc=@c,oc=@c,pc=@c,qc=@c,rc=@c,sc=@c,tc=@c,uc=@c, vc=@c,wc=@c,xc=@c,yc=@c,zc=@c; +connect (con1,localhost,root,,); +SET GLOBAL innodb_flush_log_at_trx_commit=1; +DELETE FROM t2 LIMIT 1; +disconnect con1; +connection default; + --let $shutdown_timeout=0 --source include/restart_mysqld.inc --let $shutdown_timeout= -UPDATE t1 SET a=@e,b=@e,c=@e,d=@e,e=@e,f=@e,g=@e,h=@e,i=@e,j=@e, - k=@e,l=@e,m=@e,n=@e,o=@e,p=@e,q=@e,r=@e,s=@e,t=@e,u=@e, - v=@e,w=@e,x=@e,y=@e,z=@e, - aa=@e,ba=@e,ca=@e,da=@e,ea=@e,fa=@e,ga=@e,ha=@e,ia=@e,ja=@e, - ka=@e,la=@e,ma=@e,na=@e,oa=@e,pa=@e,qa=@e,ra=@e,sa=@e,ta=@e,ua=@e, - va=@e,wa=@e,xa=@e,ya=@e,za=@e, - ab=@e,bb=@e,cb=@e,db=@e,eb=@e,fb=@e,gb=@e,hb=@e,ib=@e,jb=@e, - kb=@e,lb=@e,mb=@e,nb=@e,ob=@e,pb=@e,qb=@e,rb=@e,sb=@e,tb=@e,ub=@e, - vb=@e,wb=@e,xb=@e,yb=@e,zb=@e, - ac=@e,bc=@e,cc=@e,dc=@e,ec=@e,fc=@e,gc=@e,hc=@e,ic=@e,jc=@e, - kc=@e,lc=@e,mc=@e,nc=@e,oc=@e,pc=@e,qc=@e,rc=@e,sc=@e,tc=@e,uc=@e, - vc=@e,wc=@e,xc=@e,yc=@e,zc=@e; - -UPDATE t2 SET a=@l,b=@l,c=@l,d=@l,e=@l,f=@l,g=@l,h=@l,i=@l,j=@l, - k=@l,l=@l,m=@l,n=@l,o=@l,p=@l,q=@l,r=@l,s=@l,t=@l,u=@l, - v=@l,w=@l,x=@l,y=@l,z=@l, - aa=@l,ba=@l,ca=@l,da=@l,ea=@l,fa=@l,ga=@l,ha=@l,ia=@l,ja=@l, - ka=@l,la=@l,ma=@l,na=@l,oa=@l,pa=@l,qa=@l,ra=@l,sa=@l,ta=@l,ua=@l, - va=@l,wa=@l,xa=@l,ya=@l,za=@l, - ab=@l,bb=@l,cb=@l,db=@l,eb=@l,fb=@l,gb=@l,hb=@l,ib=@l,jb=@l, - kb=@l,lb=@l,mb=@l,nb=@l,ob=@l,pb=@l,qb=@l,rb=@l,sb=@l,tb=@l,ub=@l, - vb=@l,wb=@l,xb=@l,yb=@l,zb=@l, - ac=@l,bc=@l,cc=@l,dc=@l,ec=@l,fc=@l,gc=@l,hc=@l,ic=@l,jc=@l, - kc=@l,lc=@l,mc=@l,nc=@l,oc=@l,pc=@l,qc=@l,rc=@l,sc=@l,tc=@l,uc=@l, - vc=@l,wc=@l,xc=@l,yc=@l,zc=@l; - -COMMIT; - -BEGIN; -UPDATE t1 SET a=@f,b=@f,c=@f,d=@f,e=@f; -UPDATE t1 SET f=@f,g=@f,h=@f,i=@f,j=@f; -UPDATE t1 SET k=@f,l=@f,m=@f,n=@f,o=@f; -UPDATE t1 SET p=@f,q=@f,r=@f,s=@f,t=@f,u=@f; -UPDATE t1 SET v=@f,w=@f,x=@f,y=@f,z=@f; -UPDATE t1 SET aa=@f,ba=@f,ca=@f,da=@f; -UPDATE t1 SET ea=@f,fa=@f,ga=@f,ha=@f,ia=@f,ja=@f; -UPDATE t1 SET ka=@f,la=@f,ma=@f,na=@f,oa=@f,pa=@f; -UPDATE t1 SET qa=@f,ra=@f,sa=@f,ta=@f,ua=@f; -UPDATE t1 SET va=@f,wa=@f,xa=@f,ya=@f,za=@f; -UPDATE t1 SET ab=@f,bb=@f,cb=@f,db=@f; -UPDATE t1 SET eb=@f,fb=@f,gb=@f,hb=@f,ib=@f,ja=@f; -UPDATE t1 SET kb=@f,lb=@f,mb=@f,nb=@f,ob=@f,pa=@f; -UPDATE t1 SET qb=@f,rb=@f,sb=@f,tb=@f,ub=@f; -UPDATE t1 SET vb=@f,wb=@f,xb=@f,yb=@f,zb=@f; -UPDATE t1 SET ac=@f,bc=@f,cc=@f,dc=@f; -UPDATE t1 SET ec=@f,fc=@f,gc=@f,hc=@f,ic=@f,jc=@f; -UPDATE t1 SET kc=@f,lc=@f,mc=@f,nc=@f,oc=@f,pc=@f; -UPDATE t1 SET qc=@f,rc=@f,sc=@f,tc=@f,uc=@f; -UPDATE t1 SET vc=@f,wc=@f,xc=@f,yc=@f,zc=@f; -COMMIT; - -BEGIN; -UPDATE t2 SET a=@f,b=@f,c=@f,d=@f,e=@f; -UPDATE t2 SET f=@f,g=@f,h=@f,i=@f,j=@f; -UPDATE t2 SET k=@f,l=@f,m=@f,n=@f,o=@f; -UPDATE t2 SET p=@f,q=@f,r=@f,s=@f,t=@f,u=@f; -UPDATE t2 SET v=@f,w=@f,x=@f,y=@f,z=@f; -UPDATE t2 SET aa=@f,ba=@f,ca=@f,da=@f; -UPDATE t2 SET ea=@f,fa=@f,ga=@f,ha=@f,ia=@f,ja=@f; -UPDATE t2 SET ka=@f,la=@f,ma=@f,na=@f,oa=@f,pa=@f; -UPDATE t2 SET qa=@f,ra=@f,sa=@f,ta=@f,ua=@f; -UPDATE t2 SET va=@f,wa=@f,xa=@f,ya=@f,za=@f; -UPDATE t2 SET ab=@f,bb=@f,cb=@f,db=@f; -UPDATE t2 SET eb=@f,fb=@f,gb=@f,hb=@f,ib=@f,ja=@f; -UPDATE t2 SET kb=@f,lb=@f,mb=@f,nb=@f,ob=@f,pa=@f; -UPDATE t2 SET qb=@f,rb=@f,sb=@f,tb=@f,ub=@f; -UPDATE t2 SET vb=@f,wb=@f,xb=@f,yb=@f,zb=@f; -UPDATE t2 SET ac=@f,bc=@f,cc=@f,dc=@f; -UPDATE t2 SET ec=@f,fc=@f,gc=@f,hc=@f,ic=@f,jc=@f; -UPDATE t2 SET kc=@f,lc=@f,mc=@f,nc=@f,oc=@f,pc=@f; -UPDATE t2 SET qc=@f,rc=@f,sc=@f,tc=@f,uc=@f; -UPDATE t2 SET vc=@f,wc=@f,xc=@f,yc=@f,zc=@f; -COMMIT; - -show create table t1; -show create table t2; +check table t1,t2; drop table t1,t2; From 371a8a6615a6ebaa9867d582ca3096cbd64e0dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 13 Jun 2019 13:18:54 +0300 Subject: [PATCH 24/25] Galera test cleanup. --- mysql-test/suite/galera/disabled.def | 2 ++ .../suite/galera/r/galera_sync_wait_show.result | 2 ++ mysql-test/suite/wsrep/disabled.def | 12 ++++++++++++ 3 files changed, 16 insertions(+) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index f8510aa7429..71230a9955c 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -15,6 +15,7 @@ MW-328A : MDEV-17847 Galera test failure on MW-328[A|B|C] MW-328B : MDEV-17847 Galera test failure on MW-328[A|B|C] MW-328C : MDEV-17847 Galera test failure on MW-328[A|B|C] MW-329 : wsrep_local_replays not stable +MW-336 : MDEV-19746 Galera test failures because of wsrep_slave_threads identification MW-416 : MDEV-13549 Galera test failures MW-44 : MDEV-15809 Test failure on galera.MW-44 galera_account_management : MariaDB 10.0 does not support ALTER USER @@ -38,6 +39,7 @@ galera_sst_xtrabackup-v2 : MDEV-17848 Galera test failure galera_sst_xtrabackup-v2_data_dir : MDEV-17848 Galera test failure galera_var_node_address : MDEV-17151 Galera test failure galera_var_notify_cmd : MDEV-13549 Galera test failures +galera_var_slave_threads : MDEV-19746 Galera test failures because of wsrep_slave_threads identification galera_wan : MDEV-17259: Test failure on galera.galera_wan partition : MDEV-13549 regularly showing auto_increment mismatch pxc-421: Lock timeout exceeded diff --git a/mysql-test/suite/galera/r/galera_sync_wait_show.result b/mysql-test/suite/galera/r/galera_sync_wait_show.result index e1d6dd9d61d..2d8e4aa759b 100644 --- a/mysql-test/suite/galera/r/galera_sync_wait_show.result +++ b/mysql-test/suite/galera/r/galera_sync_wait_show.result @@ -47,6 +47,8 @@ tr1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE DROP TABLE t1; connection node_1; CREATE EVENT event1 ON SCHEDULE AT '2038-01-01 23:59:59' DO SELECT 1; +Warnings: +Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. connection node_2; SHOW CREATE EVENT event1; Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation diff --git a/mysql-test/suite/wsrep/disabled.def b/mysql-test/suite/wsrep/disabled.def index 8b137891791..bcaebf7ff4d 100644 --- a/mysql-test/suite/wsrep/disabled.def +++ b/mysql-test/suite/wsrep/disabled.def @@ -1 +1,13 @@ +############################################################################## +# +# List the test cases that are to be disabled temporarily. +# +# Separate the test case name and the comment with ':'. +# +# : MDEV- +# +# Do not use any TAB characters for whitespace. +# +############################################################################## +variables : MDEV-19746 Galera test failures because of wsrep_slave_threads identification From e9145aab44f3c052868836f2fe1b9ca87ae6895b Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 13 Jun 2019 16:31:06 +0530 Subject: [PATCH 25/25] MDEV-19435 buf_fix_count > 0 for corrupted page when it exits the LRU list Problem: ========= One of the purge thread access the corrupted page and tries to remove from LRU list. In the mean time, other purge threads are waiting for same page in buf_wait_for_read(). Assertion(buf_fix_count == 0) fails for the purge thread which tries to remove the page from LRU list. Solution: ======== - Set the page id as FIL_NULL to indicate the page is corrupted before removing the block from LRU list. Acquire hash lock for the particular page id and wait for the other threads to release buf_fix_count for the block. - Added the error check for btr_cur_open() in row_search_on_row_ref(). --- .../leaf_page_corrupted_during_recovery.test | 1 + storage/innobase/buf/buf0buf.cc | 26 +++++++++- storage/innobase/buf/buf0lru.cc | 26 ++++++---- storage/innobase/buf/buf0rea.cc | 5 +- storage/innobase/include/buf0buf.h | 16 +++--- storage/innobase/include/buf0buf.ic | 51 +++++++++++++------ storage/innobase/include/buf0lru.h | 14 +++-- storage/innobase/include/buf0types.h | 6 +++ storage/innobase/row/row0row.cc | 5 +- 9 files changed, 102 insertions(+), 48 deletions(-) diff --git a/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test index 688ea4867c8..2d8e7f2ff5e 100644 --- a/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test +++ b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test @@ -9,6 +9,7 @@ call mtr.add_suppression("\\[ERROR\\] InnoDB: Plugin initialization aborted at s call mtr.add_suppression("\\[ERROR\\] Plugin 'InnoDB' (init function|registration)"); call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption"); call mtr.add_suppression("\\[ERROR\\] mysqld.*: Index for table 't1' is corrupt; try to repair it"); +call mtr.add_suppression("InnoDB: Error code: [0-9][0-9][0-9]* btr_pcur_open_low level: 0 called from file: "); --enable_query_log CREATE TABLE t1 (pk INT PRIMARY KEY, c CHAR(255))ENGINE=InnoDB STATS_PERSISTENT=0; diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 18decb492f3..644d033e1b7 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -4801,6 +4801,23 @@ evict_from_pool: and block->lock. */ buf_wait_for_read(fix_block); + if (fix_block->page.id != page_id) { + + buf_block_unfix(fix_block); + +#ifdef UNIV_DEBUG + if (!fsp_is_system_temporary(page_id.space())) { + rw_lock_s_unlock(&fix_block->debug_latch); + } +#endif /* UNIV_DEBUG */ + + if (err) { + *err = DB_PAGE_CORRUPTED; + } + + return NULL; + } + mtr_memo_type_t fix_type; switch (rw_latch) { @@ -5775,13 +5792,18 @@ buf_corrupt_page_release(buf_page_t* bpage, const fil_space_t* space) buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); const ibool uncompressed = (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE); + page_id_t old_page_id = bpage->id; /* First unfix and release lock on the bpage */ buf_pool_mutex_enter(buf_pool); mutex_enter(buf_page_get_mutex(bpage)); ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ); - ut_ad(bpage->buf_fix_count == 0); + ut_ad(bpage->id.space() == space->id); + /* buf_fix_count can be greater than zero. Because other thread + can wait in buf_page_wait_read() for the page to be read. */ + + bpage->id.set_corrupt_id(); /* Set BUF_IO_NONE before we remove the block from LRU list */ buf_page_set_io_fix(bpage, BUF_IO_NONE); @@ -5798,7 +5820,7 @@ buf_corrupt_page_release(buf_page_t* bpage, const fil_space_t* space) } /* After this point bpage can't be referenced. */ - buf_LRU_free_one_page(bpage); + buf_LRU_free_one_page(bpage, old_page_id); ut_ad(buf_pool->n_pend_reads > 0); buf_pool->n_pend_reads--; diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index ff20bd570d7..8673c8d9d72 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -2166,25 +2166,31 @@ buf_LRU_block_free_hashed_page( buf_page_mutex_exit(block); } -/******************************************************************//** -Remove one page from LRU list and put it to free list */ -void -buf_LRU_free_one_page( -/*==================*/ - buf_page_t* bpage) /*!< in/out: block, must contain a file page and - be in a state where it can be freed; there - may or may not be a hash index to the page */ +/** Remove one page from LRU list and put it to free list. +@param[in,out] bpage block, must contain a file page and be in + a freeable state; there may or may not be a + hash index to the page +@param[in] old_page_id page number before bpage->id was invalidated */ +void buf_LRU_free_one_page(buf_page_t* bpage, page_id_t old_page_id) { buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); - - rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, bpage->id); + rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, + old_page_id); BPageMutex* block_mutex = buf_page_get_mutex(bpage); ut_ad(buf_pool_mutex_own(buf_pool)); rw_lock_x_lock(hash_lock); + + while (buf_block_get_fix(bpage) > 0) { + /* Wait for other threads to release the fix count + before releasing the bpage from LRU list. */ + } + mutex_enter(block_mutex); + bpage->id = old_page_id; + if (buf_LRU_block_remove_hashed(bpage, true)) { buf_LRU_block_free_hashed_page((buf_block_t*) bpage); } diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index 1b5abe8f252..188d0aa24b6 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -63,13 +63,14 @@ buf_read_page_handle_error( buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); const bool uncompressed = (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE); + const page_id_t old_page_id = bpage->id; /* First unfix and release lock on the bpage */ buf_pool_mutex_enter(buf_pool); mutex_enter(buf_page_get_mutex(bpage)); ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ); - ut_ad(bpage->buf_fix_count == 0); + bpage->id.set_corrupt_id(); /* Set BUF_IO_NONE before we remove the block from LRU list */ buf_page_set_io_fix(bpage, BUF_IO_NONE); @@ -82,7 +83,7 @@ buf_read_page_handle_error( mutex_exit(buf_page_get_mutex(bpage)); /* remove the block from LRU list */ - buf_LRU_free_one_page(bpage); + buf_LRU_free_one_page(bpage, old_page_id); ut_ad(buf_pool->n_pend_reads > 0); buf_pool->n_pend_reads--; diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 086bfb12710..e75a1d9ec44 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 2019, 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 @@ -609,31 +609,27 @@ buf_block_buf_fix_inc_func( @return the count */ UNIV_INLINE ulint -buf_block_fix( - buf_page_t* bpage); +buf_block_fix(buf_page_t* bpage); /** Increments the bufferfix count. @param[in,out] block block to bufferfix @return the count */ UNIV_INLINE ulint -buf_block_fix( - buf_block_t* block); +buf_block_fix(buf_block_t* block); /** Decrements the bufferfix count. @param[in,out] bpage block to bufferunfix @return the remaining buffer-fix count */ UNIV_INLINE ulint -buf_block_unfix( - buf_page_t* bpage); +buf_block_unfix(buf_page_t* bpage); /** Decrements the bufferfix count. @param[in,out] block block to bufferunfix @return the remaining buffer-fix count */ UNIV_INLINE ulint -buf_block_unfix( - buf_block_t* block); +buf_block_unfix(buf_block_t* block); # ifdef UNIV_DEBUG /** Increments the bufferfix count. @@ -1435,7 +1431,7 @@ public: page_size_t size; /** Count of how manyfold this block is currently bufferfixed. */ - ib_uint32_t buf_fix_count; + int32 buf_fix_count; /** type of pending I/O operation; also protected by buf_pool->mutex for writes only */ diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 4f1c6a7110a..98026159b8a 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2014, 2017, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -950,10 +950,11 @@ buf_block_get_modify_clock( @return the count */ UNIV_INLINE ulint -buf_block_fix( - buf_page_t* bpage) +buf_block_fix(buf_page_t* bpage) { - return(my_atomic_add32((int32*) &bpage->buf_fix_count, 1) + 1); + return uint32(my_atomic_add32_explicit( + &bpage->buf_fix_count, 1, + MY_MEMORY_ORDER_RELAXED)) + 1; } /** Increments the bufferfix count. @@ -961,10 +962,30 @@ buf_block_fix( @return the count */ UNIV_INLINE ulint -buf_block_fix( - buf_block_t* block) +buf_block_fix(buf_block_t* block) { - return(buf_block_fix(&block->page)); + return buf_block_fix(&block->page); +} + +/** Get the bufferfix count. +@param[in] bpage block to bufferfix +@return the count */ +UNIV_INLINE +ulint +buf_block_get_fix(buf_page_t* bpage) +{ + return my_atomic_load32_explicit(&bpage->buf_fix_count, + MY_MEMORY_ORDER_RELAXED); +} + +/** Get the bufferfix count. +@param[in] bpage block to bufferfix +@return the count */ +UNIV_INLINE +ulint +buf_block_get_fix(buf_block_t* block) +{ + return buf_block_get_fix(&block->page); } /*******************************************************************//** @@ -998,12 +1019,13 @@ buf_block_buf_fix_inc_func( @return the remaining buffer-fix count */ UNIV_INLINE ulint -buf_block_unfix( - buf_page_t* bpage) +buf_block_unfix(buf_page_t* bpage) { - ulint count = my_atomic_add32((int32*) &bpage->buf_fix_count, -1) - 1; - ut_ad(count + 1 != 0); - return(count); + uint32 count = uint32(my_atomic_add32_explicit( + &bpage->buf_fix_count, + -1, MY_MEMORY_ORDER_RELAXED)); + ut_ad(count != 0); + return count - 1; } /** Decrements the bufferfix count. @@ -1011,10 +1033,9 @@ buf_block_unfix( @return the remaining buffer-fix count */ UNIV_INLINE ulint -buf_block_unfix( - buf_block_t* block) +buf_block_unfix(buf_block_t* block) { - return(buf_block_unfix(&block->page)); + return buf_block_unfix(&block->page); } /*******************************************************************//** diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index d81c95fd224..1efbb1f03ef 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -201,14 +201,12 @@ void buf_LRU_stat_update(void); /*=====================*/ -/******************************************************************//** -Remove one page from LRU list and put it to free list */ -void -buf_LRU_free_one_page( -/*==================*/ - buf_page_t* bpage) /*!< in/out: block, must contain a file page and - be in a state where it can be freed; there - may or may not be a hash index to the page */ +/** Remove one page from LRU list and put it to free list. +@param[in,out] bpage block, must contain a file page and be in + a freeable state; there may or may not be a + hash index to the page +@param[in] old_page_id page number before bpage->id was invalidated */ +void buf_LRU_free_one_page(buf_page_t* bpage, page_id_t old_page_id) MY_ATTRIBUTE((nonnull)); /******************************************************************//** diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h index 63299681823..27ffee03d4c 100644 --- a/storage/innobase/include/buf0types.h +++ b/storage/innobase/include/buf0types.h @@ -175,6 +175,12 @@ public: ut_ad(page_no <= 0xFFFFFFFFU); } + /** Set the FIL_NULL for the space and page_no */ + void set_corrupt_id() + { + m_space = m_page_no = ULINT32_UNDEFINED; + } + private: /** Tablespace id. */ diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc index 3bb351eed8f..3e65dc1d28b 100644 --- a/storage/innobase/row/row0row.cc +++ b/storage/innobase/row/row0row.cc @@ -980,7 +980,10 @@ row_search_on_row_ref( ut_a(dtuple_get_n_fields(ref) == dict_index_get_n_unique(index)); - btr_pcur_open(index, ref, PAGE_CUR_LE, mode, pcur, mtr); + if (btr_pcur_open(index, ref, PAGE_CUR_LE, mode, pcur, mtr) + != DB_SUCCESS) { + return FALSE; + } low_match = btr_pcur_get_low_match(pcur);