From eb09580b67ee19f7ac30c1a41c8307b9c7d482d1 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 28 May 2019 14:53:08 -0700 Subject: [PATCH 01/57] 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/57] 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/57] 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/57] 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/57] 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/57] 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/57] 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/57] 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/57] 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/57] 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/57] 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/57] 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/57] 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/57] 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/57] 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/57] 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 34b38ad726025b3ede5db0f5b7dfaaafc8d1e754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 12 Jun 2019 08:24:30 +0300 Subject: [PATCH 17/57] MDEV-19736: Galera test failure on Remove unneeded select to provider name. Provider can have different names and can be located on different directory on different environments. --- mysql-test/suite/wsrep/r/mdev_10186.result | 3 --- mysql-test/suite/wsrep/t/mdev_10186.test | 2 -- 2 files changed, 5 deletions(-) diff --git a/mysql-test/suite/wsrep/r/mdev_10186.result b/mysql-test/suite/wsrep/r/mdev_10186.result index 778c064d208..a21e77a2595 100644 --- a/mysql-test/suite/wsrep/r/mdev_10186.result +++ b/mysql-test/suite/wsrep/r/mdev_10186.result @@ -5,7 +5,4 @@ SELECT @@wsrep_on; @@wsrep_on 0 -SELECT @@GLOBAL.wsrep_provider; -@@GLOBAL.wsrep_provider -libgalera_smm.so SET @@GLOBAL.wsrep_cluster_address='gcomm://'; diff --git a/mysql-test/suite/wsrep/t/mdev_10186.test b/mysql-test/suite/wsrep/t/mdev_10186.test index 98ea5192634..63d34db7c42 100644 --- a/mysql-test/suite/wsrep/t/mdev_10186.test +++ b/mysql-test/suite/wsrep/t/mdev_10186.test @@ -7,7 +7,5 @@ --echo # SELECT @@wsrep_on; ---replace_regex /.*libgalera_smm.so/libgalera_smm.so/ -SELECT @@GLOBAL.wsrep_provider; SET @@GLOBAL.wsrep_cluster_address='gcomm://'; From c5fe1b8fc1ba401791d0c0e0c38ec5082fa97891 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 12 Jun 2019 12:17:13 +0530 Subject: [PATCH 18/57] 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 19/57] 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 20/57] 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 21/57] 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 22/57] 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 23/57] 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 24/57] 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 25/57] 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 26/57] 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); From d9fe615ef6862c85c5aada96d4f5b62b7093177c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 14 Jun 2019 07:16:53 +0300 Subject: [PATCH 27/57] spider_db_init(): Do not return uninitialized error_num If the allocation of spider_table_sts_threads failed, we would DBUG_RETURN(error_num) without having initialized it earlier. Pre-initialize error_num to HA_ERR_OUT_OF_MEM and remove a lot of assignments that thus became redundant. This error was introduced in 207594afac99e5e7de1e639d907ce57c53c02294 (Spider 3.3.13). --- storage/spider/spd_table.cc | 162 ++++++++++-------------------------- 1 file changed, 43 insertions(+), 119 deletions(-) diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index ec604b98fe8..83c5a37555f 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -6864,7 +6864,7 @@ int spider_panic( int spider_db_init( void *p ) { - int error_num, roop_count; + int error_num = HA_ERR_OUT_OF_MEM, roop_count; uint dbton_id = 0; handlerton *spider_hton = (handlerton *)p; DBUG_ENTER("spider_db_init"); @@ -6988,16 +6988,10 @@ int spider_db_init( #ifndef WITHOUT_SPIDER_BG_SEARCH if (pthread_attr_init(&spider_pt_attr)) - { - error_num = HA_ERR_OUT_OF_MEM; goto error_pt_attr_init; - } /* if (pthread_attr_setdetachstate(&spider_pt_attr, PTHREAD_CREATE_DETACHED)) - { - error_num = HA_ERR_OUT_OF_MEM; goto error_pt_attr_setstate; - } */ #endif @@ -7007,40 +7001,28 @@ int spider_db_init( if (mysql_mutex_init(spd_key_mutex_tbl, &spider_tbl_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_tbl_mutex_init; - } #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_thread_id_mutex, MY_MUTEX_INIT_FAST)) #else if (mysql_mutex_init(spd_key_thread_id, &spider_thread_id_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_thread_id_mutex_init; - } #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_conn_id_mutex, MY_MUTEX_INIT_FAST)) #else if (mysql_mutex_init(spd_key_conn_id, &spider_conn_id_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_conn_id_mutex_init; - } #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_ipport_conn_mutex, MY_MUTEX_INIT_FAST)) #else if (mysql_mutex_init(spd_key_mutex_ipport_count, &spider_ipport_conn_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_ipport_count_mutex_init; - } #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_init_error_tbl_mutex, MY_MUTEX_INIT_FAST)) @@ -7048,10 +7030,8 @@ int spider_db_init( if (mysql_mutex_init(spd_key_mutex_init_error_tbl, &spider_init_error_tbl_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_init_error_tbl_mutex_init; - } + #ifdef WITH_PARTITION_STORAGE_ENGINE #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_pt_share_mutex, MY_MUTEX_INIT_FAST)) @@ -7059,10 +7039,8 @@ int spider_db_init( if (mysql_mutex_init(spd_key_mutex_pt_share, &spider_pt_share_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_pt_share_mutex_init; - } + #endif #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_lgtm_tblhnd_share_mutex, MY_MUTEX_INIT_FAST)) @@ -7070,30 +7048,24 @@ int spider_db_init( if (mysql_mutex_init(spd_key_mutex_lgtm_tblhnd_share, &spider_lgtm_tblhnd_share_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_lgtm_tblhnd_share_mutex_init; - } + #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_conn_mutex, MY_MUTEX_INIT_FAST)) #else if (mysql_mutex_init(spd_key_mutex_conn, &spider_conn_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_conn_mutex_init; - } + #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_open_conn_mutex, MY_MUTEX_INIT_FAST)) #else if (mysql_mutex_init(spd_key_mutex_open_conn, &spider_open_conn_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_open_conn_mutex_init; - } + #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_hs_r_conn_mutex, MY_MUTEX_INIT_FAST)) @@ -7101,20 +7073,16 @@ int spider_db_init( if (mysql_mutex_init(spd_key_mutex_hs_r_conn, &spider_hs_r_conn_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_hs_r_conn_mutex_init; - } + #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_hs_w_conn_mutex, MY_MUTEX_INIT_FAST)) #else if (mysql_mutex_init(spd_key_mutex_hs_w_conn, &spider_hs_w_conn_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_hs_w_conn_mutex_init; - } + #endif #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_allocated_thds_mutex, MY_MUTEX_INIT_FAST)) @@ -7122,20 +7090,15 @@ int spider_db_init( if (mysql_mutex_init(spd_key_mutex_allocated_thds, &spider_allocated_thds_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_allocated_thds_mutex_init; - } + #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_mon_table_cache_mutex, MY_MUTEX_INIT_FAST)) #else if (mysql_mutex_init(spd_key_mutex_mon_table_cache, &spider_mon_table_cache_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_mon_table_cache_mutex_init; - } #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_mem_calc_mutex, MY_MUTEX_INIT_FAST)) @@ -7143,127 +7106,96 @@ int spider_db_init( if (mysql_mutex_init(spd_key_mutex_mem_calc, &spider_mem_calc_mutex, MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_mem_calc_mutex_init; - } - if( - my_hash_init(&spider_open_tables, spd_charset_utf8_bin, 32, 0, 0, - (my_hash_get_key) spider_tbl_get_key, 0, 0) - ) { - error_num = HA_ERR_OUT_OF_MEM; + if (my_hash_init(&spider_open_tables, spd_charset_utf8_bin, 32, 0, 0, + (my_hash_get_key) spider_tbl_get_key, 0, 0)) goto error_open_tables_hash_init; - } + spider_alloc_calc_mem_init(spider_open_tables, 143); spider_alloc_calc_mem(NULL, spider_open_tables, spider_open_tables.array.max_element * spider_open_tables.array.size_of_element); - if( - my_hash_init(&spider_init_error_tables, spd_charset_utf8_bin, 32, 0, 0, - (my_hash_get_key) spider_tbl_get_key, 0, 0) - ) { - error_num = HA_ERR_OUT_OF_MEM; + if (my_hash_init(&spider_init_error_tables, spd_charset_utf8_bin, 32, 0, 0, + (my_hash_get_key) spider_tbl_get_key, 0, 0)) goto error_init_error_tables_hash_init; - } + spider_alloc_calc_mem_init(spider_init_error_tables, 144); spider_alloc_calc_mem(NULL, spider_init_error_tables, spider_init_error_tables.array.max_element * spider_init_error_tables.array.size_of_element); #ifdef WITH_PARTITION_STORAGE_ENGINE - if( - my_hash_init(&spider_open_pt_share, spd_charset_utf8_bin, 32, 0, 0, - (my_hash_get_key) spider_pt_share_get_key, 0, 0) - ) { - error_num = HA_ERR_OUT_OF_MEM; + if (my_hash_init(&spider_open_pt_share, spd_charset_utf8_bin, 32, 0, 0, + (my_hash_get_key) spider_pt_share_get_key, 0, 0)) goto error_open_pt_share_hash_init; - } + spider_alloc_calc_mem_init(spider_open_pt_share, 145); spider_alloc_calc_mem(NULL, spider_open_pt_share, spider_open_pt_share.array.max_element * spider_open_pt_share.array.size_of_element); #endif - if( - my_hash_init(&spider_lgtm_tblhnd_share_hash, spd_charset_utf8_bin, - 32, 0, 0, - (my_hash_get_key) spider_lgtm_tblhnd_share_hash_get_key, 0, 0) - ) { - error_num = HA_ERR_OUT_OF_MEM; + if (my_hash_init(&spider_lgtm_tblhnd_share_hash, spd_charset_utf8_bin, + 32, 0, 0, + (my_hash_get_key) spider_lgtm_tblhnd_share_hash_get_key, + 0, 0)) goto error_lgtm_tblhnd_share_hash_init; - } + spider_alloc_calc_mem_init(spider_lgtm_tblhnd_share_hash, 245); spider_alloc_calc_mem(NULL, spider_lgtm_tblhnd_share_hash, spider_lgtm_tblhnd_share_hash.array.max_element * spider_lgtm_tblhnd_share_hash.array.size_of_element); - if( - my_hash_init(&spider_open_connections, spd_charset_utf8_bin, 32, 0, 0, - (my_hash_get_key) spider_conn_get_key, 0, 0) - ) { - error_num = HA_ERR_OUT_OF_MEM; + if (my_hash_init(&spider_open_connections, spd_charset_utf8_bin, 32, 0, 0, + (my_hash_get_key) spider_conn_get_key, 0, 0)) goto error_open_connections_hash_init; - } - if( - my_hash_init(&spider_ipport_conns, spd_charset_utf8_bin, 32, 0, 0, - (my_hash_get_key) spider_ipport_conn_get_key, spider_free_ipport_conn, 0) - ) { - error_num = HA_ERR_OUT_OF_MEM; + + if (my_hash_init(&spider_ipport_conns, spd_charset_utf8_bin, 32, 0, 0, + (my_hash_get_key) spider_ipport_conn_get_key, + spider_free_ipport_conn, 0)) goto error_ipport_conn__hash_init; - } + spider_alloc_calc_mem_init(spider_open_connections, 146); spider_alloc_calc_mem(NULL, spider_open_connections, spider_open_connections.array.max_element * spider_open_connections.array.size_of_element); #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if( - my_hash_init(&spider_hs_r_conn_hash, spd_charset_utf8_bin, 32, 0, 0, - (my_hash_get_key) spider_conn_get_key, 0, 0) - ) { - error_num = HA_ERR_OUT_OF_MEM; + if (my_hash_init(&spider_hs_r_conn_hash, spd_charset_utf8_bin, 32, 0, 0, + (my_hash_get_key) spider_conn_get_key, 0, 0)) goto error_hs_r_conn_hash_init; - } + spider_alloc_calc_mem_init(spider_hs_r_conn_hash, 147); spider_alloc_calc_mem(NULL, spider_hs_r_conn_hash, spider_hs_r_conn_hash.array.max_element * spider_hs_r_conn_hash.array.size_of_element); - if( - my_hash_init(&spider_hs_w_conn_hash, spd_charset_utf8_bin, 32, 0, 0, - (my_hash_get_key) spider_conn_get_key, 0, 0) - ) { - error_num = HA_ERR_OUT_OF_MEM; + if (my_hash_init(&spider_hs_w_conn_hash, spd_charset_utf8_bin, 32, 0, 0, + (my_hash_get_key) spider_conn_get_key, 0, 0)) goto error_hs_w_conn_hash_init; - } + spider_alloc_calc_mem_init(spider_hs_w_conn_hash, 148); spider_alloc_calc_mem(NULL, spider_hs_w_conn_hash, spider_hs_w_conn_hash.array.max_element * spider_hs_w_conn_hash.array.size_of_element); #endif - if( - my_hash_init(&spider_allocated_thds, spd_charset_utf8_bin, 32, 0, 0, - (my_hash_get_key) spider_allocated_thds_get_key, 0, 0) - ) { - error_num = HA_ERR_OUT_OF_MEM; + if (my_hash_init(&spider_allocated_thds, spd_charset_utf8_bin, 32, 0, 0, + (my_hash_get_key) spider_allocated_thds_get_key, 0, 0)) goto error_allocated_thds_hash_init; - } + spider_alloc_calc_mem_init(spider_allocated_thds, 149); spider_alloc_calc_mem(NULL, spider_allocated_thds, spider_allocated_thds.array.max_element * spider_allocated_thds.array.size_of_element); - if( - SPD_INIT_DYNAMIC_ARRAY2(&spider_mon_table_cache, sizeof(SPIDER_MON_KEY), - NULL, 64, 64, MYF(MY_WME)) - ) { - error_num = HA_ERR_OUT_OF_MEM; + if (SPD_INIT_DYNAMIC_ARRAY2(&spider_mon_table_cache, sizeof(SPIDER_MON_KEY), + NULL, 64, 64, MYF(MY_WME))) goto error_mon_table_cache_array_init; - } + spider_alloc_calc_mem_init(spider_mon_table_cache, 165); spider_alloc_calc_mem(NULL, spider_mon_table_cache, @@ -7293,10 +7225,7 @@ int spider_db_init( if (mysql_mutex_init(spd_key_mutex_udf_table_mon, &spider_udf_table_mon_mutexes[roop_count], MY_MUTEX_INIT_FAST)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_init_udf_table_mon_mutex; - } } for (roop_count = 0; roop_count < (int) spider_param_udf_table_mon_mutex_count(); @@ -7308,10 +7237,7 @@ int spider_db_init( if (mysql_cond_init(spd_key_cond_udf_table_mon, &spider_udf_table_mon_conds[roop_count], NULL)) #endif - { - error_num = HA_ERR_OUT_OF_MEM; goto error_init_udf_table_mon_cond; - } } for (roop_count = 0; roop_count < (int) spider_param_udf_table_mon_mutex_count(); @@ -7320,10 +7246,8 @@ int spider_db_init( if (my_hash_init(&spider_udf_table_mon_list_hash[roop_count], spd_charset_utf8_bin, 32, 0, 0, (my_hash_get_key) spider_udf_tbl_mon_list_key, 0, 0)) - { - error_num = HA_ERR_OUT_OF_MEM; goto error_init_udf_table_mon_list_hash; - } + spider_alloc_calc_mem_init(spider_udf_table_mon_list_hash, 150); spider_alloc_calc_mem(NULL, spider_udf_table_mon_list_hash, From 2cd45add27be30016693897debb261915dcd064c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 14 Jun 2019 07:34:25 +0300 Subject: [PATCH 28/57] MDEV-6275: Fix signed/unsigned comparison --- storage/spider/spd_db_mysql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 18e2d2acbd5..aa5c27a1f06 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -1986,7 +1986,7 @@ int spider_db_mbase::connect( } else if (!strcmp(tgt_host, "127.0.0.1") || !strcmp(tgt_host, glob_hostname)) { - if (tgt_port == *spd_mysqld_port) + if (tgt_port == long{*spd_mysqld_port}) { my_printf_error(ER_SPIDER_SAME_SERVER_LINK_NUM, ER_SPIDER_SAME_SERVER_LINK_STR2, MYF(0), From e5fab61a734667595a26c2f7984132f4f54f4693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 14 Jun 2019 07:53:42 +0300 Subject: [PATCH 29/57] MDEV-6275: Use a non-narrowing conversion On 32-bit systems, sizeof(uint)==sizeof(long). The C++11 narrowing cast would issue a warning due to the sign mismatch. --- storage/spider/spd_db_mysql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index aa5c27a1f06..58351195a61 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -1986,7 +1986,7 @@ int spider_db_mbase::connect( } else if (!strcmp(tgt_host, "127.0.0.1") || !strcmp(tgt_host, glob_hostname)) { - if (tgt_port == long{*spd_mysqld_port}) + if (tgt_port == (long) *spd_mysqld_port) { my_printf_error(ER_SPIDER_SAME_SERVER_LINK_NUM, ER_SPIDER_SAME_SERVER_LINK_STR2, MYF(0), From 2e73561c6c575a20003ca22733194d7ac12ff1ee Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 20 May 2019 19:08:03 +0200 Subject: [PATCH 30/57] MDEV-16804 SYSTEM VERSIONING columns not showing as GENERATED Closes #830 --- mysql-test/suite/versioning/r/create.result | 4 +- mysql-test/suite/versioning/r/simple.result | 132 ++++++++++++++++++++ mysql-test/suite/versioning/t/simple.test | 16 +++ sql/sql_show.cc | 6 + 4 files changed, 156 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/versioning/r/create.result b/mysql-test/suite/versioning/r/create.result index 0c68624355b..e74924ed075 100644 --- a/mysql-test/suite/versioning/r/create.result +++ b/mysql-test/suite/versioning/r/create.result @@ -54,7 +54,7 @@ character_octet_length NULL character_set_name NULL collation_name NULL column_key -extra INVISIBLE +extra STORED GENERATED, INVISIBLE column_comment start is_generated ALWAYS generation_expression ROW START @@ -69,7 +69,7 @@ character_octet_length NULL character_set_name NULL collation_name NULL column_key -extra INVISIBLE +extra STORED GENERATED, INVISIBLE column_comment end is_generated ALWAYS generation_expression ROW END diff --git a/mysql-test/suite/versioning/r/simple.result b/mysql-test/suite/versioning/r/simple.result index 7b42fed45c5..6a4ea469d1c 100644 --- a/mysql-test/suite/versioning/r/simple.result +++ b/mysql-test/suite/versioning/r/simple.result @@ -71,3 +71,135 @@ and d.dept_id = e.dept_id; emp_id dept_id name salary dept_id name 1 10 bill 2000 10 accounting drop table emp, dept; +create table t1 ( +a timestamp(6), +b timestamp(6) generated always as (a + interval 1 day), +c timestamp(6) generated always as (a + interval 1 month) stored, +d timestamp(6) generated always as row start, +e timestamp(6) generated always as row end, +period for system_time(d,e) +) with system versioning; +show columns from t1; +Field Type Null Key Default Extra +a timestamp(6) NO current_timestamp(6) on update current_timestamp(6) +b timestamp(6) YES NULL VIRTUAL GENERATED +c timestamp(6) YES NULL STORED GENERATED +d timestamp(6) NO NULL STORED GENERATED +e timestamp(6) NO NULL STORED GENERATED +select *,'---' from information_schema.columns where table_name='t1'; +TABLE_CATALOG def +TABLE_SCHEMA test +TABLE_NAME t1 +COLUMN_NAME a +ORDINAL_POSITION 1 +COLUMN_DEFAULT current_timestamp(6) +IS_NULLABLE NO +DATA_TYPE timestamp +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION 6 +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +COLUMN_TYPE timestamp(6) +COLUMN_KEY +EXTRA on update current_timestamp(6) +PRIVILEGES select,insert,update,references +COLUMN_COMMENT +IS_GENERATED NEVER +GENERATION_EXPRESSION NULL +--- --- +TABLE_CATALOG def +TABLE_SCHEMA test +TABLE_NAME t1 +COLUMN_NAME b +ORDINAL_POSITION 2 +COLUMN_DEFAULT NULL +IS_NULLABLE YES +DATA_TYPE timestamp +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION 6 +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +COLUMN_TYPE timestamp(6) +COLUMN_KEY +EXTRA VIRTUAL GENERATED +PRIVILEGES select,insert,update,references +COLUMN_COMMENT +IS_GENERATED ALWAYS +GENERATION_EXPRESSION `a` + interval 1 day +--- --- +TABLE_CATALOG def +TABLE_SCHEMA test +TABLE_NAME t1 +COLUMN_NAME c +ORDINAL_POSITION 3 +COLUMN_DEFAULT NULL +IS_NULLABLE YES +DATA_TYPE timestamp +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION 6 +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +COLUMN_TYPE timestamp(6) +COLUMN_KEY +EXTRA STORED GENERATED +PRIVILEGES select,insert,update,references +COLUMN_COMMENT +IS_GENERATED ALWAYS +GENERATION_EXPRESSION `a` + interval 1 month +--- --- +TABLE_CATALOG def +TABLE_SCHEMA test +TABLE_NAME t1 +COLUMN_NAME d +ORDINAL_POSITION 4 +COLUMN_DEFAULT NULL +IS_NULLABLE NO +DATA_TYPE timestamp +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION 6 +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +COLUMN_TYPE timestamp(6) +COLUMN_KEY +EXTRA STORED GENERATED +PRIVILEGES select,insert,update,references +COLUMN_COMMENT +IS_GENERATED ALWAYS +GENERATION_EXPRESSION ROW START +--- --- +TABLE_CATALOG def +TABLE_SCHEMA test +TABLE_NAME t1 +COLUMN_NAME e +ORDINAL_POSITION 5 +COLUMN_DEFAULT NULL +IS_NULLABLE NO +DATA_TYPE timestamp +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION 6 +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +COLUMN_TYPE timestamp(6) +COLUMN_KEY +EXTRA STORED GENERATED +PRIVILEGES select,insert,update,references +COLUMN_COMMENT +IS_GENERATED ALWAYS +GENERATION_EXPRESSION ROW END +--- --- +drop table t1; diff --git a/mysql-test/suite/versioning/t/simple.test b/mysql-test/suite/versioning/t/simple.test index d61e9ffd47c..be795577702 100644 --- a/mysql-test/suite/versioning/t/simple.test +++ b/mysql-test/suite/versioning/t/simple.test @@ -71,3 +71,19 @@ where d.dept_id = 10 and d.dept_id = e.dept_id; drop table emp, dept; + +# +# MDEV-16804 SYSTEM VERSIONING columns not showing as GENERATED +# +create table t1 ( + a timestamp(6), + b timestamp(6) generated always as (a + interval 1 day), + c timestamp(6) generated always as (a + interval 1 month) stored, + d timestamp(6) generated always as row start, + e timestamp(6) generated always as row end, + period for system_time(d,e) +) with system versioning; +show columns from t1; +query_vertical select *,'---' from information_schema.columns where table_name='t1'; +drop table t1; + diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 64770595348..1170aead53c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -6001,9 +6001,15 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, else if (field->flags & VERS_SYSTEM_FIELD) { if (field->flags & VERS_SYS_START_FLAG) + { table->field[21]->store(STRING_WITH_LEN("ROW START"), cs); + buf.set(STRING_WITH_LEN("STORED GENERATED"), cs); + } else + { table->field[21]->store(STRING_WITH_LEN("ROW END"), cs); + buf.set(STRING_WITH_LEN("STORED GENERATED"), cs); + } table->field[21]->set_notnull(); table->field[20]->store(STRING_WITH_LEN("ALWAYS"), cs); } From b40c2d2c512ee947625f85e893089b4cac1da970 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 14 Jun 2019 12:28:51 +0200 Subject: [PATCH 31/57] MDEV-19633 ASAN use-after-poison in tree_insert() in main.func_gconcat when copying the TREE, take into account that init_tree can internally adjust tree->size_of_element --- sql/item_sum.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sql/item_sum.cc b/sql/item_sum.cc index b4bfba0add3..ee53b242c83 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3482,11 +3482,15 @@ int copy_to_tree(void* key, element_count count __attribute__((unused)), bool Item_func_group_concat::repack_tree(THD *thd) { struct st_repack_tree st; + int size= tree->size_of_element; + if (!tree->offset_to_key) + size-= sizeof(void*); init_tree(&st.tree, (size_t) MY_MIN(thd->variables.max_heap_table_size, thd->variables.sortbuff_size/16), 0, - tree->size_of_element, group_concat_key_cmp_with_order, NULL, + size, group_concat_key_cmp_with_order, NULL, (void*) this, MYF(MY_THREAD_SPECIFIC)); + DBUG_ASSERT(tree->size_of_element == st.tree.size_of_element); st.table= table; st.len= 0; st.maxlen= (size_t)thd->variables.group_concat_max_len; From 3a0a570e0b01a0a23a2ff8e7b823d3540fba9025 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 12 Dec 2017 11:26:09 +1100 Subject: [PATCH 32/57] systemd: multi-instance changes to -defaults-group-suffix=.%I When the multi-instance systemd service file was chosen it effectively relied on /etc/my.cnf.d/my{instancename}.cnf file to define its configuration file. This is problematic if running along side a single instance mariadb service which has /etc/my.cnf that reads all configuration file /etc/my.cnf.d/*.cnf. To prevent the service from auto starting up if a user has this previous configuration ConditionPathExists=!@sysconf2dir@/my%I.cnf to ensure that a user with the previous configuration isn't started in a non-intended mode. Documentation in the service file (should be release notes too), described a recommended migration. A new approach was to use --defaults-group-suffix=.%I as an arguement to mysqld and let the user define a [mysqld.{instancename}] group within the configuration file. This way existing global mysqld configuration options are read with the instance name having special overrides of datadir, port, socket etc. A systemd environment variable MYSQLD_MULTI_INSTANCE is used in the defination as it give the user flexability to use multiple segregation mechanisms between services. This is used multiple times within the service which all needed to be kept consistent. Another notable change is mysql_install_db being part of the ExecStartPre. This provides and auto-initialization for users that run multiple instances. --- support-files/mariadb@.service.in | 147 +++++++++++++++++++++++------- 1 file changed, 112 insertions(+), 35 deletions(-) diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in index a2f5cff0828..6da55ddfab0 100644 --- a/support-files/mariadb@.service.in +++ b/support-files/mariadb@.service.in @@ -1,21 +1,99 @@ -# Multi instance version of mariadb. For if you run multiple versions at once. -# Also used for mariadb@bootstrap to bootstrap Galera. +# Multi instance version of MariaDB # -# create config file @sysconf2dir@/my{instancename}.cnf +# Use this if you run multiple instances of MariaDB on a single server. +# +# Copyright notice: # -# start as systemctl start mariadb@{instancename}.server - # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # -# Thanks to: -# Daniel Black -# Erkan Yanar -# David Strauss -# and probably others -# Inspired from https://gitweb.gentoo.org/repo/gentoo.git/tree/dev-db/mysql-init-scripts/files/mysqld_at.service +# MULTI INSTANCES +# +# When multiple instances of MariaDB are running on a server they need to +# ensure that they don't conflict with each other. This includes elements +# like network ports, sockets and data directories. The systemd environment +# variable MYSQLD_MULTI_INSTANCE controls each instance to ensure it is +# run independently. +# +# Suffix Mechanism (default): +# +# MYSQLD_MULTI_INSTANCE=--defaults-group-suffix=.%I +# +# With this option, the [mysqld.{instancename}] group is read from the default +# configuration file. +# +# Command Line Mechanism: +# +# MYSQLD_MULTI_INSTANCE="--socket=/var/run/mysqld/%I.sock \ +# --datadir=/var/lib/mysqld-multi/%I \ +# --skip-networking" +# +# This is a good way run multiple instance where there is little difference +# in configuration between instances. +# +# Configuration File Based Mechanism: +# +# MYSQLD_MULTI_INSTANCE=@sysconfdir@/my%I.cnf +# +# Here you need to create a file for each instance. Recommend the systemd +# configuration "ConditionPathExists=@sysconf@/my%I.cnf" at the same time to +# ensure the file exists for the instance before starting. +# +# APPLYING YOUR MULTI INSTANCE MECHANISM +# +# To apply one of the non-default multi-instance mechanisms, create a file +# "/etc/systemd/system/mariadb@.service.d/multi.conf" containing: +# +# [Service] +# Environment=MYSQLD_MULTI_INSTANCE="...." +# +# Include any other settings you which to override. Directives like Exec* are +# lists and adding a directive will append to the list. You can clear the list +# by starting with "Directive=" and no value. Follow this by the list that you +# do want. +# +# Then run "systemctl daemon-reload". +# +# CONFLICTING VARIABLES +# +# A number of MariaDB system variables may conflict. The main ones that need to +# be set because their default values will conflict are: +# * socket +# * port +# * datadir +# +# Galera will require: +# * wsrep_node_address +# * wsrep_cluster_address +# * ensure SST mechanisms don't conflict on network ports or temporary locations +# +# PRE-10.3 +# +# Before 10.3 MYSQLD_MULTI_INSTANCE was effectively --defaults-file=@sysconf2dir@/my%I.cnf +# As @sysconfdir@/my.cnf included these files it was a bad choice as an +# existing single instance would include all these files. If you want to +# continue a file based multi-instance mysqld, recommend the Configuration File +# Based Mechanism above and moving @sysconf2dir@/my%I.cnf files to @sysconfdir@/my%I.cnf. +# +# SELINUX +# +# As basic selinux rules are written around a single instance of MariaDB you may need +# to define labels for the files and network ports of all instances. +# +# See: https://mariadb.com/kb/en/library/what-to-do-if-mariadb-doesnt-start/#selinux +# +# STARTING +# +# Start the instance: systemctl start mariadb@{instancename}.service +# +# DOCUMENTATION: +# +# Read https://mariadb.com/kb/en/mariadb/systemd/ regarding customisation. +# +# Also see systemd man pages: systemd.unit(5), systemd.exec(5) and +# systemd.service(5) [Unit] Description=MariaDB @VERSION@ database server (multi-instance) @@ -23,7 +101,13 @@ Documentation=man:mysqld(8) Documentation=https://mariadb.com/kb/en/library/systemd/ After=network.target -ConditionPathExists=@sysconf2dir@/my%I.cnf +# Negated condition here is because 10.2 had @sysconf2dir@/my%I.cnf +# as the configuration difference for multiple instances. This condition here +# to prevent an accidental change during an upgrade in the case the user +# created these file(s). +# +## See Environment=MYSQLD_MULTI_INSTANCE below for current recommended options. +ConditionPathExists=!@sysconf2dir@/my%I.cnf [Install] WantedBy=multi-user.target @@ -56,7 +140,8 @@ CapabilityBoundingSet=CAP_IPC_LOCK # Prevent writes to /usr, /boot, and /etc ProtectSystem=full -# Doesn't yet work properly with SELinux enabled +# Requires kernel 4.14 or later and SELinux transition rule for mysqld_t +# (https://github.com/systemd/systemd/issues/3845) # NoNewPrivileges=true PrivateDevices=true @@ -75,34 +160,23 @@ PermissionsStartOnly=true ExecStartPre=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION%I" ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \ - VAR=`@bindir@/galera_recovery --defaults-file=@sysconf2dir@/my%I.cnf`; [ $? -eq 0 ] \ + VAR=`@bindir@/galera_recovery $MYSQLD_MULTI_INSTANCE`; [ $? -eq 0 ] \ && systemctl set-environment _WSREP_START_POSITION%I=$VAR || exit 1" -# Alternate: (remove ConditionPathExists above) -# use [mysqld.INSTANCENAME] as sections in my.cnf -# -#ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \ -# VAR=`@bindir@/galera_recovery --defaults-group-suffix=%I`; [ $? -eq 0 ] \ -# && systemctl set-environment _WSREP_START_POSITION%I=$VAR || exit 1" - # Needed to create system tables etc. -# ExecStartPre=@scriptdir@/mysql_install_db -u mysql +ExecStartPre=@scriptdir@/mysql_install_db $MYSQLD_MULTI_INSTANCE --user=mysql # Start main service -# MYSQLD_OPTS here is for users to set in /etc/systemd/system/mariadb@.service.d/MY_SPECIAL.conf -# Use the [Service] section and Environment="MYSQLD_OPTS=...". -# This isn't a replacement for my.cnf. -# _WSREP_NEW_CLUSTER is for the exclusive use of the script galera_new_cluster - -# Note: Place $MYSQLD_OPTS at the very end for its options to take precedence. - -ExecStart=@sbindir@/mysqld --defaults-file=@sysconf2dir@/my%I.cnf \ - $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION%I $MYSQLD_OPTS -# Alternate: (remove ConditionPathExists above) -# use [mysqld.INSTANCENAME] as sections in my.cnf +# A few variables are here: +# * MYSQLD_MULTI_INSTANCE - control how multiple instances are distinguisable +# * _WSREP_NEW_CLUSTER - for the exclusive use of the script galera_new_cluster +# * MYSQLD_OPTS - user definable extras - not a replacement for my.cnf # -# ExecStart=@sbindir@/mysqld --defaults-group-suffix=%I \ -# $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION%I $MYSQLD_OPTS +# Note 1: Place $MYSQLD_OPTS at the very end for its options to take precedence. +# Note 2: we set --basedir to prevent probes that might trigger SELinux alarms, +# per bug https://bugzilla.redhat.com/show_bug.cgi?id=547485 +ExecStart=@sbindir@/mysqld $MYSQLD_MULTI_INSTANCE --basedir=@prefix@ \ + $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION%I $MYSQLD_OPTS # Unset _WSREP_START_POSITION environment variable. ExecStartPost=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION%I" @@ -140,6 +214,9 @@ UMask=007 # LOAD DATA INFILE you can enable PrivateTmp=true for a little more security. PrivateTmp=false +# Controlling how multiple instances are separated. See top of this file. +Environment=MYSQLD_MULTI_INSTANCE=--defaults-group-suffix=.%I + ## ## Options previously available to be set via [mysqld_safe] ## that now needs to be set by systemd config files as mysqld_safe From 91f1694836b65afd7fe2f4a669106e51ee47612c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 18 Jan 2019 14:52:25 +1100 Subject: [PATCH 33/57] systemd: multi-instance not for Galera, User/Group flexible By removing Galera functionality, we remove PermissionsStartOnly=true and hence make this service more flexible for running multiple instances each on a different user. --- support-files/mariadb@.service.in | 59 ++++++++++++++----------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in index 6da55ddfab0..45608c6c424 100644 --- a/support-files/mariadb@.service.in +++ b/support-files/mariadb@.service.in @@ -17,9 +17,12 @@ # variable MYSQLD_MULTI_INSTANCE controls each instance to ensure it is # run independently. # +# This is not suitable for Galera as specialised SST recovery scripts are +# needed. +# # Suffix Mechanism (default): # -# MYSQLD_MULTI_INSTANCE=--defaults-group-suffix=.%I +# MYSQLD_MULTI_INSTANCE=--defaults-group-suffix=.%I --basedir=@prefix@ # # With this option, the [mysqld.{instancename}] group is read from the default # configuration file. @@ -56,6 +59,15 @@ # # Then run "systemctl daemon-reload". # +# Multi User Based Mechanism +# +# Create instances in users home directory with abstract socket: +# +# [Service] +# User=%I +# ProtectHome=false +# Environment=MYSQLD_MULTI_INSTANCE="--defaults-file=/home/%I/my%I.cnf --datadir=/home/%I/mysqldatadir --skip-networking --socket=@mysql-%I" +# # CONFLICTING VARIABLES # # A number of MariaDB system variables may conflict. The main ones that need to @@ -64,11 +76,6 @@ # * port # * datadir # -# Galera will require: -# * wsrep_node_address -# * wsrep_cluster_address -# * ensure SST mechanisms don't conflict on network ports or temporary locations -# # PRE-10.3 # # Before 10.3 MYSQLD_MULTI_INSTANCE was effectively --defaults-file=@sysconf2dir@/my%I.cnf @@ -131,9 +138,6 @@ PrivateNetwork=false ## Package maintainers ## -User=mysql -Group=mysql - # To allow memlock to be used as non-root user if set in configuration CapabilityBoundingSet=CAP_IPC_LOCK @@ -149,37 +153,16 @@ PrivateDevices=true # Prevent accessing /home, /root and /run/user ProtectHome=true -# Execute pre and post scripts as root, otherwise it does it as User= -PermissionsStartOnly=true - -# Perform automatic wsrep recovery. When server is started without wsrep, -# galera_recovery simply returns an empty string. In any case, however, -# the script is not expected to return with a non-zero status. -# It is always safe to unset _WSREP_START_POSITION%I environment variable. -# Do not panic if galera_recovery script is not available. (MDEV-10538) -ExecStartPre=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION%I" - -ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \ - VAR=`@bindir@/galera_recovery $MYSQLD_MULTI_INSTANCE`; [ $? -eq 0 ] \ - && systemctl set-environment _WSREP_START_POSITION%I=$VAR || exit 1" - # Needed to create system tables etc. -ExecStartPre=@scriptdir@/mysql_install_db $MYSQLD_MULTI_INSTANCE --user=mysql +ExecStartPre=@scriptdir@/mysql_install_db $MYSQLD_MULTI_INSTANCE # Start main service # A few variables are here: # * MYSQLD_MULTI_INSTANCE - control how multiple instances are distinguisable -# * _WSREP_NEW_CLUSTER - for the exclusive use of the script galera_new_cluster # * MYSQLD_OPTS - user definable extras - not a replacement for my.cnf # # Note 1: Place $MYSQLD_OPTS at the very end for its options to take precedence. -# Note 2: we set --basedir to prevent probes that might trigger SELinux alarms, -# per bug https://bugzilla.redhat.com/show_bug.cgi?id=547485 -ExecStart=@sbindir@/mysqld $MYSQLD_MULTI_INSTANCE --basedir=@prefix@ \ - $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION%I $MYSQLD_OPTS - -# Unset _WSREP_START_POSITION environment variable. -ExecStartPost=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION%I" +ExecStart=@sbindir@/mysqld $MYSQLD_MULTI_INSTANCE $MYSQLD_OPTS KillSignal=SIGTERM @@ -215,7 +198,17 @@ UMask=007 PrivateTmp=false # Controlling how multiple instances are separated. See top of this file. -Environment=MYSQLD_MULTI_INSTANCE=--defaults-group-suffix=.%I +# Note 1: This service isn't User=mysql be default so we need to be explicit. +# Note 2: we set --basedir to prevent probes that might trigger SELinux alarms, +# per bug https://bugzilla.redhat.com/show_bug.cgi?id=547485. Its as an option +# here as a user may want to use the MYSQLD_MULTI_INSTANCE to run multiple +# versions. +Environment=MYSQLD_MULTI_INSTANCE=--defaults-group-suffix=.%I --basedir=@prefix@ + +# While you can override these, you shouldn't leave them empty as that +# will default to root. +User=mysql +Group=mysql ## ## Options previously available to be set via [mysqld_safe] From 6e5c24663983a9d12e812af22414d01de32a6728 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 12 Feb 2019 12:13:14 +1100 Subject: [PATCH 34/57] MDEV-11670: ensure sysconfdir/sysconf2dir are not blank for mariadb@.service --- support-files/CMakeLists.txt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 43ab5787ceb..b04df4cd87e 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -90,8 +90,18 @@ IF(UNIX) SET(scriptdir ${INSTALL_SCRIPTDIRABS}) SET(libexecdir ${INSTALL_SBINDIRABS}) SET(pkgdatadir ${INSTALL_MYSQLSHAREDIRABS}) - SET(sysconfdir ${INSTALL_SYSCONFDIR}) - SET(sysconf2dir ${INSTALL_SYSCONF2DIR}) + IF(INSTALL_SYSCONFDIR) + SET(sysconfdir ${INSTALL_SYSCONFDIR}) + ELSEIF(DEFAULT_SYSCONFDIR) + SET(sysconfdir ${DEFAULT_SYSCONFDIR}) + ELSE() + SET(sysconfdir "/etc") + ENDIF() + IF(INSTALL_SYSCONFDIR) + SET(sysconf2dir ${INSTALL_SYSCONF2DIR}) + ELSE() + SET(sysconf2dir "${sysconfdir}/mysql") + ENDIF() CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql.server.sh ${CMAKE_CURRENT_BINARY_DIR}/mysql.server @ONLY) INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/mysql.server From 764a10a92606eaec7c1d55fc405837afdcec995c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 12 Feb 2019 12:14:01 +1100 Subject: [PATCH 35/57] MDEV-11670: mariadb@.service remove alias, clean up documentation/order --- support-files/mariadb@.service.in | 98 +++++++++++++++++++------------ 1 file changed, 62 insertions(+), 36 deletions(-) diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in index 45608c6c424..13982ad59da 100644 --- a/support-files/mariadb@.service.in +++ b/support-files/mariadb@.service.in @@ -2,6 +2,10 @@ # # Use this if you run multiple instances of MariaDB on a single server. # +# This systemd service is not suitable for Galera as specialised SST recovery +# scripts are needed. +# +# # Copyright notice: # # This file is free software; you can redistribute it and/or modify it @@ -9,40 +13,25 @@ # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # +# # MULTI INSTANCES # # When multiple instances of MariaDB are running on a server they need to # ensure that they don't conflict with each other. This includes elements -# like network ports, sockets and data directories. The systemd environment -# variable MYSQLD_MULTI_INSTANCE controls each instance to ensure it is -# run independently. +# like network ports, sockets and data directories listed under CONFLICTING +# VARIABLES below. The systemd environment variable MYSQLD_MULTI_INSTANCE +# controls each instance to ensure it is run independently. It is passed to +# mysqld and mysql_install # -# This is not suitable for Galera as specialised SST recovery scripts are -# needed. +# By default, a group suffix exists andw ithin the default configuration +# files, a group [mysqld.{instancename}] is read for each service. Other +# default groups, like [server.{instancename}] and [mariadb.{instancename}], +# are also read. For each instance, one of the groups will need to contain +# the conflicting variables listed below under CONFLICTING VARIABLES. # -# Suffix Mechanism (default): +# The MYSQLD_MULTI_INSTANCE environment used is: +# Environment='MYSQLD_MULTI_INSTANCE=--defaults-group-suffix=.%I --basedir=@prefix@' # -# MYSQLD_MULTI_INSTANCE=--defaults-group-suffix=.%I --basedir=@prefix@ -# -# With this option, the [mysqld.{instancename}] group is read from the default -# configuration file. -# -# Command Line Mechanism: -# -# MYSQLD_MULTI_INSTANCE="--socket=/var/run/mysqld/%I.sock \ -# --datadir=/var/lib/mysqld-multi/%I \ -# --skip-networking" -# -# This is a good way run multiple instance where there is little difference -# in configuration between instances. -# -# Configuration File Based Mechanism: -# -# MYSQLD_MULTI_INSTANCE=@sysconfdir@/my%I.cnf -# -# Here you need to create a file for each instance. Recommend the systemd -# configuration "ConditionPathExists=@sysconf@/my%I.cnf" at the same time to -# ensure the file exists for the instance before starting. # # APPLYING YOUR MULTI INSTANCE MECHANISM # @@ -55,18 +44,53 @@ # Include any other settings you which to override. Directives like Exec* are # lists and adding a directive will append to the list. You can clear the list # by starting with "Directive=" and no value. Follow this by the list that you -# do want. +# do want. See the systemd.unit(5) manual page for more information. # # Then run "systemctl daemon-reload". # -# Multi User Based Mechanism +# +# EXAMPLE MYSQLD_MULTI_INSTANCE CONFIGURATIONS +# +# Configuration File Based Mechanism: +# +# This has a configuration file per instance. +# +# [Unit] +# ConditionPathExists=@sysconfdir@/my.%I.cnf +# +# [Service] +# Environment=MYSQLD_MULTI_INSTANCE=--defaults-file=@sysconfdir@/my.%I.cnf +# +# Here you need to create a configuration file @sysconfdir@/my.%I.cnf for each +# instance, each containing the conflicting variables to separate instances. +# +# +# Multi User Based Mechanism: +# +# Here each user (the instance name) has their own mysql instance. # # Create instances in users home directory with abstract socket: # # [Service] # User=%I # ProtectHome=false -# Environment=MYSQLD_MULTI_INSTANCE="--defaults-file=/home/%I/my%I.cnf --datadir=/home/%I/mysqldatadir --skip-networking --socket=@mysql-%I" +# ExecStartPre= +# ExecStartPre=@scriptdir@/mysql_install_db $MYSQLD_MULTI_INSTANCE \ +# --auth-root-authentication-method=socket --auth-root-socket-user=%I +# Environment=MYSQLD_MULTI_INSTANCE="--defaults-file=/home/%I/my%I.cnf \ +# --datadir=/home/%I/mysqldatadir --skip-networking --socket=@mysql-%I" +# +# +# Command Line Mechanism: +# +# This is a good way run multiple instance where there is little difference +# in configuration between instances. +# +# [Service] +# Environment=MYSQLD_MULTI_INSTANCE="--socket=/var/run/mysqld/%I.sock \ +# --datadir=/var/lib/mysqld-multi/%I \ +# --skip-networking" +# # # CONFLICTING VARIABLES # @@ -76,6 +100,7 @@ # * port # * datadir # +# # PRE-10.3 # # Before 10.3 MYSQLD_MULTI_INSTANCE was effectively --defaults-file=@sysconf2dir@/my%I.cnf @@ -84,6 +109,7 @@ # continue a file based multi-instance mysqld, recommend the Configuration File # Based Mechanism above and moving @sysconf2dir@/my%I.cnf files to @sysconfdir@/my%I.cnf. # +# # SELINUX # # As basic selinux rules are written around a single instance of MariaDB you may need @@ -91,10 +117,12 @@ # # See: https://mariadb.com/kb/en/library/what-to-do-if-mariadb-doesnt-start/#selinux # +# # STARTING # # Start the instance: systemctl start mariadb@{instancename}.service # +# # DOCUMENTATION: # # Read https://mariadb.com/kb/en/mariadb/systemd/ regarding customisation. @@ -108,7 +136,7 @@ Documentation=man:mysqld(8) Documentation=https://mariadb.com/kb/en/library/systemd/ After=network.target -# Negated condition here is because 10.2 had @sysconf2dir@/my%I.cnf +# Negated condition here is because 10.3 and before had @sysconf2dir@/my%I.cnf # as the configuration difference for multiple instances. This condition here # to prevent an accidental change during an upgrade in the case the user # created these file(s). @@ -116,14 +144,12 @@ After=network.target ## See Environment=MYSQLD_MULTI_INSTANCE below for current recommended options. ConditionPathExists=!@sysconf2dir@/my%I.cnf + [Install] WantedBy=multi-user.target -Alias=mysql.service -Alias=mysqld.service [Service] - ############################################################################## ## Core requirements ## @@ -198,12 +224,12 @@ UMask=007 PrivateTmp=false # Controlling how multiple instances are separated. See top of this file. -# Note 1: This service isn't User=mysql be default so we need to be explicit. +# Note 1: This service isn't User=mysql by default so we need to be explicit. # Note 2: we set --basedir to prevent probes that might trigger SELinux alarms, # per bug https://bugzilla.redhat.com/show_bug.cgi?id=547485. Its as an option # here as a user may want to use the MYSQLD_MULTI_INSTANCE to run multiple # versions. -Environment=MYSQLD_MULTI_INSTANCE=--defaults-group-suffix=.%I --basedir=@prefix@ +Environment='MYSQLD_MULTI_INSTANCE=--defaults-group-suffix=.%I --basedir=@prefix@' # While you can override these, you shouldn't leave them empty as that # will default to root. From e22d2cfe58bac9847dbaa1f03827fe8ea564d443 Mon Sep 17 00:00:00 2001 From: faust Date: Wed, 13 Feb 2019 07:31:48 +1100 Subject: [PATCH 36/57] fix typo support-files/mariadb@.service.in Co-Authored-By: grooverdan --- support-files/mariadb@.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in index 13982ad59da..727c1b85301 100644 --- a/support-files/mariadb@.service.in +++ b/support-files/mariadb@.service.in @@ -23,7 +23,7 @@ # controls each instance to ensure it is run independently. It is passed to # mysqld and mysql_install # -# By default, a group suffix exists andw ithin the default configuration +# By default, a group suffix exists and within the default configuration # files, a group [mysqld.{instancename}] is read for each service. Other # default groups, like [server.{instancename}] and [mariadb.{instancename}], # are also read. For each instance, one of the groups will need to contain From 4ec302ebf86ed2f36bd072ee5b43f5e2b724136b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 14 Jun 2019 15:49:38 +0200 Subject: [PATCH 37/57] WolfSSL : Fix crosscompiling i386 on x86_64, on Linux --- extra/wolfssl/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extra/wolfssl/CMakeLists.txt b/extra/wolfssl/CMakeLists.txt index cf6715280e3..f3f09f631d7 100644 --- a/extra/wolfssl/CMakeLists.txt +++ b/extra/wolfssl/CMakeLists.txt @@ -6,7 +6,8 @@ ELSE() PROJECT(wolfssl C) ENDIF() -IF(MSVC AND (CMAKE_SIZEOF_VOID_P MATCHES 8)) +IF(CMAKE_SIZEOF_VOID_P MATCHES 8) +IF(MSVC) SET(WOLFSSL_INTELASM ON) ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") IF(CMAKE_C_COMPILER_ID MATCHES GNU AND CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) @@ -20,6 +21,7 @@ ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") SET(WOLFSSL_INTELASM ON) ENDIF() ENDIF() +ENDIF() SET(WOLFSSL_SRCDIR ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl/src) ADD_DEFINITIONS(${SSL_DEFINES}) From 1e3dc15d62c2f7f7d3afe6affb0db66c8515234d Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 4 Jun 2019 17:11:42 +0200 Subject: [PATCH 38/57] Use generated user_settings.h for WolfSSL, as recommended by WolfSSL documentation Apparently, WolfSSL wants to have *exactly* the same defines for the user of the library as the was when building library itself. A lot of #defines have an impact on ABI (structure sizes, alignment etc) --- .gitignore | 1 + cmake/ssl.cmake | 3 +- extra/wolfssl/CMakeLists.txt | 47 ++++++++++++-------------------- extra/wolfssl/user_settings.h.in | 33 ++++++++++++++++++++++ 4 files changed, 53 insertions(+), 31 deletions(-) create mode 100644 extra/wolfssl/user_settings.h.in diff --git a/.gitignore b/.gitignore index 0fb30cc3184..95aa3ae64d4 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,7 @@ extra/perror extra/replace extra/resolve_stack_dump extra/resolveip +extra/wolfssl/user_settings.h import_executables.cmake include/*.h.tmp include/config.h diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake index 7a571171eaf..bcb4a512126 100644 --- a/cmake/ssl.cmake +++ b/cmake/ssl.cmake @@ -49,12 +49,13 @@ ENDMACRO() MACRO (MYSQL_USE_BUNDLED_SSL) SET(INC_DIRS + ${CMAKE_BINARY_DIR}/extra/wolfssl ${CMAKE_SOURCE_DIR}/extra/wolfssl/wolfssl ${CMAKE_SOURCE_DIR}/extra/wolfssl/wolfssl/wolfssl ) SET(SSL_LIBRARIES wolfssl wolfcrypt) SET(SSL_INCLUDE_DIRS ${INC_DIRS}) - SET(SSL_DEFINES "-DHAVE_OPENSSL -DHAVE_WOLFSSL -DOPENSSL_ALL -DWOLFSSL_MYSQL_COMPATIBLE -DWC_NO_HARDEN") + SET(SSL_DEFINES "-DHAVE_OPENSSL -DHAVE_WOLFSSL -DWOLFSSL_USER_SETTINGS") SET(HAVE_ERR_remove_thread_state ON CACHE INTERNAL "wolfssl doesn't have ERR_remove_thread_state") SET(HAVE_EncryptAes128Ctr OFF CACHE INTERNAL "wolfssl does support AES-CTR, but differently from openssl") SET(HAVE_EncryptAes128Gcm OFF CACHE INTERNAL "wolfssl does not support AES-GCM") diff --git a/extra/wolfssl/CMakeLists.txt b/extra/wolfssl/CMakeLists.txt index f3f09f631d7..2cb3f1dd3d1 100644 --- a/extra/wolfssl/CMakeLists.txt +++ b/extra/wolfssl/CMakeLists.txt @@ -25,25 +25,6 @@ ENDIF() SET(WOLFSSL_SRCDIR ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl/src) ADD_DEFINITIONS(${SSL_DEFINES}) -ADD_DEFINITIONS( - -DHAVE_CRL - -DWOLFSSL_MYSQL_COMPATIBLE - -DHAVE_ECC - -DECC_TIMING_RESISTANT - -DBUILDING_WOLFSSL - -DHAVE_HASHDRBG - -DWOLFSSL_AES_DIRECT - -DWOLFSSL_SHA384 - -DWOLFSSL_SHA512 - -DWOLFSSL_SHA224 - -DSESSION_CERT - -DKEEP_OUR_CERT - -DWOLFSSL_STATIC_RSA - -DWC_RSA_BLINDING - -DHAVE_TLS_EXTENSIONS - -DHAVE_AES_ECB - -DWOLFSSL_AES_COUNTER - -DNO_WOLFSSL_STUB) SET(WOLFSSL_SOURCES ${WOLFSSL_SRCDIR}/crl.c @@ -53,7 +34,8 @@ SET(WOLFSSL_SOURCES ${WOLFSSL_SRCDIR}/wolfio.c ${WOLFSSL_SRCDIR}/ocsp.c ${WOLFSSL_SRCDIR}/ssl.c) -ADD_DEFINITIONS(-DWOLFSSL_LIB) +ADD_DEFINITIONS(-DWOLFSSL_LIB -DBUILDING_WOLFSSL) + INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl) IF(MSVC) # size_t to long truncation warning @@ -116,28 +98,31 @@ IF(NOT (MSVC AND CMAKE_C_COMPILER_ID MATCHES Clang) ENDIF() IF(WOLFSSL_FASTMATH) - ADD_DEFINITIONS(-DUSE_FAST_MATH) - # FP_MAX_BITS is set high solely to satisfy ssl_8k_key.test - # WolfSSL will use more stack space with it - ADD_DEFINITIONS(-DFP_MAX_BITS=16384) - SET(WOLFCRYPT_SOURCES ${WOLFCRYPT_SOURCES} ${WOLFCRYPT_SRCDIR}/tfm.c) + SET(USE_FAST_MATH 1) + SET(TFM_TIMING_RESISTANT 1) + # FP_MAX_BITS is set high solely to satisfy ssl_8k_key.test + # WolfSSL will use more stack space with it + SET(FP_MAX_BITS 16384) + SET(WOLFCRYPT_SOURCES ${WOLFCRYPT_SOURCES} ${WOLFCRYPT_SRCDIR}/tfm.c) ELSE() - SET(WOLFCRYPT_SOURCES ${WOLFCRYPT_SOURCES} ${WOLFCRYPT_SRCDIR}/integer.c) + SET(WOLFCRYPT_SOURCES ${WOLFCRYPT_SOURCES} ${WOLFCRYPT_SRCDIR}/integer.c) ENDIF() IF(WOLFSSL_INTELASM) - ADD_DEFINITIONS(-DWOLFSSL_AESNI) - SET(SSL_DEFINES "${SSL_DEFINES} -DWOLFSSL_AESNI" PARENT_SCOPE) + SET(WOLFSSL_AESNI 1) + LIST(APPEND WOLFCRYPT_SOURCES ${WOLFCRYPT_SRCDIR}/cpuid.c) IF(MSVC) LIST(APPEND WOLFCRYPT_SOURCES ${WOLFCRYPT_SRCDIR}/aes_asm.asm) IF(CMAKE_C_COMPILER_ID MATCHES Clang) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes") ELSE() - ADD_DEFINITIONS(-DHAVE_INTEL_RDSEED -DWOLFSSL_X86_64_BUILD) + SET(HAVE_INTEL_RDSEED 1) + SET(WOLFSSL_X86_64_BUILD 1) ENDIF() ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") - ADD_DEFINITIONS(-DHAVE_INTEL_RDSEED -DUSE_INTEL_SPEEDUP) + SET(HAVE_INTEL_RDSEED 1) + SET(USE_INTEL_SPEEDUP 1) LIST(APPEND WOLFCRYPT_SOURCES ${WOLFCRYPT_SRCDIR}/aes_asm.S ${WOLFCRYPT_SRCDIR}/sha512_asm.S @@ -146,5 +131,7 @@ IF(WOLFSSL_INTELASM) ENDIF() ENDIF() +CONFIGURE_FILE(user_settings.h.in user_settings.h) +INCLUDE_DIRECTORIES(${SSL_INCLUDE_DIRS}) ADD_CONVENIENCE_LIBRARY(wolfcrypt ${WOLFCRYPT_SOURCES}) diff --git a/extra/wolfssl/user_settings.h.in b/extra/wolfssl/user_settings.h.in new file mode 100644 index 00000000000..f44143517fa --- /dev/null +++ b/extra/wolfssl/user_settings.h.in @@ -0,0 +1,33 @@ +#ifndef WOLFSSL_USER_SETTINGS_H +#define WOLFSSL_USER_SETTINGS_H + +#define HAVE_CRL +#define WOLFSSL_MYSQL_COMPATIBLE +#define HAVE_ECC +#define ECC_TIMING_RESISTANT +#define HAVE_HASHDRBG +#define WOLFSSL_AES_DIRECT +#define WOLFSSL_SHA384 +#define WOLFSSL_SHA512 +#define WOLFSSL_SHA224 +#define SESSION_CERT +#define KEEP_OUR_CERT +#define WOLFSSL_STATIC_RSA +#define WC_RSA_BLINDING +#define HAVE_TLS_EXTENSIONS +#define HAVE_AES_ECB +#define WOLFSSL_AES_COUNTER +#define NO_WOLFSSL_STUB +#define OPENSSL_ALL + + +#cmakedefine WOLFSSL_AESNI +#cmakedefine USE_FAST_MATH +#cmakedefine TFM_TIMING_RESISTANT +#cmakedefine HAVE_INTEL_RDSEED +#cmakedefine USE_INTEL_SPEEDUP +#cmakedefine FP_MAX_BITS @FP_MAX_BITS@ +#cmakedefine USE_FAST_MATH +#cmakedefine WOLFSSL_X86_64_BUILD + +#endif /* WOLFSSL_USER_SETTINGS_H */ From 772c5f3c78fcdaea2169ba435bac8d851c7945c7 Mon Sep 17 00:00:00 2001 From: Varun Date: Fri, 14 Jun 2019 12:16:17 +0530 Subject: [PATCH 39/57] MDEV-19634: Assertion `0' failed in row_sel_convert_mysql_key_to_innobase, [Warning] InnoDB: Using a partial-field key prefix in search For a key with keyparts (k1,k2,k3) , if we are building a range over the keyparts we should make sure that if min_value/max_value for a keypart is not added to key buffer then the keyparts following should also not be allowed. --- mysql-test/main/range_innodb.result | 18 ++++++++++++++++++ mysql-test/main/range_innodb.test | 19 +++++++++++++++++++ sql/opt_range.h | 10 ++++++---- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/range_innodb.result b/mysql-test/main/range_innodb.result index 30161a2711d..8774a623826 100644 --- a/mysql-test/main/range_innodb.result +++ b/mysql-test/main/range_innodb.result @@ -80,3 +80,21 @@ ERROR HY000: Table definition has changed, please retry transaction DROP TABLE t0,t1; set @@global.debug_dbug="-d"; set @@optimizer_switch= @optimizer_switch_save; +# +# MDEV-19634: Assertion `0' failed in row_sel_convert_mysql_key_to_innobase, +# [Warning] InnoDB: Using a partial-field key prefix in search +# +CREATE TABLE t1 ( +pk INT, +a VARCHAR(1), +b INT, +PRIMARY KEY (pk), +KEY (a,b) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,'a',1),(2,'b',2); +explain SELECT a FROM t1 WHERE pk < 0 AND a <= 'w' and b > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index PRIMARY,a a 9 NULL 2 Using where; Using index +SELECT a FROM t1 WHERE pk < 0 AND a <= 'w' and b > 0; +a +drop table t1; diff --git a/mysql-test/main/range_innodb.test b/mysql-test/main/range_innodb.test index a17ef3f1146..2c225df27fe 100644 --- a/mysql-test/main/range_innodb.test +++ b/mysql-test/main/range_innodb.test @@ -87,3 +87,22 @@ select * from t1 where a=10 and b=10; DROP TABLE t0,t1; set @@global.debug_dbug="-d"; set @@optimizer_switch= @optimizer_switch_save; + +--echo # +--echo # MDEV-19634: Assertion `0' failed in row_sel_convert_mysql_key_to_innobase, +--echo # [Warning] InnoDB: Using a partial-field key prefix in search +--echo # + +CREATE TABLE t1 ( + pk INT, + a VARCHAR(1), + b INT, + PRIMARY KEY (pk), + KEY (a,b) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES (1,'a',1),(2,'b',2); + +explain SELECT a FROM t1 WHERE pk < 0 AND a <= 'w' and b > 0; +SELECT a FROM t1 WHERE pk < 0 AND a <= 'w' and b > 0; +drop table t1; diff --git a/sql/opt_range.h b/sql/opt_range.h index ae0e3822272..73def7bde92 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -459,8 +459,9 @@ public: uint res= key_tree->store_min(key[key_tree->part].store_length, range_key, *range_key_flag); // add flags only if a key_part is written to the buffer - if (res) - *range_key_flag|= key_tree->min_flag; + if (!res) + return 0; + *range_key_flag|= key_tree->min_flag; if (key_tree->next_key_part && key_tree->next_key_part->type == SEL_ARG::KEY_RANGE && key_tree->part != last_part && @@ -482,8 +483,9 @@ public: SEL_ARG *key_tree= last(); uint res=key_tree->store_max(key[key_tree->part].store_length, range_key, *range_key_flag); - if (res) - (*range_key_flag)|= key_tree->max_flag; + if (!res) + return 0; + *range_key_flag|= key_tree->max_flag; if (key_tree->next_key_part && key_tree->next_key_part->type == SEL_ARG::KEY_RANGE && key_tree->part != last_part && From bf90a486c367a10b66c20fba4bfe64d378fc3238 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 14 Jun 2019 23:52:13 +0200 Subject: [PATCH 40/57] Do not use LEX_CSTRING in printf-like function --- storage/rocksdb/ha_rocksdb.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index c80722f22eb..1f7d19167d8 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -8745,7 +8745,7 @@ int ha_rocksdb::check(THD *const thd, HA_CHECK_OPT *const check_opt) { int res; // NO_LINT_DEBUG sql_print_verbose_info("CHECKTABLE %s: Checking index %s", table_name, - table->key_info[keyno].name); + table->key_info[keyno].name.str); while (1) { if (!rows) res = index_first(table->record[0]); From bff7cf9df8349a80a337c94ea55ceaa3daf3d72f Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Sat, 15 Jun 2019 18:57:07 +0200 Subject: [PATCH 41/57] Fix of fail of period.updtae with ps protocol. --- sql/sql_update.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index a193d501c1e..b16c49cf17a 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -181,6 +181,11 @@ static bool check_fields(THD *thd, TABLE_LIST *table, List &items, if (table->has_period()) { + if (table->is_view_or_derived()) + { + my_error(ER_IT_IS_A_VIEW, MYF(0), table->table_name.str); + return TRUE; + } DBUG_ASSERT(thd->lex->sql_command == SQLCOM_UPDATE); for (List_iterator_fast it(items); (item=it++);) { From daf333abcfc056b9fc85ec8883ef9e949b0ad8d4 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 17 Jun 2019 11:20:31 +0300 Subject: [PATCH 42/57] Rename of stat table tried to rename open table. When compiling with -DEXTRA_DEBUG and run main.stat_tables_missing on go the warning: Warning: Table: ./mysql/column_stats is open on rename old_table This happened because rename_table_in_stat_tables() re-open the table that was to be renamed. Fixed by moving update of stat tables after all renames has been made. --- sql/sql_table.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 41687de5c8e..f2be573d984 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9157,11 +9157,6 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list, close_all_tables_for_name(thd, table->s, HA_EXTRA_PREPARE_FOR_RENAME, NULL); - (void) rename_table_in_stat_tables(thd, &alter_ctx->db, - &alter_ctx->table_name, - &alter_ctx->new_db, - &alter_ctx->new_alias); - if (mysql_rename_table(old_db_type, &alter_ctx->db, &alter_ctx->table_name, &alter_ctx->new_db, &alter_ctx->new_alias, 0)) error= -1; @@ -9178,6 +9173,12 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list, NO_FK_CHECKS); error= -1; } + /* Update stat tables last. This is to be able to handle rename of a stat table */ + if (error == 0) + (void) rename_table_in_stat_tables(thd, &alter_ctx->db, + &alter_ctx->table_name, + &alter_ctx->new_db, + &alter_ctx->new_alias); } if (likely(!error)) From 7ad1e4a5469bffeef93dca2623545dd7c83d4f70 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 17 Jun 2019 12:26:15 +0200 Subject: [PATCH 43/57] fix tests, failing after daf333abcfc --- mysql-test/suite/plugins/r/server_audit.result | 2 +- mysql-test/suite/plugins/r/thread_pool_server_audit.result | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index 39614b4505c..215625c4500 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -293,10 +293,10 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0 TIME,HOSTNAME,root,localhost,ID,ID,READ,test,t2, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0 TIME,HOSTNAME,root,localhost,ID,ID,ALTER,test,t1, +TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,table_stats, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,column_stats, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats, -TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0 diff --git a/mysql-test/suite/plugins/r/thread_pool_server_audit.result b/mysql-test/suite/plugins/r/thread_pool_server_audit.result index 1a3a7d4c5bf..8c6ece53227 100644 --- a/mysql-test/suite/plugins/r/thread_pool_server_audit.result +++ b/mysql-test/suite/plugins/r/thread_pool_server_audit.result @@ -266,10 +266,10 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0 TIME,HOSTNAME,root,localhost,ID,ID,READ,test,t2, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0 TIME,HOSTNAME,root,localhost,ID,ID,ALTER,test,t1, +TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,table_stats, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,column_stats, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats, -TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0 From b3f3b3eaca0942610e3d566eb0781cbde3823b57 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 15 Jun 2019 21:30:44 +0200 Subject: [PATCH 44/57] fix versioning.simple for embedded --- mysql-test/suite/versioning/r/simple.result | 217 ++++++++++---------- mysql-test/suite/versioning/t/simple.test | 2 +- 2 files changed, 107 insertions(+), 112 deletions(-) diff --git a/mysql-test/suite/versioning/r/simple.result b/mysql-test/suite/versioning/r/simple.result index 6a4ea469d1c..df47f80c9e9 100644 --- a/mysql-test/suite/versioning/r/simple.result +++ b/mysql-test/suite/versioning/r/simple.result @@ -86,120 +86,115 @@ b timestamp(6) YES NULL VIRTUAL GENERATED c timestamp(6) YES NULL STORED GENERATED d timestamp(6) NO NULL STORED GENERATED e timestamp(6) NO NULL STORED GENERATED -select *,'---' from information_schema.columns where table_name='t1'; -TABLE_CATALOG def -TABLE_SCHEMA test -TABLE_NAME t1 -COLUMN_NAME a -ORDINAL_POSITION 1 -COLUMN_DEFAULT current_timestamp(6) -IS_NULLABLE NO -DATA_TYPE timestamp -CHARACTER_MAXIMUM_LENGTH NULL -CHARACTER_OCTET_LENGTH NULL -NUMERIC_PRECISION NULL -NUMERIC_SCALE NULL -DATETIME_PRECISION 6 -CHARACTER_SET_NAME NULL -COLLATION_NAME NULL -COLUMN_TYPE timestamp(6) -COLUMN_KEY -EXTRA on update current_timestamp(6) -PRIVILEGES select,insert,update,references -COLUMN_COMMENT -IS_GENERATED NEVER -GENERATION_EXPRESSION NULL +select table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,is_nullable,data_type,character_maximum_length,character_octet_length,numeric_precision,numeric_scale,datetime_precision,character_set_name,collation_name,column_type,column_key,extra,column_comment,is_generated,generation_expression,'---' from information_schema.columns where table_name='t1'; +table_catalog def +table_schema test +table_name t1 +column_name a +ordinal_position 1 +column_default current_timestamp(6) +is_nullable NO +data_type timestamp +character_maximum_length NULL +character_octet_length NULL +numeric_precision NULL +numeric_scale NULL +datetime_precision 6 +character_set_name NULL +collation_name NULL +column_type timestamp(6) +column_key +extra on update current_timestamp(6) +column_comment +is_generated NEVER +generation_expression NULL --- --- -TABLE_CATALOG def -TABLE_SCHEMA test -TABLE_NAME t1 -COLUMN_NAME b -ORDINAL_POSITION 2 -COLUMN_DEFAULT NULL -IS_NULLABLE YES -DATA_TYPE timestamp -CHARACTER_MAXIMUM_LENGTH NULL -CHARACTER_OCTET_LENGTH NULL -NUMERIC_PRECISION NULL -NUMERIC_SCALE NULL -DATETIME_PRECISION 6 -CHARACTER_SET_NAME NULL -COLLATION_NAME NULL -COLUMN_TYPE timestamp(6) -COLUMN_KEY -EXTRA VIRTUAL GENERATED -PRIVILEGES select,insert,update,references -COLUMN_COMMENT -IS_GENERATED ALWAYS -GENERATION_EXPRESSION `a` + interval 1 day +table_catalog def +table_schema test +table_name t1 +column_name b +ordinal_position 2 +column_default NULL +is_nullable YES +data_type timestamp +character_maximum_length NULL +character_octet_length NULL +numeric_precision NULL +numeric_scale NULL +datetime_precision 6 +character_set_name NULL +collation_name NULL +column_type timestamp(6) +column_key +extra VIRTUAL GENERATED +column_comment +is_generated ALWAYS +generation_expression `a` + interval 1 day --- --- -TABLE_CATALOG def -TABLE_SCHEMA test -TABLE_NAME t1 -COLUMN_NAME c -ORDINAL_POSITION 3 -COLUMN_DEFAULT NULL -IS_NULLABLE YES -DATA_TYPE timestamp -CHARACTER_MAXIMUM_LENGTH NULL -CHARACTER_OCTET_LENGTH NULL -NUMERIC_PRECISION NULL -NUMERIC_SCALE NULL -DATETIME_PRECISION 6 -CHARACTER_SET_NAME NULL -COLLATION_NAME NULL -COLUMN_TYPE timestamp(6) -COLUMN_KEY -EXTRA STORED GENERATED -PRIVILEGES select,insert,update,references -COLUMN_COMMENT -IS_GENERATED ALWAYS -GENERATION_EXPRESSION `a` + interval 1 month +table_catalog def +table_schema test +table_name t1 +column_name c +ordinal_position 3 +column_default NULL +is_nullable YES +data_type timestamp +character_maximum_length NULL +character_octet_length NULL +numeric_precision NULL +numeric_scale NULL +datetime_precision 6 +character_set_name NULL +collation_name NULL +column_type timestamp(6) +column_key +extra STORED GENERATED +column_comment +is_generated ALWAYS +generation_expression `a` + interval 1 month --- --- -TABLE_CATALOG def -TABLE_SCHEMA test -TABLE_NAME t1 -COLUMN_NAME d -ORDINAL_POSITION 4 -COLUMN_DEFAULT NULL -IS_NULLABLE NO -DATA_TYPE timestamp -CHARACTER_MAXIMUM_LENGTH NULL -CHARACTER_OCTET_LENGTH NULL -NUMERIC_PRECISION NULL -NUMERIC_SCALE NULL -DATETIME_PRECISION 6 -CHARACTER_SET_NAME NULL -COLLATION_NAME NULL -COLUMN_TYPE timestamp(6) -COLUMN_KEY -EXTRA STORED GENERATED -PRIVILEGES select,insert,update,references -COLUMN_COMMENT -IS_GENERATED ALWAYS -GENERATION_EXPRESSION ROW START +table_catalog def +table_schema test +table_name t1 +column_name d +ordinal_position 4 +column_default NULL +is_nullable NO +data_type timestamp +character_maximum_length NULL +character_octet_length NULL +numeric_precision NULL +numeric_scale NULL +datetime_precision 6 +character_set_name NULL +collation_name NULL +column_type timestamp(6) +column_key +extra STORED GENERATED +column_comment +is_generated ALWAYS +generation_expression ROW START --- --- -TABLE_CATALOG def -TABLE_SCHEMA test -TABLE_NAME t1 -COLUMN_NAME e -ORDINAL_POSITION 5 -COLUMN_DEFAULT NULL -IS_NULLABLE NO -DATA_TYPE timestamp -CHARACTER_MAXIMUM_LENGTH NULL -CHARACTER_OCTET_LENGTH NULL -NUMERIC_PRECISION NULL -NUMERIC_SCALE NULL -DATETIME_PRECISION 6 -CHARACTER_SET_NAME NULL -COLLATION_NAME NULL -COLUMN_TYPE timestamp(6) -COLUMN_KEY -EXTRA STORED GENERATED -PRIVILEGES select,insert,update,references -COLUMN_COMMENT -IS_GENERATED ALWAYS -GENERATION_EXPRESSION ROW END +table_catalog def +table_schema test +table_name t1 +column_name e +ordinal_position 5 +column_default NULL +is_nullable NO +data_type timestamp +character_maximum_length NULL +character_octet_length NULL +numeric_precision NULL +numeric_scale NULL +datetime_precision 6 +character_set_name NULL +collation_name NULL +column_type timestamp(6) +column_key +extra STORED GENERATED +column_comment +is_generated ALWAYS +generation_expression ROW END --- --- drop table t1; diff --git a/mysql-test/suite/versioning/t/simple.test b/mysql-test/suite/versioning/t/simple.test index be795577702..b550b3967d9 100644 --- a/mysql-test/suite/versioning/t/simple.test +++ b/mysql-test/suite/versioning/t/simple.test @@ -84,6 +84,6 @@ create table t1 ( period for system_time(d,e) ) with system versioning; show columns from t1; -query_vertical select *,'---' from information_schema.columns where table_name='t1'; +query_vertical select table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,is_nullable,data_type,character_maximum_length,character_octet_length,numeric_precision,numeric_scale,datetime_precision,character_set_name,collation_name,column_type,column_key,extra,column_comment,is_generated,generation_expression,'---' from information_schema.columns where table_name='t1'; drop table t1; From 379ffc6eaa64d1e9d195a9c1931c50ac053e261a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 14 Jun 2019 19:52:00 +0200 Subject: [PATCH 45/57] MDEV-19765 Bug in CMakeLists.txt introduced by MDEV-11670 fix a typo followup for 6e5c2466398 --- support-files/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index b04df4cd87e..3655c87b94e 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -97,7 +97,7 @@ IF(UNIX) ELSE() SET(sysconfdir "/etc") ENDIF() - IF(INSTALL_SYSCONFDIR) + IF(INSTALL_SYSCONF2DIR) SET(sysconf2dir ${INSTALL_SYSCONF2DIR}) ELSE() SET(sysconf2dir "${sysconfdir}/mysql") From d13080133f6de9d89975b4c1f09615d47a10748d Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 11 Jun 2019 12:44:16 +0200 Subject: [PATCH 46/57] MDEV-14101 Provide an option to select TLS protocol version Server and command line tools now support option --tls_version to specify the TLS version between client and server. Valid values are TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3 or a combination of them. E.g. --tls_version=TLSv1.3 --tls_version=TLSv1.2,TLSv1.3 In case there is a gap between versions, the lowest version will be used: --tls_version=TLSv1.1,TLSv1.3 -> Only TLSv1.1 will be available. If the used TLS library doesn't support the specified TLS version, it will use the default configuration. Limitations: SSLv3 is not supported. The default configuration doesn't support TLSv1.0 anymore. TLSv1.3 protocol currently is only supported by OpenSSL 1.1.0 (client and server) and GnuTLS 3.6.5 (client only). Overview of TLS implementations and protocols Server: +-----------+-----------------------------------------+ | Library | Supported TLS versions | +-----------+-----------------------------------------+ | WolfSSL | TLSv1.1, TLSv1,2 | +-----------+-----------------------------------------+ | OpenSSL | (TLSv1.0), TLSv1.1, TLSv1,2, TLSv1.3 | +-----------+-----------------------------------------+ | LibreSSL | (TLSv1.0), TLSv1.1, TLSv1,2, TLSv1.3 | +-----------+-----------------------------------------+ Client (MariaDB Connector/C) +-----------+-----------------------------------------+ | Library | Supported TLS versions | +-----------+-----------------------------------------+ | GnuTLS | (TLSv1.0), TLSv1.1, TLSv1.2, TLSv1.3 | +-----------+-----------------------------------------+ | Schannel | (TLSv1.0), TLSv1.1, TLSv1.2 | +-----------+-----------------------------------------+ | OpenSSL | (TLSv1.0), TLSv1.1, TLSv1,2, TLSv1.3 | +-----------+-----------------------------------------+ | LibreSSL | (TLSv1.0), TLSv1.1, TLSv1,2, TLSv1.3 | +-----------+-----------------------------------------+ --- client/client_priv.h | 2 +- client/mysql.cc | 1 + client/mysqladmin.cc | 1 + client/mysqlbinlog.cc | 1 + client/mysqldump.c | 1 + client/mysqlimport.c | 1 + client/mysqlshow.c | 1 + client/mysqltest.cc | 1 + extra/mariabackup/xtrabackup.cc | 2 + include/sslopt-longopts.h | 5 ++ include/sslopt-vars.h | 1 + include/violite.h | 11 +++- mysql-test/main/mysqld--help.result | 2 + mysql-test/main/mysqld--help.test | 2 +- mysql-test/main/openssl_6975.test | 24 ++++---- mysql-test/main/tls_version.opt | 1 + mysql-test/main/tls_version.result | 14 +++++ mysql-test/main/tls_version.test | 24 ++++++++ .../suite/sys_vars/inc/sysvars_server.inc | 2 + .../sys_vars/r/sysvars_server_embedded.result | 12 ++++ .../r/sysvars_server_notembedded.result | 12 ++++ sql/mysqld.cc | 10 ++-- sql/mysqld.h | 2 + sql/sys_vars.cc | 23 +++++++ vio/viosslfactories.c | 60 ++++++++++++++++--- 25 files changed, 189 insertions(+), 27 deletions(-) create mode 100644 mysql-test/main/tls_version.opt create mode 100644 mysql-test/main/tls_version.result create mode 100644 mysql-test/main/tls_version.test diff --git a/client/client_priv.h b/client/client_priv.h index 5b6b31ccda9..3ad46cf4b9b 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -46,7 +46,7 @@ enum options_client OPT_MAX_ALLOWED_PACKET, OPT_NET_BUFFER_LENGTH, OPT_SELECT_LIMIT, OPT_MAX_JOIN_SIZE, OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH, - OPT_SSL_CIPHER, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE, + OPT_SSL_CIPHER, OPT_TLS_VERSION, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE, OPT_DELETE_MASTER_LOGS, OPT_COMPACT, OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL, OPT_FRM, OPT_SKIP_OPTIMIZATION, diff --git a/client/mysql.cc b/client/mysql.cc index f1311991afe..c38ce6bc962 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1363,6 +1363,7 @@ static bool do_connect(MYSQL *mysql, const char *host, const char *user, opt_ssl_capath, opt_ssl_cipher); mysql_options(mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl); mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath); + mysql_options(mysql, MARIADB_OPT_TLS_VERSION, opt_tls_version); } mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (char*)&opt_ssl_verify_server_cert); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 3ad6ae40ab2..10b56f10228 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -359,6 +359,7 @@ int main(int argc,char *argv[]) opt_ssl_capath, opt_ssl_cipher); mysql_options(&mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl); mysql_options(&mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath); + mysql_options(&mysql, MARIADB_OPT_TLS_VERSION, opt_tls_version); } mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (char*)&opt_ssl_verify_server_cert); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 11566a8b628..d28de8aeda6 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -2126,6 +2126,7 @@ static Exit_status safe_connect() opt_ssl_capath, opt_ssl_cipher); mysql_options(mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl); mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath); + mysql_options(mysql, MARIADB_OPT_TLS_VERSION, opt_tls_version); } mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (char*)&opt_ssl_verify_server_cert); diff --git a/client/mysqldump.c b/client/mysqldump.c index f1d59b449af..38db869c7ac 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1709,6 +1709,7 @@ static int connect_to_db(char *host, char *user,char *passwd) opt_ssl_capath, opt_ssl_cipher); mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRL, opt_ssl_crl); mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath); + mysql_options(&mysql_connection, MARIADB_OPT_TLS_VERSION, opt_tls_version); } mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (char*)&opt_ssl_verify_server_cert); diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 3e250bdd9ed..619def5f123 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -448,6 +448,7 @@ static MYSQL *db_connect(char *host, char *database, opt_ssl_capath, opt_ssl_cipher); mysql_options(mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl); mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath); + mysql_options(mysql, MARIADB_OPT_TLS_VERSION, opt_tls_version); } mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (char*)&opt_ssl_verify_server_cert); diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 54c2a6e39fa..9885b219171 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -122,6 +122,7 @@ int main(int argc, char **argv) opt_ssl_capath, opt_ssl_cipher); mysql_options(&mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl); mysql_options(&mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath); + mysql_options(&mysql, MARIADB_OPT_TLS_VERSION, opt_tls_version); } mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (char*)&opt_ssl_verify_server_cert); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index be4080384c4..4b663ebd2cd 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -6068,6 +6068,7 @@ void do_connect(struct st_command *command) opt_ssl_capath, ssl_cipher ? ssl_cipher : opt_ssl_cipher); mysql_options(con_slot->mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl); mysql_options(con_slot->mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath); + mysql_options(con_slot->mysql, MARIADB_OPT_TLS_VERSION, opt_tls_version); #if MYSQL_VERSION_ID >= 50000 /* Turn on ssl_verify_server_cert only if host is "localhost" */ opt_ssl_verify_server_cert= !strcmp(ds_host.str, "localhost"); diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 24bc739ca57..f0388048cdd 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -199,6 +199,7 @@ static char* log_ignored_opt; extern my_bool opt_use_ssl; +extern char *opt_tls_version; my_bool opt_ssl_verify_server_cert; my_bool opt_extended_validation; my_bool opt_encrypted_backup; @@ -830,6 +831,7 @@ enum options_xtrabackup OPT_XTRA_CHECK_PRIVILEGES }; + struct my_option xb_client_options[] = { {"verbose", 'V', "display verbose output", diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h index be64e7f6590..d0278a1645d 100644 --- a/include/sslopt-longopts.h +++ b/include/sslopt-longopts.h @@ -46,6 +46,11 @@ "Certificate revocation list path (implies --ssl).", &opt_ssl_crlpath, &opt_ssl_crlpath, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"tls-version", OPT_TLS_VERSION, + "TLS protocol version for secure connection.", + &opt_tls_version, &opt_tls_version, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, + #ifdef MYSQL_CLIENT {"ssl-verify-server-cert", OPT_SSL_VERIFY_SERVER_CERT, "Verify server's \"Common Name\" in its cert against hostname used " diff --git a/include/sslopt-vars.h b/include/sslopt-vars.h index c65aa693b76..e28f19b919d 100644 --- a/include/sslopt-vars.h +++ b/include/sslopt-vars.h @@ -30,6 +30,7 @@ SSL_STATIC char *opt_ssl_cipher = 0; SSL_STATIC char *opt_ssl_key = 0; SSL_STATIC char *opt_ssl_crl = 0; SSL_STATIC char *opt_ssl_crlpath = 0; +SSL_STATIC char *opt_tls_version = 0; #ifdef MYSQL_CLIENT SSL_STATIC my_bool opt_ssl_verify_server_cert= 0; #endif diff --git a/include/violite.h b/include/violite.h index 7ee00912837..4778c5521de 100644 --- a/include/violite.h +++ b/include/violite.h @@ -59,6 +59,11 @@ struct vio_keepalive_opts }; +#define VIO_TLSv1_0 1 +#define VIO_TLSv1_1 2 +#define VIO_TLSv1_2 4 +#define VIO_TLSv1_3 8 + #define VIO_LOCALHOST 1U /* a localhost connection */ #define VIO_BUFFERED_READ 2U /* use buffered read */ #define VIO_READ_BUFFER_SIZE 16384U /* size of read buffer */ @@ -148,7 +153,8 @@ enum enum_ssl_init_error { SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY, SSL_INITERR_NOMATCH, SSL_INITERR_BAD_PATHS, SSL_INITERR_CIPHERS, - SSL_INITERR_MEMFAIL, SSL_INITERR_DH, SSL_INITERR_LASTERR + SSL_INITERR_MEMFAIL, SSL_INITERR_DH, SSL_INITERR_PROTOCOL, + SSL_INITERR_LASTERR }; const char* sslGetErrString(enum enum_ssl_init_error err); @@ -169,7 +175,8 @@ struct st_VioSSLFd *new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, const char *ca_file,const char *ca_path, const char *cipher, enum enum_ssl_init_error *error, - const char *crl_file, const char *crl_path); + const char *crl_file, const char *crl_path, + ulonglong tls_version); void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd); #endif /* HAVE_OPENSSL */ diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 402d64445e6..c5630770eff 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -1352,6 +1352,8 @@ The following specify which files/extra groups are read (specified before remain --time-format=name The TIME format (ignored) --timed-mutexes Specify whether to time mutexes. Deprecated, has no effect. + --tls-version=name TLS protocol version for secure connections.. Any + combination of: TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3 --tmp-disk-table-size=# Max size for data for an internal temporary on-disk MyISAM or Aria table. diff --git a/mysql-test/main/mysqld--help.test b/mysql-test/main/mysqld--help.test index c2b6424599a..9e67764d765 100644 --- a/mysql-test/main/mysqld--help.test +++ b/mysql-test/main/mysqld--help.test @@ -23,7 +23,7 @@ perl; log-slow-queries pid-file slow-query-log-file log-basename datadir slave-load-tmpdir tmpdir socket thread-pool-size large-files-support lower-case-file-system system-time-zone - collation-server character-set-server log-tc-size version.*/; + collation-server character-set-server log-tc-size tls-version version.*/; # Plugins which may or may not be there: @plugins=qw/innodb archive blackhole federated partition diff --git a/mysql-test/main/openssl_6975.test b/mysql-test/main/openssl_6975.test index 6a82d013fb6..bfcb0d56681 100644 --- a/mysql-test/main/openssl_6975.test +++ b/mysql-test/main/openssl_6975.test @@ -18,25 +18,25 @@ let $mysql=$MYSQL --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$ disable_abort_on_error; echo TLS1.2 ciphers: user is ok with any cipher; -exec $mysql --ssl-cipher=AES128-SHA256; +exec $mysql --tls-version=TLSv1.2 --ssl-cipher=AES128-SHA256; --replace_result DHE-RSA-CHACHA20-POLY1305 DHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 -exec $mysql --ssl-cipher=TLSv1.2; +exec $mysql --tls-version=TLSv1.2 --ssl-cipher=TLSv1.2; echo TLS1.2 ciphers: user requires SSLv3 cipher AES128-SHA; -exec $mysql --user ssl_sslv3 --ssl-cipher=AES128-SHA256; -exec $mysql --user ssl_sslv3 --ssl-cipher=TLSv1.2; +exec $mysql --user ssl_sslv3 --tls-version=TLSv1.2 --ssl-cipher=AES128-SHA256; +exec $mysql --user ssl_sslv3 --tls-version=TLSv1.2 --ssl-cipher=TLSv1.2; echo TLS1.2 ciphers: user requires TLSv1.2 cipher AES128-SHA256; -exec $mysql --user ssl_tls12 --ssl-cipher=AES128-SHA256; -exec $mysql --user ssl_tls12 --ssl-cipher=TLSv1.2; +exec $mysql --user ssl_tls12 --tls-version=TLSv1.2 --ssl-cipher=AES128-SHA256; +exec $mysql --user ssl_tls12 --tls-version=TLSv1.2 --ssl-cipher=TLSv1.2; echo SSLv3 ciphers: user is ok with any cipher; -exec $mysql --ssl-cipher=AES256-SHA; -exec $mysql --ssl-cipher=SSLv3; +exec $mysql --tls-version=TLSv1.0,TLSv1.1,TLSv1.2 --ssl-cipher=AES256-SHA; +exec $mysql --tls-version=TLSv1.0,TLSv1.1,TLSv1.2 --ssl-cipher=SSLv3; echo SSLv3 ciphers: user requires SSLv3 cipher AES128-SHA; -exec $mysql --user ssl_sslv3 --ssl-cipher=AES128-SHA; -exec $mysql --user ssl_sslv3 --ssl-cipher=SSLv3; +exec $mysql --user ssl_sslv3 --tls-version=TLSv1.0,TLSv1.1,TLSv1.2 --ssl-cipher=AES128-SHA; +exec $mysql --user ssl_sslv3 --tls-version=TLSv1.0,TLSv1.1,TLSv1.2 --ssl-cipher=SSLv3; echo SSLv3 ciphers: user requires TLSv1.2 cipher AES128-SHA256; -exec $mysql --user ssl_tls12 --ssl-cipher=AES128-SHA; -exec $mysql --user ssl_tls12 --ssl-cipher=SSLv3; +exec $mysql --user ssl_tls12 --tls-version=TLSv1.0,TLSv1.1,TLSv1.2 --ssl-cipher=AES128-SHA; +exec $mysql --user ssl_tls12 --tls-version=TLSv1.0,TLSv1.1,TLSv1.2 --ssl-cipher=SSLv3; drop user ssl_sslv3@localhost; drop user ssl_tls12@localhost; diff --git a/mysql-test/main/tls_version.opt b/mysql-test/main/tls_version.opt new file mode 100644 index 00000000000..5f30e3749a4 --- /dev/null +++ b/mysql-test/main/tls_version.opt @@ -0,0 +1 @@ +--tls_version=TLSv1.1,TLSv1.2 diff --git a/mysql-test/main/tls_version.result b/mysql-test/main/tls_version.result new file mode 100644 index 00000000000..d1b20a121fe --- /dev/null +++ b/mysql-test/main/tls_version.result @@ -0,0 +1,14 @@ +Variable_name Value +Ssl_version TLSv1.2 +Variable_name Value +Ssl_version TLSv1.2 +Variable_name Value +Ssl_version TLSv1.1 +Variable_name Value +Ssl_version TLSv1.1 +Variable_name Value +Ssl_version TLSv1.2 +Variable_name Value +Ssl_version TLSv1.2 +@@tls_version +TLSv1.1,TLSv1.2 diff --git a/mysql-test/main/tls_version.test b/mysql-test/main/tls_version.test new file mode 100644 index 00000000000..875fed19821 --- /dev/null +++ b/mysql-test/main/tls_version.test @@ -0,0 +1,24 @@ +# Tests for SSL connections, only run if mysqld is compiled +# with support for SSL. + +-- source include/have_ssl_communication.inc +#default is highest available version: TLSv1.2 +--exec $MYSQL --host=localhost --ssl -e "show status like 'ssl_version';" +# TLSv1.2 +--exec $MYSQL --host=localhost --ssl --tls_version=TLSv1.2 -e "show status like 'ssl_version';" +# TLSv1.1 +--exec $MYSQL --host=localhost --ssl --tls_version=TLSv1.1 -e "show status like 'ssl_version';" +# if a gap is between TLS versions, lowest version number should be used (TLS1.1) +--exec $MYSQL --host=localhost --ssl --tls_version=TLSv1.1,TLSv1.3 -e "show status like 'ssl_version';" +# TLSv1.3 is not enabled, so TLSv1.2 should be used +--exec $MYSQL --host=localhost --ssl --tls_version=TLSv1.2,TLSv1.3 -e "show status like 'ssl_version';" +# Highest TLS version number should be used (TLSv1.2) +--exec $MYSQL --host=localhost --ssl --tls_version=TLSv1.1,TLSv1.2 -e "show status like 'ssl_version';" +# Errors: +# TLS v1.0 is disabled on server, so we should get an error +--replace_regex /2026 SSL connection error.*/2026 SSL connection error: xxxx/ +--error 1 +--exec $MYSQL --host=localhost --ssl --tls_version=TLSv1.0 -e "show status like 'ssl_version';" +# finally list available protocols +--exec $MYSQL --host=localhost --ssl -e "select @@tls_version;" + diff --git a/mysql-test/suite/sys_vars/inc/sysvars_server.inc b/mysql-test/suite/sys_vars/inc/sysvars_server.inc index af1b0ce4563..56053449bae 100644 --- a/mysql-test/suite/sys_vars/inc/sysvars_server.inc +++ b/mysql-test/suite/sys_vars/inc/sysvars_server.inc @@ -31,6 +31,7 @@ select * from information_schema.system_variables 'rand_seed1', 'rand_seed2', 'system_time_zone', + 'tls_version', 'version_comment', 'version_source_revision', 'version_compile_machine', 'version_compile_os', @@ -55,6 +56,7 @@ select VARIABLE_NAME, VARIABLE_SCOPE, VARIABLE_TYPE, VARIABLE_COMMENT, 'rand_seed1', 'rand_seed2', 'system_time_zone', + 'tls_version', 'version_comment', 'version_source_revision', 'version_compile_machine', 'version_compile_os', diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index 509e098498d..0b587ab82c2 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -20,6 +20,7 @@ variable_name not in ( 'rand_seed1', 'rand_seed2', 'system_time_zone', +'tls_version', 'version_comment', 'version_source_revision', 'version_compile_machine', 'version_compile_os', @@ -4661,6 +4662,7 @@ where variable_name in ( 'rand_seed1', 'rand_seed2', 'system_time_zone', +'tls_version', 'version_comment', 'version_source_revision', 'version_compile_machine', 'version_compile_os', @@ -4767,6 +4769,16 @@ NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT NULL +VARIABLE_NAME TLS_VERSION +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE SET +VARIABLE_COMMENT TLS protocol version for secure connections. +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST TLSv1.0,TLSv1.1,TLSv1.2,TLSv1.3 +READ_ONLY YES +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME VERSION VARIABLE_SCOPE GLOBAL VARIABLE_TYPE VARCHAR diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index aa75bb6e2f1..134c457dd8d 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -20,6 +20,7 @@ variable_name not in ( 'rand_seed1', 'rand_seed2', 'system_time_zone', +'tls_version', 'version_comment', 'version_source_revision', 'version_compile_machine', 'version_compile_os', @@ -5725,6 +5726,7 @@ where variable_name in ( 'rand_seed1', 'rand_seed2', 'system_time_zone', +'tls_version', 'version_comment', 'version_source_revision', 'version_compile_machine', 'version_compile_os', @@ -5831,6 +5833,16 @@ NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT NULL +VARIABLE_NAME TLS_VERSION +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE SET +VARIABLE_COMMENT TLS protocol version for secure connections. +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST TLSv1.0,TLSv1.1,TLSv1.2,TLSv1.3 +READ_ONLY YES +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME VERSION VARIABLE_SCOPE GLOBAL VARIABLE_TYPE VARCHAR diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ea49e28384b..289d45cddee 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1444,8 +1444,8 @@ Query_cache query_cache; my_bool opt_use_ssl = 0; char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL, *opt_ssl_cipher= NULL, *opt_ssl_key= NULL, *opt_ssl_crl= NULL, - *opt_ssl_crlpath= NULL; - + *opt_ssl_crlpath= NULL, *opt_tls_version= NULL; +ulonglong tls_version= 0; static scheduler_functions thread_scheduler_struct, extra_thread_scheduler_struct; scheduler_functions *thread_scheduler= &thread_scheduler_struct, @@ -4722,7 +4722,8 @@ static void init_ssl() ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher, &error, - opt_ssl_crl, opt_ssl_crlpath); + opt_ssl_crl, opt_ssl_crlpath, + tls_version); DBUG_PRINT("info",("ssl_acceptor_fd: %p", ssl_acceptor_fd)); if (!ssl_acceptor_fd) { @@ -4761,7 +4762,8 @@ int reinit_ssl() enum enum_ssl_init_error error = SSL_INITERR_NOERROR; st_VioSSLFd *new_fd = new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, - opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher, &error, opt_ssl_crl, opt_ssl_crlpath); + opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher, &error, opt_ssl_crl, + opt_ssl_crlpath, tls_version); if (!new_fd) { diff --git a/sql/mysqld.h b/sql/mysqld.h index a29ca9ef8fe..c5e7872262a 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -635,6 +635,7 @@ extern Atomic_counter thread_count; extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher, *opt_ssl_key, *opt_ssl_crl, *opt_ssl_crlpath; +extern ulonglong tls_version; extern MYSQL_PLUGIN_IMPORT pthread_key(THD*, THR_THD); @@ -697,6 +698,7 @@ enum options_mysqld OPT_WSREP_SYNC_WAIT, #endif /* WITH_WSREP */ OPT_MYSQL_COMPATIBILITY, + OPT_TLS_VERSION, OPT_MYSQL_TO_BE_IMPLEMENTED, OPT_which_is_always_the_last }; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 1160e936a2b..f2a6000843d 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3565,6 +3565,29 @@ static Sys_var_charptr Sys_ssl_crlpath( READ_ONLY GLOBAL_VAR(opt_ssl_crlpath), SSL_OPT(OPT_SSL_CRLPATH), IN_FS_CHARSET, DEFAULT(0)); +static const char *tls_version_names[]= +{ + "TLSv1.0", + "TLSv1.1", + "TLSv1.2", + "TLSv1.3", + 0 +}; + +export bool tls_version_string_representation(THD *thd, sql_mode_t sql_mode, + LEX_CSTRING *ls) +{ + set_to_string(thd, ls, tls_version, tls_version_names); + return ls->str == 0; +} + +static Sys_var_set Sys_tls_version( + "tls_version", + "TLS protocol version for secure connections.", + READ_ONLY GLOBAL_VAR(tls_version), CMD_LINE(REQUIRED_ARG), + tls_version_names, + DEFAULT(VIO_TLSv1_1 | VIO_TLSv1_2 | VIO_TLSv1_3)); + static Sys_var_mybool Sys_standard_compliant_cte( "standard_compliant_cte", "Allow only CTEs compliant to SQL standard", diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 033d71779ab..4a31ebd1798 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -83,7 +83,8 @@ ssl_error_string[] = "SSL_CTX_set_default_verify_paths failed", "Failed to set ciphers to use", "SSL_CTX_new failed", - "SSL_CTX_set_tmp_dh failed" + "SSL_CTX_set_tmp_dh failed", + "Unknown TLS version" }; const char* @@ -183,21 +184,57 @@ static int wolfssl_send(WOLFSSL* ssl, char* buf, int sz, void* vio) } #endif /* HAVE_WOLFSSL */ +static long vio_tls_protocol_options(ulonglong tls_version) +{ + long tls_protocol_flags= +#ifdef TLS1_3_VERSION + SSL_OP_NO_TLSv1_3 | +#endif +#if defined(TLS1_2_VERSION) || defined(HAVE_WOLFSSL) + SSL_OP_NO_TLSv1_2 | +#endif + SSL_OP_NO_TLSv1_1 | + SSL_OP_NO_TLSv1; + long disabled_tls_protocols= tls_protocol_flags, + disabled_ssl_protocols= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; + + if (!tls_version) + return disabled_ssl_protocols; + + if (tls_version & VIO_TLSv1_0) + disabled_tls_protocols&= ~SSL_OP_NO_TLSv1; + if (tls_version & VIO_TLSv1_1) + disabled_tls_protocols&= ~SSL_OP_NO_TLSv1_1; +#if defined(TLS1_2_VERSION) || defined(HAVE_WOLFSSL) + if (tls_version & VIO_TLSv1_2) + disabled_tls_protocols&= ~SSL_OP_NO_TLSv1_2; +#endif +#ifdef TLS1_3_VERSION + if (tls_version & VIO_TLSv1_3) + disabled_tls_protocols&= ~SSL_OP_NO_TLSv1_3; +#endif + + /* some garbage was specified in tls_version option */ + if (tls_protocol_flags == disabled_tls_protocols) + return -1; + return (disabled_tls_protocols | disabled_ssl_protocols); +} + /************************ VioSSLFd **********************************/ static struct st_VioSSLFd * new_VioSSLFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, const char *cipher, my_bool is_client_method, enum enum_ssl_init_error *error, - const char *crl_file, const char *crl_path) + const char *crl_file, const char *crl_path, ulonglong tls_version) { DH *dh; struct st_VioSSLFd *ssl_fd; - long ssl_ctx_options= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; + long ssl_ctx_options; DBUG_ENTER("new_VioSSLFd"); DBUG_PRINT("enter", ("key_file: '%s' cert_file: '%s' ca_file: '%s' ca_path: '%s' " - "cipher: '%s' crl_file: '%s' crl_path: '%s' ", + "cipher: '%s' crl_file: '%s' crl_path: '%s'", key_file ? key_file : "NULL", cert_file ? cert_file : "NULL", ca_file ? ca_file : "NULL", @@ -220,6 +257,14 @@ new_VioSSLFd(const char *key_file, const char *cert_file, goto err1; } + ssl_ctx_options= vio_tls_protocol_options(tls_version); + if (ssl_ctx_options == -1) + { + *error= SSL_INITERR_PROTOCOL; + DBUG_PRINT("error", ("%s", sslGetErrString(*error))); + goto err1; + } + SSL_CTX_set_options(ssl_fd->ssl_context, ssl_ctx_options); /* @@ -342,7 +387,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, ca_path, cipher, TRUE, error, - crl_file, crl_path))) + crl_file, crl_path, 0))) { return 0; } @@ -360,13 +405,14 @@ struct st_VioSSLFd * new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, const char *cipher, enum enum_ssl_init_error* error, - const char *crl_file, const char *crl_path) + const char *crl_file, const char *crl_path, + ulonglong tls_version) { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, ca_path, cipher, FALSE, error, - crl_file, crl_path))) + crl_file, crl_path, tls_version))) { return 0; } From fd00c449e33a5e4dda23832a16512d3af5939818 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 10 Jun 2019 09:24:43 +0200 Subject: [PATCH 47/57] bugfix: PROXY privilege matched usernames incorrectly username can be empty, meaning anybody, or must match literally. only db and host names are matched with wildcards. --- mysql-test/main/plugin_auth_qa_1.result | 3 +++ mysql-test/main/plugin_auth_qa_1.test | 4 ++++ sql/sql_acl.cc | 6 ++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/plugin_auth_qa_1.result b/mysql-test/main/plugin_auth_qa_1.result index d2d902cb6a6..261767d4cd2 100644 --- a/mysql-test/main/plugin_auth_qa_1.result +++ b/mysql-test/main/plugin_auth_qa_1.result @@ -4,6 +4,9 @@ User plugin authentication_string ========== test 1.1.3.2 ==================================== CREATE USER plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON `plug%dest` TO plug_user; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +REVOKE PROXY ON `plug%dest` FROM plug_user; GRANT PROXY ON plug_dest TO plug_user; current_user() plug_dest@% diff --git a/mysql-test/main/plugin_auth_qa_1.test b/mysql-test/main/plugin_auth_qa_1.test index fb577fc178f..17fbf2ca25e 100644 --- a/mysql-test/main/plugin_auth_qa_1.test +++ b/mysql-test/main/plugin_auth_qa_1.test @@ -13,6 +13,10 @@ SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; # CREATE...WITH/CREATE...BY/GRANT CREATE USER plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON `plug%dest` TO plug_user; +--error 1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +REVOKE PROXY ON `plug%dest` FROM plug_user; GRANT PROXY ON plug_dest TO plug_user; --replace_result $MASTER_MYSOCK MASTER_MYSOCK --exec $MYSQL -S $MASTER_MYSOCK -u plug_user --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 49dad4a6e3e..f549d295a50 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -392,10 +392,8 @@ public: proxied_user_arg, proxied_user)); DBUG_RETURN(compare_hostname(&host, host_arg, ip_arg) && compare_hostname(&proxied_host, host_arg, ip_arg) && - (!*user || - (user_arg && !wild_compare(user_arg, user, TRUE))) && - (!*proxied_user || - !wild_compare(proxied_user_arg, proxied_user, TRUE))); + (!*user || !strcmp(user_arg, user)) && + (!*proxied_user || !strcmp(proxied_user_arg, proxied_user))); } From 0a43df4fbc78db89aef3fad525ba28cd2a010d50 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 10 Jun 2019 12:13:39 +0200 Subject: [PATCH 48/57] MDEV-14735 better matching order for grants fixes MDEV-14732 mysql.db privileges evaluated on order of grants rather than hierarchically MDEV-8269 Correct fix for Bug #20181776 :- ACCESS CONTROL DOESN'T MATCH MOST SPECIFIC HOST WHEN IT CONTAINS WILDCARD reimplement the old ad hoc get_sort() function to use a wildcard pattern ordering logic that works correctly in may be all practical cases. get_sort() is renamed to catch merge errors at compilation time. moved to a separate included file, because of a long comment. --- mysql-test/main/grant5.result | 25 +++++ mysql-test/main/grant5.test | 38 +++++++ sql/sql_acl.cc | 73 +++--------- sql/sql_acl_getsort.ic | 205 ++++++++++++++++++++++++++++++++++ 4 files changed, 286 insertions(+), 55 deletions(-) create mode 100644 sql/sql_acl_getsort.ic diff --git a/mysql-test/main/grant5.result b/mysql-test/main/grant5.result index c35e8201582..086ae7011e4 100644 --- a/mysql-test/main/grant5.result +++ b/mysql-test/main/grant5.result @@ -102,3 +102,28 @@ u6 Y mysql_old_password 78a302dd267f6044 u7 Y mysql_old_password 78a302dd267f6044 u8 Y nonexistent 78a302dd267f6044 drop user u1@h, u2@h, u3@h, u4@h, u5@h, u6@h, u7@h, u8@h; +create database mysqltest_1; +create user twg@'%' identified by 'test'; +create table mysqltest_1.t1(id int); +grant create, drop on `mysqltest_1%`.* to twg@'%'; +grant all privileges on `mysqltest_1`.* to twg@'%'; +connect conn1,localhost,twg,test,mysqltest_1; +insert into t1 values(1); +disconnect conn1; +connection default; +revoke all privileges, grant option from twg@'%'; +grant create, drop on `mysqlt%`.* to twg@'%'; +grant all privileges on `mysqlt%1`.* to twg@'%'; +connect conn1,localhost,twg,test,mysqltest_1; +insert into t1 values(1); +disconnect conn1; +connection default; +revoke all privileges, grant option from twg@'%'; +grant create, drop on `mysqlt%`.* to twg@'%'; +grant all privileges on `%mysqltest_1`.* to twg@'%'; +connect conn1,localhost,twg,test,mysqltest_1; +insert into t1 values(1); +disconnect conn1; +connection default; +drop database mysqltest_1; +drop user twg@'%'; diff --git a/mysql-test/main/grant5.test b/mysql-test/main/grant5.test index cc673754461..4db262c25c1 100644 --- a/mysql-test/main/grant5.test +++ b/mysql-test/main/grant5.test @@ -86,3 +86,41 @@ select user,select_priv,plugin,authentication_string from mysql.user where user # but they still can be dropped drop user u1@h, u2@h, u3@h, u4@h, u5@h, u6@h, u7@h, u8@h; + +# +# MDEV-14735 better matching order for grants +# MDEV-14732 mysql.db privileges evaluated on order of grants rather than hierarchically +# MDEV-8269 Correct fix for Bug #20181776 :- ACCESS CONTROL DOESN'T MATCH MOST SPECIFIC HOST WHEN IT CONTAINS WILDCARD +# +create database mysqltest_1; +create user twg@'%' identified by 'test'; +create table mysqltest_1.t1(id int); + +# MDEV-14732 test case +grant create, drop on `mysqltest_1%`.* to twg@'%'; +grant all privileges on `mysqltest_1`.* to twg@'%'; +connect conn1,localhost,twg,test,mysqltest_1; +insert into t1 values(1); +disconnect conn1; +connection default; + +# prefix%suffix +revoke all privileges, grant option from twg@'%'; +grant create, drop on `mysqlt%`.* to twg@'%'; +grant all privileges on `mysqlt%1`.* to twg@'%'; +connect conn1,localhost,twg,test,mysqltest_1; +insert into t1 values(1); +disconnect conn1; +connection default; + +# more specific can even have a shorter prefix +revoke all privileges, grant option from twg@'%'; +grant create, drop on `mysqlt%`.* to twg@'%'; +grant all privileges on `%mysqltest_1`.* to twg@'%'; +connect conn1,localhost,twg,test,mysqltest_1; +insert into t1 values(1); +disconnect conn1; +connection default; + +drop database mysqltest_1; +drop user twg@'%'; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f549d295a50..17ae6dc036a 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -62,6 +62,12 @@ bool mysql_user_table_is_in_short_password_format= false; bool using_global_priv_table= true; +// set that from field length in acl_load? +const uint max_hostname_length= 60; +const uint max_dbname_length= 64; + +#include "sql_acl_getsort.ic" + static LEX_CSTRING native_password_plugin_name= { STRING_WITH_LEN("mysql_native_password") }; @@ -117,7 +123,7 @@ static bool compare_hostname(const acl_host_and_ip *, const char *, const char * class ACL_ACCESS { public: - ulong sort; + ulonglong sort; ulong access; ACL_ACCESS() :sort(0), access(0) @@ -284,7 +290,6 @@ ulong role_global_merges= 0, role_db_merges= 0, role_table_merges= 0, #ifndef NO_EMBEDDED_ACCESS_CHECKS static void update_hostname(acl_host_and_ip *host, const char *hostname); -static ulong get_sort(uint count,...); static bool show_proxy_grants (THD *, const char *, const char *, char *, size_t); static bool show_role_grants(THD *, const char *, const char *, @@ -332,7 +337,8 @@ public: (proxied_host_arg && *proxied_host_arg) ? proxied_host_arg : NULL); with_grant= with_grant_arg; - sort= get_sort(4, host.hostname, user, proxied_host.hostname, proxied_user); + sort= get_magic_sort("huhu", host.hostname, user, proxied_host.hostname, + proxied_user); } void init(MEM_ROOT *mem, const char *host_arg, const char *user_arg, @@ -2344,7 +2350,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables) } host.access= host_table.get_access(); host.access= fix_rights_for_db(host.access); - host.sort= get_sort(2, host.host.hostname, host.db); + host.sort= get_magic_sort("hd", host.host.hostname, host.db); if (check_no_resolve && hostname_requires_resolving(host.host.hostname)) { sql_print_warning("'host' entry '%s|%s' " @@ -2386,7 +2392,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables) user.access= user_table.get_access(); - user.sort= get_sort(2, user.host.hostname, user.user.str); + user.sort= get_magic_sort("hu", user.host.hostname, user.user.str); user.hostname_length= safe_strlen(user.host.hostname); my_init_dynamic_array(&user.role_grants, sizeof(ACL_ROLE *), 0, 8, MYF(0)); @@ -2505,7 +2511,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables) db.db, db.user, safe_str(db.host.hostname)); } } - db.sort=get_sort(3,db.host.hostname,db.db,db.user); + db.sort=get_magic_sort("hdu", db.host.hostname, db.db, db.user); #ifndef TO_BE_REMOVED if (db_table.num_fields() <= 9) { // Without grant @@ -2753,49 +2759,6 @@ static ulong get_access(TABLE *form, uint fieldnr, uint *next_field) } -/* - Return a number which, if sorted 'desc', puts strings in this order: - no wildcards - wildcards - empty string -*/ - -static ulong get_sort(uint count,...) -{ - va_list args; - va_start(args,count); - ulong sort=0; - - /* Should not use this function with more than 4 arguments for compare. */ - DBUG_ASSERT(count <= 4); - - while (count--) - { - char *start, *str= va_arg(args,char*); - uint chars= 0; - uint wild_pos= 0; /* first wildcard position */ - - if ((start= str)) - { - for (; *str ; str++) - { - if (*str == wild_prefix && str[1]) - str++; - else if (*str == wild_many || *str == wild_one) - { - wild_pos= (uint) (str - start) + 1; - break; - } - chars= 128; // Marker that chars existed - } - } - sort= (sort << 8) + (wild_pos ? MY_MIN(wild_pos, 127U) : chars); - } - va_end(args); - return sort; -} - - static int acl_compare(const ACL_ACCESS *a, const ACL_ACCESS *b) { if (a->sort > b->sort) @@ -3157,7 +3120,7 @@ ACL_USER::ACL_USER(THD *thd, const LEX_USER &combo, user= safe_lexcstrdup_root(&acl_memroot, combo.user); update_hostname(&host, safe_strdup_root(&acl_memroot, combo.host.str)); hostname_length= combo.host.length; - sort= get_sort(2, host.hostname, user.str); + sort= get_magic_sort("hu", host.hostname, user.str); password_last_changed= thd->query_start(); password_lifetime= -1; my_init_dynamic_array(&role_grants, sizeof(ACL_USER *), 0, 8, MYF(0)); @@ -3314,7 +3277,7 @@ static void acl_insert_db(const char *user, const char *host, const char *db, update_hostname(&acl_db.host, safe_strdup_root(&acl_memroot, host)); acl_db.db=strdup_root(&acl_memroot,db); acl_db.initial_access= acl_db.access= privileges; - acl_db.sort=get_sort(3,acl_db.host.hostname,acl_db.db,acl_db.user); + acl_db.sort=get_magic_sort("hdu", acl_db.host.hostname, acl_db.db, acl_db.user); acl_dbs.push(acl_db); rebuild_acl_dbs(); } @@ -5033,7 +4996,7 @@ public: char *db, *user, *tname, *hash_key; ulong privs; ulong init_privs; /* privileges found in physical table */ - ulong sort; + ulonglong sort; size_t key_length; GRANT_NAME(const char *h, const char *d,const char *u, const char *t, ulong p, bool is_routine); @@ -5079,7 +5042,7 @@ void GRANT_NAME::set_user_details(const char *h, const char *d, my_casedn_str(files_charset_info, db); } user = strdup_root(&grant_memroot,u); - sort= get_sort(3,host.hostname,db,user); + sort= get_magic_sort("hdu", host.hostname, db, user); if (tname != t) { tname= strdup_root(&grant_memroot, t); @@ -5121,7 +5084,7 @@ GRANT_NAME::GRANT_NAME(TABLE *form, bool is_routine) update_hostname(&host, hostname); db= get_field(&grant_memroot,form->field[1]); - sort= get_sort(3, host.hostname, db, user); + sort= get_magic_sort("hdu", host.hostname, db, user); tname= get_field(&grant_memroot,form->field[3]); if (!db || !tname) { @@ -6214,7 +6177,7 @@ static int update_role_db(int merged, int first, ulong access, acl_db.db= acl_dbs.at(first).db; acl_db.access= access; acl_db.initial_access= 0; - acl_db.sort=get_sort(3, "", acl_db.db, role); + acl_db.sort= get_magic_sort("hdu", "", acl_db.db, role); acl_dbs.push(acl_db); return 2; } diff --git a/sql/sql_acl_getsort.ic b/sql/sql_acl_getsort.ic new file mode 100644 index 00000000000..df55c7c5f1e --- /dev/null +++ b/sql/sql_acl_getsort.ic @@ -0,0 +1,205 @@ +/* Copyright (c) 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 Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ + +#ifndef NO_EMBEDDED_ACCESS_CHECKS +/* + Returns a number which, if sorted in descending order, magically puts + patterns in the order from most specific (e.g. no wildcards) to most generic + (e.g. "%"). That is, the larger the number, the more specific the pattern is. + + Takes a template that lists types of following patterns (by the first letter + of _h_ostname, _d_bname, _u_sername) and up to four patterns. + No more than two can be of 'h' or 'd' type (because one magic value takes 26 + bits, see below). + + ======================================================================== + + Here's how the magic is created: + + Let's look at one iteration of the for() loop. That's one pattern. With + wildcards (usernames aren't interesting). + + By definition a pattern A is "more specific" than pattern B if the set of + strings that match the pattern A is smaller than the set of strings that + match the pattern B. Strings are taken from the big superset of all valid + utf8 strings up to the maxlen. + + Strings are matched character by character. For every non-wildcard + character there can be only one matching character in the matched string. + + For a wild_one character ('_') any valid utf8 character will do. Below + numchars would mean a total number of vaid utf8 characters. It's a huge + number. A number of matching strings for wild_one will be numchars. + + For a wild_many character ('%') any number of valid utf8 characters will do. + How many string will match it depends on the amount of non-wild_many + characters. Say, if a number of non-wildcard characters is N, and a number + of wild_one characters is M, and the number of wild_many characters is K, + then for K=1 its wild_many character will match any number of valid utf8 + characters from 0 to L=maxlen-N-M. The number of matching strings will be + + 1 + numchars + numchars^2 + numchars^3 + ... + numchars^L + + Intermediate result: if M=K=0, the pattern will match only one string, + if M>0, K=0, the pattern will match numchars^M strings, if K=1, the + pattern will match + + numchars^M + 1 + numchars + numchars^2 + ... + numchars^L + + For a more visual notation, let's write these huge numbers not as + decimal or binary, but base numchars. Then the last number will be + a sum of two numbers: the first is one followed by M zeros, the second + constists of L+1 ones: + + 1000{...M...}000 + 111{...L+1...}1111 + + This could produce any of the following + + 111...112111...1111 if L > M, K = 1 + 100...001111...1111 if M > L, K = 1 + 2111111...111111111 if M = L, K = 1 + 1111111...111111111 if M = 0, K = 1 + 1000000...000000000 if K = 0, M > 0 + + There are two complications caused by multiple wild_many characters. + For, say, two wild_many characters, either can accept any number of utf8 + characters, as long the the total amount of them is less then or equal to L. + Same logic applies to any number of non-consequent wild_many characters + (consequent wild_many characters count as one). This gives the number of + matching strings of + + 1 + F(K,1)*numchars + F(K,2)*numchars^2 + ... + F(K,L)*numchars^L + + where F(K,R) is the "number of ways one can put R balls into K boxes", + that is C^{K-1}_{R+K-1}. + + In the "base numchars" notation, it means that besides 0, 1, and 2, + an R-th digit can be F(K,R). For the purpose of comparison, we only need + to know the most significant digit, F(K, L). + While it can be huge, we don't need the exact value, it's a + a monotonously increasing function of K, so if K1>K2, F(K1,L) > F(K2,L) + and we can simply compare values of K instead of complex F(K,L). + + The second complication: F(K,R) gives only an upper boundary, the + actual number of matched strings can be smaller. + Example: pattern "a%b%c" can match "abbc" as a(b)b()c, and as a()b(b)c. + F(2,1) = 2, but it's only one string "abbc". + We'll ignore it here under assumption that it almost never happens + in practice and this simplification won't noticeably disrupt the ordering. + + The last detail: old get_sort function sorted by the non-wildcard prefix + length, so in "abc_" and "a_bc" the former one was sorted first. Strictly + speaking they're both equally specific, but to preserve the backward + compatible sorting we'll use the P "prefix length or 0 if no wildcards" + to break ties. + + Now, let's compare two long numbers. Numbers are easy to compare, + the longer number is larger. If they both have the same lengths, + the one with the larger first digit is larger, and so on. + + But there is no need to actually calculate these numbers. + Three numbers L, K, M (and P to break ties) are enough to describe a pattern + for a purpose of comparison. L/K/M triplets can be compared like this: + + * case 1: if for both patterns L>M: compare L, K, M, in that order + because: + - if L1 > L2, the first number is longer + - If L1 == L2, then the first digit is a monotonously increasing function + of K, so the first digit is larger when K is larger + - if K1 == K2, then all other digits in these numbers would be the + same too, with the exception of one digit in the middle that + got +1 because of +1000{...M...}000. So, whatever number has a + larger M will get this +1 first. + * case 2: if for both patterns LM1, other L2=M2: compare L, K, M + * case 5: if one L1M1, the other M2>L2: first is more generic + unless (case 6a) K1=K2=1,M1=0,M2=L2+1 (in that case - equal) + + note that in case 3 one can use a rule from the case either 1 or 2, + in the case 4 one can use the rule from the case 1, + in the case 5 one can use the rule from the case 2. + + for the case 6 and ignoring the special case 6a, to compare patterns by a + magic number as a function z(a,b,c), we must ensure that z(L1,K1,M1) is + greater than z(M2,L2,K2) when L1=M2. This can be done by an extra bit, + which is 1 for K and 0 for L. Thus, the magic number could be + + case 1: (((L*2 + 1)*(maxlen+1) + K)*(maxlen+1) + M)*(maxlen+1) + P + case 2: ((M*2*(maxlen+1) + L)*(maxlen+1) + K)*(maxlen+1) + P + + upper bound: L<=maxlen, M<=maxlen, K<=maxlen/2, P M) + magic= (((L * 2 + 1) * d + K) * d + M) * d + P; + else + magic= (((M * 2 + 0) * d + L) * d + K) * d + P; + DBUG_ASSERT(magic < 1<<26); + sort= (sort << 26) + magic; + IF_DBUG(bits_used+= 26,); + } + DBUG_ASSERT(bits_used < 8*sizeof(sort)); + va_end(args); + return ~sort; +} +#endif From a4cc6fb91f3855e0ed803a6e1762440cfcf8cb5c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 14 Jun 2019 16:10:45 +0200 Subject: [PATCH 49/57] MDEV-15526 SysV init service deployed file '/etc/init.d/mysql' prevents systemctl disable command to work correctly (mariadb|mysql naming support) (debian/ubuntu) mariadb service is controlled by systemd Do not install SysV init script on Debian/Ubuntu in /etc/init.d/ put it in /usr/share/mysql in case the user would need it for something. Use systemctl in pre/post scripts directly without funky conditionals and wrapper scripts --- .../mysql.init} | 0 debian/mariadb-server-10.4.install | 1 + debian/mariadb-server-10.4.postinst | 6 +----- debian/mariadb-server-10.4.postrm | 6 +----- debian/mariadb-server-10.4.preinst | 11 ++--------- 5 files changed, 5 insertions(+), 19 deletions(-) rename debian/{mariadb-server-10.4.mysql.init => additions/mysql.init} (100%) diff --git a/debian/mariadb-server-10.4.mysql.init b/debian/additions/mysql.init similarity index 100% rename from debian/mariadb-server-10.4.mysql.init rename to debian/additions/mysql.init diff --git a/debian/mariadb-server-10.4.install b/debian/mariadb-server-10.4.install index a9cbbfc8a99..e3a66b7b63f 100644 --- a/debian/mariadb-server-10.4.install +++ b/debian/mariadb-server-10.4.install @@ -2,6 +2,7 @@ debian/additions/debian-start etc/mysql debian/additions/debian-start.inc.sh usr/share/mysql debian/additions/echo_stderr usr/share/mysql debian/additions/mysqld_safe_syslog.cnf etc/mysql/conf.d +debian/additions/mysql.init usr/share/mysql etc/apparmor.d/usr.sbin.mysqld lib/systemd/system/mariadb@bootstrap.service.d/use_galera_new_cluster.conf usr/bin/aria_chk diff --git a/debian/mariadb-server-10.4.postinst b/debian/mariadb-server-10.4.postinst index 4532085169e..42cbe394c28 100644 --- a/debian/mariadb-server-10.4.postinst +++ b/debian/mariadb-server-10.4.postinst @@ -17,11 +17,7 @@ ERR_LOGGER="logger -p daemon.err -t mariadb-server-$VER.postinst -i" set -o pipefail invoke() { - if [ -x /usr/sbin/invoke-rc.d ]; then - invoke-rc.d mysql $1 - else - /etc/init.d/mysql $1 - fi + systemctl $1 mysql } case "$1" in diff --git a/debian/mariadb-server-10.4.postrm b/debian/mariadb-server-10.4.postrm index bb9ba8cec68..3cbd3721414 100644 --- a/debian/mariadb-server-10.4.postrm +++ b/debian/mariadb-server-10.4.postrm @@ -12,11 +12,7 @@ MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf" # is running! stop_server() { set +e - if [ -x /usr/sbin/invoke-rc.d ]; then - invoke-rc.d mysql stop - else - /etc/init.d/mysql stop - fi + systemctl stop mysql errno=$? set -e diff --git a/debian/mariadb-server-10.4.preinst b/debian/mariadb-server-10.4.preinst index 08e424bc712..032124c0fcc 100644 --- a/debian/mariadb-server-10.4.preinst +++ b/debian/mariadb-server-10.4.preinst @@ -20,25 +20,18 @@ mysql_upgradedir=/var/lib/mysql-upgrade # do it himself. No database directories should be removed while the server # is running! Another mysqld in e.g. a different chroot is fine for us. stop_server() { - if [ ! -x /etc/init.d/mysql ]; then return; fi - # Return immediately if there are no mysql processes running # as there is no point in trying to shutdown in that case. if ! pgrep mysqld > /dev/null; then return; fi set +e - if [ -x /usr/sbin/invoke-rc.d ]; then - cmd="invoke-rc.d mysql stop" - else - cmd="/etc/init.d/mysql stop" - fi - $cmd + systemctl stop mysql errno=$? set -e # 0=ok, 100=no init script (fresh install) if [ "$errno" != 0 -a "$errno" != 100 ]; then - echo "${cmd/ */} returned $errno" 1>&2 + echo "'systemctl stop mysql' returned $errno" 1>&2 echo "There is a MySQL server running, but we failed in our attempts to stop it." 1>&2 echo "Stop it yourself and try again!" 1>&2 db_stop From 09332120360e2d303fdbfba48fa1e13931c870be Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 16 Jun 2019 00:41:54 +0200 Subject: [PATCH 50/57] C/C --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index ab4d09dd8de..c098613d289 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit ab4d09dd8de0bb2c56ca0c60cb386f02d1736190 +Subproject commit c098613d289ed88fc53286e98add28ae9f2d8b46 From 13e8f728ec83133b990ed21404cbac1d8a0bc74c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 16 Jun 2019 01:25:03 +0200 Subject: [PATCH 51/57] compilation failure on ppc with -DCMAKE_BUILD_TYPE=Debug if ${CRC32_LIBRARY} target has no COMPILE_FLAGS yet, GET_TARGET_PROPERTY returns COMPILE_FLAGS-NOTFOUND, which doesn't work very well when it's later fed back into COMPILE_FLAGS. GET_PROPERTY() returns an empty string in this case. --- extra/crc32-vpmsum/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/crc32-vpmsum/CMakeLists.txt b/extra/crc32-vpmsum/CMakeLists.txt index 31c09a97d6a..b4adebdadf5 100644 --- a/extra/crc32-vpmsum/CMakeLists.txt +++ b/extra/crc32-vpmsum/CMakeLists.txt @@ -2,7 +2,7 @@ ADD_CONVENIENCE_LIBRARY(${CRC32_LIBRARY} $ $ Date: Sun, 16 Jun 2019 14:53:17 +0200 Subject: [PATCH 52/57] make the heap.heap test portable in HEAP btree indexes, the address of a record in memory is part of the key. So, when inserting many identical keys, the actual btree shape is defined by how and where records in memory are allocated. records_in_range uses floats to estimate the size of the chunk of the btree between min and max records, it depends on the btree shape and, thus, is not portable either. As are optimizer decisions that are based on records_in_range estimations, if the number happens to be close to a tipping point. as a fix, reduce the number of matching rows, so that even with system-specific variations the optimizer would still pick the expected plan. Fixes heap.heap failure (range vs ALL) on ppc64 --- mysql-test/suite/heap/heap.result | 21 +++++++++------------ mysql-test/suite/heap/heap.test | 1 + 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/mysql-test/suite/heap/heap.result b/mysql-test/suite/heap/heap.result index 326142a71a4..e8d1341aa9b 100644 --- a/mysql-test/suite/heap/heap.result +++ b/mysql-test/suite/heap/heap.result @@ -563,32 +563,32 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MEMORY DEFAULT CHARSET=latin1 select count(*) from t1; count(*) -270 +267 insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1))); select count(*) from t1 where v='a'; count(*) -10 +7 select count(*) from t1 where c='a'; count(*) -10 +7 select count(*) from t1 where t='a'; count(*) -10 +7 select count(*) from t1 where v='a '; count(*) -10 +7 select count(*) from t1 where c='a '; count(*) -10 +7 select count(*) from t1 where t='a '; count(*) -10 +7 select count(*) from t1 where v between 'a' and 'a '; count(*) -10 +7 select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; count(*) -10 +7 explain select count(*) from t1 where v='a '; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 13 const # Using where @@ -618,9 +618,6 @@ qq *a *a*a * *a *a*a * *a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * explain select * from t1 where v='a'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 13 const # Using where diff --git a/mysql-test/suite/heap/heap.test b/mysql-test/suite/heap/heap.test index ea07d020e4d..237685a6423 100644 --- a/mysql-test/suite/heap/heap.test +++ b/mysql-test/suite/heap/heap.test @@ -337,6 +337,7 @@ while ($1) } dec $1; } +delete from t1 where v like 'a%' and length(v) > 7; commit; --enable_query_log select count(*) from t1; From da619f010f2fc8554b1df5724e1d344442df1b3d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 16 Jun 2019 19:42:59 +0200 Subject: [PATCH 53/57] compilation fix for fulltest-big --- storage/oqgraph/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/oqgraph/CMakeLists.txt b/storage/oqgraph/CMakeLists.txt index 6199a648c2c..68582e2802d 100644 --- a/storage/oqgraph/CMakeLists.txt +++ b/storage/oqgraph/CMakeLists.txt @@ -38,7 +38,7 @@ IF(MSVC) ADD_DEFINITIONS(-DJU_WIN) ELSE(MSVC) # Fix lp bug 1221555 with -fpermissive, so that errors in gcc 4.7 become warnings for the time being - STRING(REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + STRING(REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -fno-strict-aliasing -fpermissive") ENDIF(MSVC) From f02bc3cf0f8f972c8f626a42490864dddd2e4f23 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 16 Jun 2019 22:38:02 +0200 Subject: [PATCH 54/57] change pam and disks plugin maturity beta->gamma --- plugin/auth_pam/auth_pam.c | 2 +- plugin/disks/information_schema_disks.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index 599b323b0b7..45a5028429f 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -218,6 +218,6 @@ maria_declare_plugin(pam) NULL, vars, "2.0", - MariaDB_PLUGIN_MATURITY_BETA + MariaDB_PLUGIN_MATURITY_GAMMA } maria_declare_plugin_end; diff --git a/plugin/disks/information_schema_disks.cc b/plugin/disks/information_schema_disks.cc index 5bd7e0e46b7..54dbb25b101 100644 --- a/plugin/disks/information_schema_disks.cc +++ b/plugin/disks/information_schema_disks.cc @@ -149,7 +149,7 @@ maria_declare_plugin(disks) NULL, /* no status variables */ NULL, /* no system variables */ "1.0", /* String version representation */ - MariaDB_PLUGIN_MATURITY_BETA /* Maturity (see include/mysql/plugin.h)*/ + MariaDB_PLUGIN_MATURITY_GAMMA /* Maturity (see include/mysql/plugin.h)*/ } mysql_declare_plugin_end; From 24503d5711677ce77617e3ff2514a4838e95eac7 Mon Sep 17 00:00:00 2001 From: Rasmus Johansson Date: Sat, 18 May 2019 06:11:01 +0000 Subject: [PATCH 55/57] MDEV-17592 Create MariaDB named commands/symlinks --- CMakeLists.txt | 1 + client/CMakeLists.txt | 5 +- cmake/install_macros.cmake | 7 ++- cmake/mysql_add_executable.cmake | 4 ++ cmake/symlinks.cmake | 72 +++++++++++++++++++++++++++ debian/mariadb-client-10.4.links | 38 ++++++++++++++ debian/mariadb-client-core-10.4.links | 4 ++ debian/mariadb-server-10.4.install | 2 +- debian/mariadb-server-10.4.links | 18 +++++++ debian/mariadb-server-core-10.4.links | 4 ++ man/CMakeLists.txt | 39 +++++++++++++++ scripts/CMakeLists.txt | 1 + 12 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 cmake/symlinks.cmake create mode 100644 debian/mariadb-client-core-10.4.links create mode 100644 debian/mariadb-server-10.4.links create mode 100644 debian/mariadb-server-core-10.4.links diff --git a/CMakeLists.txt b/CMakeLists.txt index 1299bd1765d..c5f8c2e0cca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,6 +160,7 @@ INCLUDE(plugin) INCLUDE(install_macros) INCLUDE(systemd) INCLUDE(mysql_add_executable) +INCLUDE(symlinks) INCLUDE(compile_flags) INCLUDE(crc32) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 37087b7c6c6..63e4cf36b00 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -56,7 +56,6 @@ TARGET_LINK_LIBRARIES(mysqlcheck ${CLIENT_LIB}) MYSQL_ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c) TARGET_LINK_LIBRARIES(mysqldump ${CLIENT_LIB}) - MYSQL_ADD_EXECUTABLE(mysqlimport mysqlimport.c) SET_SOURCE_FILES_PROPERTIES(mysqlimport.c PROPERTIES COMPILE_FLAGS "-DTHREADS") TARGET_LINK_LIBRARIES(mysqlimport ${CLIENT_LIB}) @@ -93,11 +92,9 @@ TARGET_LINK_LIBRARIES(async_example ${CLIENT_LIB}) SET_TARGET_PROPERTIES (mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow mysqlslap mysql_plugin async_example PROPERTIES HAS_CXX TRUE) - -FOREACH(t mysql mysqltest mysqltest mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow mysql_plugin mysqlbinlog +FOREACH(t mysql mysqltest mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow mysql_plugin mysqlbinlog mysqladmin mysqlslap async_example) ADD_DEPENDENCIES(${t} GenError ${CLIENT_LIB}) ENDFOREACH() ADD_DEFINITIONS(-DHAVE_DLOPEN) - diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index f28720e97bc..a4ba10c28e5 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -71,9 +71,10 @@ FUNCTION(INSTALL_MANPAGE file) ${MYSQL_DOC_DIR}/man/*${file}.8* ${GLOB_EXPR} ) - ENDIF() + ENDIF() FILE(GLOB_RECURSE MANPAGES ${GLOB_EXPR}) + IF(MANPAGES) LIST(GET MANPAGES 0 MANPAGE) STRING(REPLACE "${file}man.1" "${file}.1" MANPAGE "${MANPAGE}") @@ -111,8 +112,10 @@ FUNCTION(INSTALL_SCRIPT) ENDIF() INSTALL(PROGRAMS ${script} DESTINATION ${ARG_DESTINATION} ${COMP}) + get_filename_component(dest "${script}" NAME) + CREATE_MARIADB_SYMLINK(${dest} ${ARG_DESTINATION} ${COMP}) - INSTALL_MANPAGE(${script}) + INSTALL_MANPAGE(${dest}) ENDFUNCTION() diff --git a/cmake/mysql_add_executable.cmake b/cmake/mysql_add_executable.cmake index d3a888f9a75..d894ee2de9a 100644 --- a/cmake/mysql_add_executable.cmake +++ b/cmake/mysql_add_executable.cmake @@ -63,6 +63,7 @@ FUNCTION (MYSQL_ADD_EXECUTABLE) UNSET(EXCLUDE_FROM_ALL) ENDIF() ADD_EXECUTABLE(${target} ${WIN32} ${MACOSX_BUNDLE} ${EXCLUDE_FROM_ALL} ${sources}) + # tell CPack where to install IF(NOT ARG_EXCLUDE_FROM_ALL) IF(NOT ARG_DESTINATION) @@ -80,4 +81,7 @@ FUNCTION (MYSQL_ADD_EXECUTABLE) ENDIF() MYSQL_INSTALL_TARGETS(${target} DESTINATION ${ARG_DESTINATION} ${COMP}) ENDIF() + + # create mariadb named symlink + CREATE_MARIADB_SYMLINK(${target} ${ARG_DESTINATION} ${COMP}) ENDFUNCTION() diff --git a/cmake/symlinks.cmake b/cmake/symlinks.cmake new file mode 100644 index 00000000000..8fbdc93e869 --- /dev/null +++ b/cmake/symlinks.cmake @@ -0,0 +1,72 @@ +# Create lists +macro(REGISTER_SYMLINK from to) + list(APPEND MARIADB_SYMLINK_FROMS ${from}) + list(APPEND MARIADB_SYMLINK_TOS ${to}) +endmacro() + +# MariaDB names for executables +REGISTER_SYMLINK("mysql" "mariadb") +REGISTER_SYMLINK("mysqlaccess" "mariadb-access") +REGISTER_SYMLINK("mysqladmin" "mariadb-admin") +REGISTER_SYMLINK("mariabackup" "mariadb-backup") +REGISTER_SYMLINK("mysqlbinlog" "mariadb-binlog") +REGISTER_SYMLINK("mysqlcheck" "mariadb-check") +REGISTER_SYMLINK("mysql_client_test_embedded" "mariadb-client-test-embedded") +REGISTER_SYMLINK("mariadb_config" "mariadb-config") +REGISTER_SYMLINK("mysql_convert_table_format" "mariadb-convert-table-format") +REGISTER_SYMLINK("mysqldump" "mariadb-dump") +REGISTER_SYMLINK("mysqldumpslow" "mariadb-dumpslow") +REGISTER_SYMLINK("mysql_embedded" "mariadb-embedded") +REGISTER_SYMLINK("mysql_find_rows" "mariadb-find-rows") +REGISTER_SYMLINK("mysql_fix_extensions" "mariadb-fix-extensions") +REGISTER_SYMLINK("mysqlhotcopy" "mariadb-hotcopy") +REGISTER_SYMLINK("mysqlimport" "mariadb-import") +REGISTER_SYMLINK("mysql_install_db" "mariadb-install-db") +REGISTER_SYMLINK("mysql_ldb" "mariadb-ldb") +REGISTER_SYMLINK("mysql_plugin" "mariadb-plugin") +REGISTER_SYMLINK("mysql_secure_installation" "mariadb-secure-installation") +REGISTER_SYMLINK("mysql_setpermission" "mariadb-setpermission") +REGISTER_SYMLINK("mysqlshow" "mariadb-show") +REGISTER_SYMLINK("mysqlslap" "mariadb-slap") +REGISTER_SYMLINK("mysqltest" "mariadb-test") +REGISTER_SYMLINK("mysqltest_embedded" "mariadb-test-embedded") +REGISTER_SYMLINK("mytop" "mariadb-top") +REGISTER_SYMLINK("mysql_tzinfo_to_sql" "mariadb-tzinfo-to-sql") +REGISTER_SYMLINK("mysql_upgrade" "mariadb-upgrade") +REGISTER_SYMLINK("mysql_upgrade_service" "mariadb-upgrade-service") +REGISTER_SYMLINK("mysql_upgrade_wizard" "mariadb-upgrade-wizard") +REGISTER_SYMLINK("mysql_waitpid" "mariadb-waitpid") +REGISTER_SYMLINK("mysqld" "mariadbd") +REGISTER_SYMLINK("mysqld_multi" "mariadbd-multi") +REGISTER_SYMLINK("mysqld_safe" "mariadbd-safe") +REGISTER_SYMLINK("mysqld_safe_helper" "mariadbd-safe-helper") + +# Add MariaDB symlinks +macro(CREATE_MARIADB_SYMLINK src dir comp) + # Find the MariaDB name for executable + list(FIND MARIADB_SYMLINK_FROMS ${src} _index) + + if (${_index} GREATER -1) + list(GET MARIADB_SYMLINK_TOS ${_index} mariadbname) + endif() + + if (mariadbname) + CREATE_MARIADB_SYMLINK_IN_DIR(${src} ${mariadbname} ${dir} ${comp}) + endif() +endmacro(CREATE_MARIADB_SYMLINK) + +# Add MariaDB symlinks in directory +macro(CREATE_MARIADB_SYMLINK_IN_DIR src dest dir comp) + if(UNIX) + add_custom_target( + symlink_${dest}_${comp} ALL + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${dest} + ) + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${dest} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E create_symlink ${src} ${dest} + COMMENT "mklink ${src} -> ${dest}") + + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${dest} DESTINATION ${dir} COMPONENT ${comp}) + endif() +endmacro(CREATE_MARIADB_SYMLINK_IN_DIR) diff --git a/debian/mariadb-client-10.4.links b/debian/mariadb-client-10.4.links index 4a504969246..b93d2d7f8fd 100644 --- a/debian/mariadb-client-10.4.links +++ b/debian/mariadb-client-10.4.links @@ -1,6 +1,44 @@ +usr/bin/mysql_find_rows usr/bin/mariadb-find-rows +usr/bin/mysql_fix_extensions usr/bin/mariadb-fix-extenstions +usr/bin/mysql_plugin usr/bin/mariadb-plugin +usr/bin/mysql_waitpid usr/bin/mariadb-waitpid +usr/bin/mysqlaccess usr/bin/mariadb-access +usr/bin/mysqladmin usr/bin/mariadb-admin +usr/bin/mysqlanalyze usr/bin/mariadb-analyze +usr/bin/mysqlbinlog usr/bin/mariadb-binlog +usr/bin/mysqlcheck usr/bin/mariadb-analyze +usr/bin/mysqlcheck usr/bin/mariadb-optimize +usr/bin/mysqlcheck usr/bin/mariadb-repair usr/bin/mysqlcheck usr/bin/mysqlanalyze usr/bin/mysqlcheck usr/bin/mysqloptimize usr/bin/mysqlcheck usr/bin/mysqlrepair +usr/bin/mysqldump usr/bin/mariadb-dump +usr/bin/mysqldumpslow usr/bin/mariadb-dump-slow +usr/bin/mysqlimport usr/bin/mariadb-import +usr/bin/mysqloptimize usr/bin/mariadb-optimize +usr/bin/mysqlrepair usr/bin/mariadb-repair +usr/bin/mysqlreport usr/bin/mariadb-report +usr/bin/mysqlslap usr/bin/mariadb-slap +usr/bin/mysqltest usr/bin/mariadb-test +usr/share/man/man1/mysql_find_rows.1.gz usr/share/man/man1/mariadb-find-rows.1.gz +usr/share/man/man1/mysql_fix_extensions.1.gz usr/share/man/man1/mariadb-fix-extensions.1.gz +usr/share/man/man1/mysql_plugin.1.gz usr/share/man/man1/mariadb-plugin.1.gz +usr/share/man/man1/mysql_waitpid.1.gz usr/share/man/man1/mariadb-waitpid.1.gz +usr/share/man/man1/mysqlaccess.1.gz usr/share/man/man1/mariadb-access.1.gz +usr/share/man/man1/mysqladmin.1.gz usr/share/man/man1/mariadb-admin.1.gz +usr/share/man/man1/mysqlanalyze.1.gz usr/share/man/man1/mariadb-analyze.1.gz +usr/share/man/man1/mysqlbinlog.1.gz usr/share/man/man1/mariadb-binlog.1.gz +usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mariadb-analyze.1.gz +usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mariadb-optimize.1.gz +usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mariadb-repair.1.gz usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mysqlanalyze.1.gz usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mysqloptimize.1.gz usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mysqlrepair.1.gz +usr/share/man/man1/mysqldump.1.gz usr/share/man/man1/mariadb-dump.1.gz +usr/share/man/man1/mysqldumpslow.1.gz usr/share/man/man1/mariadb-dump-slow.1.gz +usr/share/man/man1/mysqlimport.1.gz usr/share/man/man1/mariadb-import.1.gz +usr/share/man/man1/mysqloptimize.1.gz usr/share/man/man1/mariadb-optimize.1.gz +usr/share/man/man1/mysqlrepair.1.gz usr/share/man/man1/mariadb-repair.1.gz +usr/share/man/man1/mysqlreport.1.gz usr/share/man/man1/mariadb-report.1.gz +usr/share/man/man1/mysqlslap.1.gz usr/share/man/man1/mariadb-slap.1.gz +usr/share/man/man1/mysqltest.1.gz usr/share/man/man1/mariadb-test.1.gz diff --git a/debian/mariadb-client-core-10.4.links b/debian/mariadb-client-core-10.4.links new file mode 100644 index 00000000000..4c5ff23b38b --- /dev/null +++ b/debian/mariadb-client-core-10.4.links @@ -0,0 +1,4 @@ +usr/bin/mysql usr/bin/mariadb +usr/bin/mysqlcheck usr/bin/mariadb-check +usr/share/man/man1/mysql.1.gz usr/share/man/man1/mariadb.1.gz +usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mariadb-check.1.gz diff --git a/debian/mariadb-server-10.4.install b/debian/mariadb-server-10.4.install index e3a66b7b63f..bfc5f907d09 100644 --- a/debian/mariadb-server-10.4.install +++ b/debian/mariadb-server-10.4.install @@ -88,9 +88,9 @@ usr/share/man/man1/replace.1 usr/share/man/man1/resolve_stack_dump.1 usr/share/man/man1/resolveip.1 usr/share/man/man1/wsrep_sst_common.1 +usr/share/man/man1/wsrep_sst_mariabackup.1 usr/share/man/man1/wsrep_sst_mysqldump.1 usr/share/man/man1/wsrep_sst_rsync.1 -usr/share/man/man1/wsrep_sst_mariabackup.1 usr/share/mysql/errmsg-utf8.txt usr/share/mysql/fill_help_tables.sql usr/share/mysql/maria_add_gis_sp_bootstrap.sql diff --git a/debian/mariadb-server-10.4.links b/debian/mariadb-server-10.4.links new file mode 100644 index 00000000000..65e0a6650d5 --- /dev/null +++ b/debian/mariadb-server-10.4.links @@ -0,0 +1,18 @@ +usr/bin/mysql_convert_table_format usr/bin/mariadb-convert-table-format +usr/bin/mysql_secure_installation usr/bin/mariadb-secure-installation +usr/bin/mysql_setpermission usr/bin/mariadb-setpermission +usr/bin/mysql_tzinfo_to_sql usr/bin/mariadb-tzinfo-to-sql +usr/bin/mysqld_multi usr/bin/mariadb-multi +usr/bin/mysqld_safe usr/bin/mariadb-safe +usr/bin/mysqld_safe_helper usr/bin/mariadb-safe-helper +usr/bin/mysqlhotcopy usr/bin/mariadb-hotcopy +usr/bin/mysqlshow usr/bin/mariadb-show +usr/share/man/man1/mysql_convert_table_format.1.gz usr/share/man/man1/mariadb-convert-table-format.1.gz +usr/share/man/man1/mysql_secure_installation.1.gz usr/share/man/man1/mariadb-secure-installation.1.gz +usr/share/man/man1/mysql_setpermission.1.gz usr/share/man/man1/mariadb-setpermission.1.gz +usr/share/man/man1/mysql_tzinfo_to_sql.1.gz usr/share/man/man1/mariadb-tzinfo-to-sql.1.gz +usr/share/man/man1/mysqld_multi.1.gz usr/share/man/man1/mariadb-multi.1.gz +usr/share/man/man1/mysqld_safe.1.gz usr/share/man/man1/mariadb-safe.1.gz +usr/share/man/man1/mysqld_safe_helper.1.gz usr/share/man/man1/mariadb-safe-helper.1.gz +usr/share/man/man1/mysqlhotcopy.1.gz usr/share/man/man1/mariadb-hotcopy.1.gz +usr/share/man/man1/mysqlshow.1.gz usr/share/man/man1/mariadb-show.1.gz diff --git a/debian/mariadb-server-core-10.4.links b/debian/mariadb-server-core-10.4.links new file mode 100644 index 00000000000..90ed9ee01cf --- /dev/null +++ b/debian/mariadb-server-core-10.4.links @@ -0,0 +1,4 @@ +usr/bin/mysql_install_db usr/bin/mariadb-install-db +usr/bin/mysql_upgrade usr/bin/mariadb-upgrade +usr/share/man/man1/mysql_install_db.1.gz usr/share/man/man1/mariadb-install-db.1.gz +usr/share/man/man1/mysql_upgrade.1.gz usr/share/man/man1/mariadb-upgrade-db.1.gz diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index 7a1e284b3e7..c89d156718d 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -44,3 +44,42 @@ INSTALL(FILES ${MAN1_CLIENT} DESTINATION ${INSTALL_MANDIR}/man1 COMPONENT ManPag INSTALL(FILES ${MAN1_DEVEL} DESTINATION ${INSTALL_MANDIR}/man1 COMPONENT ManPagesDevelopment) INSTALL(FILES ${MAN1_TEST} DESTINATION ${INSTALL_MANDIR}/man1 COMPONENT ManPagesTest) +macro(MARIADB_SYMLINK_MANPAGE) + list(LENGTH MARIADB_SYMLINK_FROMS _len) + math(EXPR _listlen "${_len}-1") + + foreach(_index RANGE ${_listlen}) + list(GET MARIADB_SYMLINK_FROMS ${_index} _name) + + set(_manname "${_name}") + list(FIND MAN1_SERVER ${_manname}.1 _iman1server) + list(FIND MAN8_SERVER ${_manname}.8 _iman8server) + list(FIND MAN1_CLIENT ${_manname}.1 _iman1client) + list(FIND MAN1_DEVEL ${_manname}.1 _iman1devel) + list(FIND MAN1_TEST ${_manname}.1 _iman1test) + + if (${_iman1server} GREATER -1) + MARIADB_SYMLINK_MANPAGE_CREATE(${_manname} ${_index} 1 "man1" ManPagesServer) + endif() + if (${_iman8server} GREATER -1) + MARIADB_SYMLINK_MANPAGE_CREATE(${_manname} ${_index} 8 "man8" ManPagesServer) + endif() + if (${_iman1client} GREATER -1) + MARIADB_SYMLINK_MANPAGE_CREATE(${_manname} ${_index} 1 "man1" ManPagesClient) + endif() + if (${_iman1devel} GREATER -1) + MARIADB_SYMLINK_MANPAGE_CREATE(${_manname} ${_index} 1 "man1" ManPagesDevelopment) + endif() + if (${_iman1test} GREATER -1) + MARIADB_SYMLINK_MANPAGE_CREATE(${_manname} ${_index} 1 "man1" ManPagesTest) + endif() + endforeach(_index) +endmacro(MARIADB_SYMLINK_MANPAGE) + +macro(MARIADB_SYMLINK_MANPAGE_CREATE mysqlname index mannr dir comp) + list(GET MARIADB_SYMLINK_TOS ${index} _mariadbname) + set(symlinkname "${_mariadbname}.${mannr}") + CREATE_MARIADB_SYMLINK_IN_DIR(${mysqlname}.${mannr} ${symlinkname} ${INSTALL_MANDIR}/${dir} ${comp}) +endmacro(MARIADB_SYMLINK_MANPAGE_CREATE) + +MARIADB_SYMLINK_MANPAGE() diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 3d31cda4ceb..7be46ac1985 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -332,6 +332,7 @@ ELSE() COMPONENT ${${file}_COMPONENT} ) ENDFOREACH() + SET (wsrep_sst_rsync_wan ${CMAKE_CURRENT_BINARY_DIR}/wsrep_sst_rsync_wan) ADD_CUSTOM_COMMAND( OUTPUT ${wsrep_sst_rsync_wan} From 306e439c6d19b578fdd12b640a6f9a81ed2737e1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 15 Jun 2019 18:27:30 +0200 Subject: [PATCH 56/57] MDEV-17592 Create MariaDB named commands/symlinks post-merge fixes: * .gitignore * don't put the keyword COMPONENT into ${COMP} anymore * don't alias mytop, but do alias mysql_client_test * don't symlink manpages, use troff aliasing technique instead (symlinked manpages break rpm and out-of-source bintar builds) * move debian to use troff aliased manpages, fix typos in debian files, put aliases in the correct packages, add more aliases to match rpm/bintar packaging --- .gitignore | 64 +++++++++++++++++++++++++ cmake/install_macros.cmake | 8 +--- cmake/mysql_add_executable.cmake | 8 ++-- cmake/symlinks.cmake | 4 +- debian/mariadb-backup.install | 2 + debian/mariadb-backup.links | 1 + debian/mariadb-client-10.4.install | 11 +++++ debian/mariadb-client-10.4.links | 23 +-------- debian/mariadb-client-core-10.4.install | 2 + debian/mariadb-client-core-10.4.links | 2 - debian/mariadb-plugin-rocksdb.install | 2 + debian/mariadb-plugin-rocksdb.links | 1 + debian/mariadb-server-10.4.install | 9 ++++ debian/mariadb-server-10.4.links | 15 ++---- debian/mariadb-server-core-10.4.install | 3 ++ debian/mariadb-server-core-10.4.links | 3 +- debian/mariadb-test.install | 4 ++ debian/mariadb-test.links | 4 ++ man/CMakeLists.txt | 7 +-- tests/CMakeLists.txt | 4 +- 20 files changed, 122 insertions(+), 55 deletions(-) create mode 100644 debian/mariadb-backup.links create mode 100644 debian/mariadb-plugin-rocksdb.links diff --git a/.gitignore b/.gitignore index 95aa3ae64d4..66212558955 100644 --- a/.gitignore +++ b/.gitignore @@ -524,3 +524,67 @@ compile_commands.json # Clion && other JetBrains ides .idea +client/mariadb +client/mariadb-admin +client/mariadb-binlog +client/mariadb-check +client/mariadb-dump +client/mariadb-import +client/mariadb-plugin +client/mariadb-show +client/mariadb-slap +client/mariadb-test +client/mariadb-upgrade +extra/mariabackup/mariadb-backup +extra/mariadb-waitpid +extra/mariadbd-safe-helper +libmysqld/examples/mariadb-client-test-embedded +libmysqld/examples/mariadb-embedded +libmysqld/examples/mariadb-test-embedded +man/mariadb-access.1 +man/mariadb-admin.1 +man/mariadb-backup.1 +man/mariadb-binlog.1 +man/mariadb-check.1 +man/mariadb-client-test-embedded.1 +man/mariadb-client-test.1 +man/mariadb-convert-table-format.1 +man/mariadb-dump.1 +man/mariadb-dumpslow.1 +man/mariadb-embedded.1 +man/mariadb-find-rows.1 +man/mariadb-fix-extensions.1 +man/mariadb-hotcopy.1 +man/mariadb-import.1 +man/mariadb-install-db.1 +man/mariadb-ldb.1 +man/mariadb-plugin.1 +man/mariadb-secure-installation.1 +man/mariadb-setpermission.1 +man/mariadb-show.1 +man/mariadb-slap.1 +man/mariadb-test-embedded.1 +man/mariadb-test.1 +man/mariadb-tzinfo-to-sql.1 +man/mariadb-upgrade.1 +man/mariadb-waitpid.1 +man/mariadb.1 +man/mariadbd-multi.1 +man/mariadbd-safe-helper.1 +man/mariadbd-safe.1 +man/mariadbd.8 +scripts/mariadb-access +scripts/mariadb-convert-table-format +scripts/mariadb-dumpslow +scripts/mariadb-find-rows +scripts/mariadb-fix-extensions +scripts/mariadb-hotcopy +scripts/mariadb-install-db +scripts/mariadb-secure-installation +scripts/mariadb-setpermission +scripts/mariadbd-multi +scripts/mariadbd-safe +sql/mariadb-tzinfo-to-sql +sql/mariadbd +storage/rocksdb/mariadb-ldb +tests/mariadb-client-test diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index a4ba10c28e5..f04ab691af1 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -101,17 +101,13 @@ FUNCTION(INSTALL_SCRIPT) IF(NOT ARG_DESTINATION) SET(ARG_DESTINATION ${INSTALL_BINDIR}) ENDIF() - IF(ARG_COMPONENT) - SET(COMP COMPONENT ${ARG_COMPONENT}) - ELSE() - SET(COMP) - ENDIF() + SET(COMP ${ARG_COMPONENT}) IF (COMP MATCHES ${SKIP_COMPONENTS}) RETURN() ENDIF() - INSTALL(PROGRAMS ${script} DESTINATION ${ARG_DESTINATION} ${COMP}) + INSTALL(PROGRAMS ${script} DESTINATION ${ARG_DESTINATION} COMPONENT ${COMP}) get_filename_component(dest "${script}" NAME) CREATE_MARIADB_SYMLINK(${dest} ${ARG_DESTINATION} ${COMP}) diff --git a/cmake/mysql_add_executable.cmake b/cmake/mysql_add_executable.cmake index d894ee2de9a..54fdab7b17c 100644 --- a/cmake/mysql_add_executable.cmake +++ b/cmake/mysql_add_executable.cmake @@ -70,16 +70,16 @@ FUNCTION (MYSQL_ADD_EXECUTABLE) SET(ARG_DESTINATION ${INSTALL_BINDIR}) ENDIF() IF(ARG_COMPONENT) - SET(COMP COMPONENT ${ARG_COMPONENT}) + SET(COMP ${ARG_COMPONENT}) ELSEIF(MYSQL_INSTALL_COMPONENT) - SET(COMP COMPONENT ${MYSQL_INSTALL_COMPONENT}) + SET(COMP ${MYSQL_INSTALL_COMPONENT}) ELSE() - SET(COMP COMPONENT Client) + SET(COMP Client) ENDIF() IF (COMP MATCHES ${SKIP_COMPONENTS}) RETURN() ENDIF() - MYSQL_INSTALL_TARGETS(${target} DESTINATION ${ARG_DESTINATION} ${COMP}) + MYSQL_INSTALL_TARGETS(${target} DESTINATION ${ARG_DESTINATION} COMPONENT ${COMP}) ENDIF() # create mariadb named symlink diff --git a/cmake/symlinks.cmake b/cmake/symlinks.cmake index 8fbdc93e869..251532892c2 100644 --- a/cmake/symlinks.cmake +++ b/cmake/symlinks.cmake @@ -12,6 +12,7 @@ REGISTER_SYMLINK("mariabackup" "mariadb-backup") REGISTER_SYMLINK("mysqlbinlog" "mariadb-binlog") REGISTER_SYMLINK("mysqlcheck" "mariadb-check") REGISTER_SYMLINK("mysql_client_test_embedded" "mariadb-client-test-embedded") +REGISTER_SYMLINK("mysql_client_test" "mariadb-client-test") REGISTER_SYMLINK("mariadb_config" "mariadb-config") REGISTER_SYMLINK("mysql_convert_table_format" "mariadb-convert-table-format") REGISTER_SYMLINK("mysqldump" "mariadb-dump") @@ -30,7 +31,6 @@ REGISTER_SYMLINK("mysqlshow" "mariadb-show") REGISTER_SYMLINK("mysqlslap" "mariadb-slap") REGISTER_SYMLINK("mysqltest" "mariadb-test") REGISTER_SYMLINK("mysqltest_embedded" "mariadb-test-embedded") -REGISTER_SYMLINK("mytop" "mariadb-top") REGISTER_SYMLINK("mysql_tzinfo_to_sql" "mariadb-tzinfo-to-sql") REGISTER_SYMLINK("mysql_upgrade" "mariadb-upgrade") REGISTER_SYMLINK("mysql_upgrade_service" "mariadb-upgrade-service") @@ -59,7 +59,7 @@ endmacro(CREATE_MARIADB_SYMLINK) macro(CREATE_MARIADB_SYMLINK_IN_DIR src dest dir comp) if(UNIX) add_custom_target( - symlink_${dest}_${comp} ALL + SYM_${dest} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${dest} ) diff --git a/debian/mariadb-backup.install b/debian/mariadb-backup.install index 734117c92e2..21a32860b0c 100644 --- a/debian/mariadb-backup.install +++ b/debian/mariadb-backup.install @@ -1,2 +1,4 @@ usr/bin/mariabackup usr/bin/mbstream +usr/share/man/man1/mariabackup.1 +usr/share/man/man1/mariadb-backup.1 diff --git a/debian/mariadb-backup.links b/debian/mariadb-backup.links new file mode 100644 index 00000000000..7980ef5e54d --- /dev/null +++ b/debian/mariadb-backup.links @@ -0,0 +1 @@ +usr/bin/mariabackup usr/bin/mariadb-backup diff --git a/debian/mariadb-client-10.4.install b/debian/mariadb-client-10.4.install index 945bf77c689..9cb4ee3dede 100644 --- a/debian/mariadb-client-10.4.install +++ b/debian/mariadb-client-10.4.install @@ -20,3 +20,14 @@ usr/share/man/man1/mysqldumpslow.1 usr/share/man/man1/mysqlimport.1 usr/share/man/man1/mysqlshow.1 usr/share/man/man1/mysqlslap.1 +usr/share/man/man1/mariadb-access.1 +usr/share/man/man1/mariadb-admin.1 +usr/share/man/man1/mariadb-binlog.1 +usr/share/man/man1/mariadb-dump.1 +usr/share/man/man1/mariadb-dumpslow.1 +usr/share/man/man1/mariadb-find-rows.1 +usr/share/man/man1/mariadb-fix-extensions.1 +usr/share/man/man1/mariadb-import.1 +usr/share/man/man1/mariadb-plugin.1 +usr/share/man/man1/mariadb-slap.1 +usr/share/man/man1/mariadb-waitpid.1 diff --git a/debian/mariadb-client-10.4.links b/debian/mariadb-client-10.4.links index b93d2d7f8fd..5d966575b76 100644 --- a/debian/mariadb-client-10.4.links +++ b/debian/mariadb-client-10.4.links @@ -1,10 +1,9 @@ usr/bin/mysql_find_rows usr/bin/mariadb-find-rows -usr/bin/mysql_fix_extensions usr/bin/mariadb-fix-extenstions +usr/bin/mysql_fix_extensions usr/bin/mariadb-fix-extensions usr/bin/mysql_plugin usr/bin/mariadb-plugin usr/bin/mysql_waitpid usr/bin/mariadb-waitpid usr/bin/mysqlaccess usr/bin/mariadb-access usr/bin/mysqladmin usr/bin/mariadb-admin -usr/bin/mysqlanalyze usr/bin/mariadb-analyze usr/bin/mysqlbinlog usr/bin/mariadb-binlog usr/bin/mysqlcheck usr/bin/mariadb-analyze usr/bin/mysqlcheck usr/bin/mariadb-optimize @@ -13,32 +12,14 @@ usr/bin/mysqlcheck usr/bin/mysqlanalyze usr/bin/mysqlcheck usr/bin/mysqloptimize usr/bin/mysqlcheck usr/bin/mysqlrepair usr/bin/mysqldump usr/bin/mariadb-dump -usr/bin/mysqldumpslow usr/bin/mariadb-dump-slow +usr/bin/mysqldumpslow usr/bin/mariadb-dumpslow usr/bin/mysqlimport usr/bin/mariadb-import -usr/bin/mysqloptimize usr/bin/mariadb-optimize -usr/bin/mysqlrepair usr/bin/mariadb-repair usr/bin/mysqlreport usr/bin/mariadb-report usr/bin/mysqlslap usr/bin/mariadb-slap -usr/bin/mysqltest usr/bin/mariadb-test -usr/share/man/man1/mysql_find_rows.1.gz usr/share/man/man1/mariadb-find-rows.1.gz -usr/share/man/man1/mysql_fix_extensions.1.gz usr/share/man/man1/mariadb-fix-extensions.1.gz -usr/share/man/man1/mysql_plugin.1.gz usr/share/man/man1/mariadb-plugin.1.gz -usr/share/man/man1/mysql_waitpid.1.gz usr/share/man/man1/mariadb-waitpid.1.gz -usr/share/man/man1/mysqlaccess.1.gz usr/share/man/man1/mariadb-access.1.gz -usr/share/man/man1/mysqladmin.1.gz usr/share/man/man1/mariadb-admin.1.gz -usr/share/man/man1/mysqlanalyze.1.gz usr/share/man/man1/mariadb-analyze.1.gz -usr/share/man/man1/mysqlbinlog.1.gz usr/share/man/man1/mariadb-binlog.1.gz usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mariadb-analyze.1.gz usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mariadb-optimize.1.gz usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mariadb-repair.1.gz usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mysqlanalyze.1.gz usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mysqloptimize.1.gz usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mysqlrepair.1.gz -usr/share/man/man1/mysqldump.1.gz usr/share/man/man1/mariadb-dump.1.gz -usr/share/man/man1/mysqldumpslow.1.gz usr/share/man/man1/mariadb-dump-slow.1.gz -usr/share/man/man1/mysqlimport.1.gz usr/share/man/man1/mariadb-import.1.gz -usr/share/man/man1/mysqloptimize.1.gz usr/share/man/man1/mariadb-optimize.1.gz -usr/share/man/man1/mysqlrepair.1.gz usr/share/man/man1/mariadb-repair.1.gz usr/share/man/man1/mysqlreport.1.gz usr/share/man/man1/mariadb-report.1.gz -usr/share/man/man1/mysqlslap.1.gz usr/share/man/man1/mariadb-slap.1.gz -usr/share/man/man1/mysqltest.1.gz usr/share/man/man1/mariadb-test.1.gz diff --git a/debian/mariadb-client-core-10.4.install b/debian/mariadb-client-core-10.4.install index a2781309439..0706b272e8a 100644 --- a/debian/mariadb-client-core-10.4.install +++ b/debian/mariadb-client-core-10.4.install @@ -2,3 +2,5 @@ usr/bin/mysql usr/bin/mysqlcheck usr/share/man/man1/mysql.1 usr/share/man/man1/mysqlcheck.1 +usr/share/man/man1/mariadb.1 +usr/share/man/man1/mariadb-check.1 diff --git a/debian/mariadb-client-core-10.4.links b/debian/mariadb-client-core-10.4.links index 4c5ff23b38b..d889e7164b0 100644 --- a/debian/mariadb-client-core-10.4.links +++ b/debian/mariadb-client-core-10.4.links @@ -1,4 +1,2 @@ usr/bin/mysql usr/bin/mariadb usr/bin/mysqlcheck usr/bin/mariadb-check -usr/share/man/man1/mysql.1.gz usr/share/man/man1/mariadb.1.gz -usr/share/man/man1/mysqlcheck.1.gz usr/share/man/man1/mariadb-check.1.gz diff --git a/debian/mariadb-plugin-rocksdb.install b/debian/mariadb-plugin-rocksdb.install index 403c7f291b6..a2b8b805cdb 100644 --- a/debian/mariadb-plugin-rocksdb.install +++ b/debian/mariadb-plugin-rocksdb.install @@ -1,5 +1,7 @@ etc/mysql/conf.d/rocksdb.cnf etc/mysql/mariadb.conf.d usr/bin/myrocks_hotbackup usr/bin/mysql_ldb +usr/share/man/man1/mariadb-ldb.1 +usr/share/man/man1/mysql_ldb.1 usr/bin/sst_dump usr/lib/mysql/plugin/ha_rocksdb.so diff --git a/debian/mariadb-plugin-rocksdb.links b/debian/mariadb-plugin-rocksdb.links new file mode 100644 index 00000000000..78e47d43359 --- /dev/null +++ b/debian/mariadb-plugin-rocksdb.links @@ -0,0 +1 @@ +usr/bin/mysql_ldb usr/bin/mariadb-ldb diff --git a/debian/mariadb-server-10.4.install b/debian/mariadb-server-10.4.install index bfc5f907d09..6d08243d675 100644 --- a/debian/mariadb-server-10.4.install +++ b/debian/mariadb-server-10.4.install @@ -66,7 +66,16 @@ usr/share/man/man1/aria_pack.1 usr/share/man/man1/aria_read_log.1 usr/share/man/man1/galera_new_cluster.1 usr/share/man/man1/galera_recovery.1 +usr/share/man/man1/mariadb-convert-table-format.1 +usr/share/man/man1/mariadb-hotcopy.1 +usr/share/man/man1/mariadb-secure-installation.1 usr/share/man/man1/mariadb-service-convert.1 +usr/share/man/man1/mariadb-setpermission.1 +usr/share/man/man1/mariadb-show.1 +usr/share/man/man1/mariadb-tzinfo-to-sql.1 +usr/share/man/man1/mariadbd-multi.1 +usr/share/man/man1/mariadbd-safe-helper.1 +usr/share/man/man1/mariadbd-safe.1 usr/share/man/man1/msql2mysql.1 usr/share/man/man1/my_print_defaults.1 usr/share/man/man1/myisam_ftdump.1 diff --git a/debian/mariadb-server-10.4.links b/debian/mariadb-server-10.4.links index 65e0a6650d5..f2d97460371 100644 --- a/debian/mariadb-server-10.4.links +++ b/debian/mariadb-server-10.4.links @@ -2,17 +2,8 @@ usr/bin/mysql_convert_table_format usr/bin/mariadb-convert-table-format usr/bin/mysql_secure_installation usr/bin/mariadb-secure-installation usr/bin/mysql_setpermission usr/bin/mariadb-setpermission usr/bin/mysql_tzinfo_to_sql usr/bin/mariadb-tzinfo-to-sql -usr/bin/mysqld_multi usr/bin/mariadb-multi -usr/bin/mysqld_safe usr/bin/mariadb-safe -usr/bin/mysqld_safe_helper usr/bin/mariadb-safe-helper +usr/bin/mysqld_multi usr/bin/mariadbd-multi +usr/bin/mysqld_safe usr/bin/mariadbd-safe +usr/bin/mysqld_safe_helper usr/bin/mariadbd-safe-helper usr/bin/mysqlhotcopy usr/bin/mariadb-hotcopy usr/bin/mysqlshow usr/bin/mariadb-show -usr/share/man/man1/mysql_convert_table_format.1.gz usr/share/man/man1/mariadb-convert-table-format.1.gz -usr/share/man/man1/mysql_secure_installation.1.gz usr/share/man/man1/mariadb-secure-installation.1.gz -usr/share/man/man1/mysql_setpermission.1.gz usr/share/man/man1/mariadb-setpermission.1.gz -usr/share/man/man1/mysql_tzinfo_to_sql.1.gz usr/share/man/man1/mariadb-tzinfo-to-sql.1.gz -usr/share/man/man1/mysqld_multi.1.gz usr/share/man/man1/mariadb-multi.1.gz -usr/share/man/man1/mysqld_safe.1.gz usr/share/man/man1/mariadb-safe.1.gz -usr/share/man/man1/mysqld_safe_helper.1.gz usr/share/man/man1/mariadb-safe-helper.1.gz -usr/share/man/man1/mysqlhotcopy.1.gz usr/share/man/man1/mariadb-hotcopy.1.gz -usr/share/man/man1/mysqlshow.1.gz usr/share/man/man1/mariadb-show.1.gz diff --git a/debian/mariadb-server-core-10.4.install b/debian/mariadb-server-core-10.4.install index 46c116b618d..24f967252a2 100644 --- a/debian/mariadb-server-core-10.4.install +++ b/debian/mariadb-server-core-10.4.install @@ -6,6 +6,9 @@ usr/share/man/man1/innochecksum.1 usr/share/man/man1/mysql_install_db.1 usr/share/man/man1/mysql_upgrade.1 usr/share/man/man8/mysqld.8 +usr/share/man/man1/mariadb-install-db.1 +usr/share/man/man1/mariadb-upgrade.1 +usr/share/man/man8/mariadbd.8 usr/share/mysql/charsets usr/share/mysql/czech usr/share/mysql/danish diff --git a/debian/mariadb-server-core-10.4.links b/debian/mariadb-server-core-10.4.links index 90ed9ee01cf..b7873f93141 100644 --- a/debian/mariadb-server-core-10.4.links +++ b/debian/mariadb-server-core-10.4.links @@ -1,4 +1,3 @@ usr/bin/mysql_install_db usr/bin/mariadb-install-db usr/bin/mysql_upgrade usr/bin/mariadb-upgrade -usr/share/man/man1/mysql_install_db.1.gz usr/share/man/man1/mariadb-install-db.1.gz -usr/share/man/man1/mysql_upgrade.1.gz usr/share/man/man1/mariadb-upgrade-db.1.gz +usr/sbin/mysqld usr/sbin/mariadbd diff --git a/debian/mariadb-test.install b/debian/mariadb-test.install index f715825274c..5d3afda68d4 100644 --- a/debian/mariadb-test.install +++ b/debian/mariadb-test.install @@ -23,6 +23,10 @@ usr/share/man/man1/mysql_client_test.1 usr/share/man/man1/mysql_client_test_embedded.1 usr/share/man/man1/mysqltest.1 usr/share/man/man1/mysqltest_embedded.1 +usr/share/man/man1/mariadb-client-test-embedded.1 +usr/share/man/man1/mariadb-client-test.1 +usr/share/man/man1/mariadb-test-embedded.1 +usr/share/man/man1/mariadb-test.1 usr/share/mysql/mysql-test/README usr/share/mysql/mysql-test/README-gcov usr/share/mysql/mysql-test/README.stress diff --git a/debian/mariadb-test.links b/debian/mariadb-test.links index 884b25a81da..8b9ca6fe98b 100644 --- a/debian/mariadb-test.links +++ b/debian/mariadb-test.links @@ -1,2 +1,6 @@ usr/share/mysql/mysql-test/mysql-test-run.pl usr/share/mysql/mysql-test/mtr usr/share/mysql/mysql-test/mysql-test-run.pl usr/share/mysql/mysql-test/mysql-test-run +usr/bin/mysql_client_test_embedded usr/bin/mariadb-client-test-embedded +usr/bin/mysqltest_embedded usr/bin/mariadb-test-embedded +usr/bin/mysql_client_test usr/bin/mariadb-client-test +usr/bin/mysqltest usr/bin/mariadb-test diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index c89d156718d..9ceda0c4c33 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -77,9 +77,10 @@ macro(MARIADB_SYMLINK_MANPAGE) endmacro(MARIADB_SYMLINK_MANPAGE) macro(MARIADB_SYMLINK_MANPAGE_CREATE mysqlname index mannr dir comp) - list(GET MARIADB_SYMLINK_TOS ${index} _mariadbname) - set(symlinkname "${_mariadbname}.${mannr}") - CREATE_MARIADB_SYMLINK_IN_DIR(${mysqlname}.${mannr} ${symlinkname} ${INSTALL_MANDIR}/${dir} ${comp}) + LIST(GET MARIADB_SYMLINK_TOS ${index} _mariadbname) + SET(dest "${CMAKE_CURRENT_BINARY_DIR}/${_mariadbname}.${mannr}") + FILE(WRITE ${dest} ".so ${mysqlname}.${mannr}") + INSTALL(FILES ${dest} DESTINATION ${INSTALL_MANDIR}/${dir} COMPONENT ${comp}) endmacro(MARIADB_SYMLINK_MANPAGE_CREATE) MARIADB_SYMLINK_MANPAGE() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 917ec458203..cb6c756cfe3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,7 +22,7 @@ INCLUDE_DIRECTORIES(BEFORE ${CMAKE_BINARY_DIR}/libmariadb/include ${CMAKE_SOURCE_DIR}/libmariadb/include) -ADD_EXECUTABLE(mysql_client_test mysql_client_test.c) +MYSQL_ADD_EXECUTABLE(mysql_client_test mysql_client_test.c COMPONENT Test) SET(CLIENT_LIB mariadbclient mysys) TARGET_LINK_LIBRARIES(mysql_client_test ${CLIENT_LIB}) @@ -34,8 +34,6 @@ IF(WITH_UNIT_TESTS) ADD_DEPENDENCIES(bug25714 GenError ${CLIENT_LIB}) ENDIF() -INSTALL(TARGETS mysql_client_test DESTINATION ${INSTALL_BINDIR} COMPONENT Test) - CHECK_INCLUDE_FILE(event.h HAVE_EVENT_H) FIND_LIBRARY(EVENT_LIBRARY event) MARK_AS_ADVANCED(EVENT_LIBRARY) From e85e4814eeca9123b23c23b40dd776416bfba2ca Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 17 Jun 2019 17:26:42 +0200 Subject: [PATCH 57/57] 10.4.6 is stable, not gamma --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 9e556e06de4..b594c4a91b0 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=4 MYSQL_VERSION_PATCH=6 -SERVER_MATURITY=gamma +SERVER_MATURITY=stable