summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/control2
-rw-r--r--mysql-test/r/func_isnull.result20
-rw-r--r--mysql-test/r/func_time.result5
-rw-r--r--mysql-test/r/group_min_max.result17
-rw-r--r--mysql-test/r/mysql.result2
-rw-r--r--mysql-test/r/mysql_not_windows.result2
-rw-r--r--mysql-test/r/subselect_extra_no_semijoin.result22
-rw-r--r--mysql-test/r/subselect_mat.result6
-rw-r--r--mysql-test/r/subselect_sj_mat.result6
-rw-r--r--mysql-test/suite/galera/r/MW-44.result15
-rw-r--r--mysql-test/suite/galera/r/galera_binlog_stmt_autoinc.result161
-rw-r--r--mysql-test/suite/galera/r/galera_var_desync_on.result2
-rw-r--r--mysql-test/suite/galera/t/MW-44.test11
-rw-r--r--mysql-test/suite/galera/t/galera_binlog_stmt_autoinc.test223
-rw-r--r--mysql-test/suite/galera/t/galera_var_desync_on.test7
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_spatial.result16
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_spatial.test17
-rw-r--r--mysql-test/t/func_isnull.test16
-rw-r--r--mysql-test/t/func_time.test4
-rw-r--r--mysql-test/t/group_min_max.test27
-rw-r--r--mysql-test/t/mysql.test5
-rw-r--r--mysql-test/t/mysql_not_windows.test7
-rw-r--r--mysql-test/t/subselect_extra_no_semijoin.test31
-rw-r--r--scripts/wsrep_sst_rsync.sh80
-rw-r--r--sql/field.h46
-rw-r--r--sql/handler.cc31
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item_cmpfunc.cc6
-rw-r--r--sql/key.cc3
-rw-r--r--sql/mysqld.cc36
-rw-r--r--sql/protocol.cc8
-rw-r--r--sql/sql_class.h11
-rw-r--r--sql/sql_list.h5
-rw-r--r--sql/sql_select.cc10
-rw-r--r--sql/sql_show.cc2
-rw-r--r--sql/sql_time.cc2
-rw-r--r--sql/sys_vars.cc93
-rw-r--r--sql/wsrep_mysqld.h4
-rw-r--r--sql/wsrep_thd.cc22
-rw-r--r--sql/wsrep_var.cc6
-rw-r--r--storage/innobase/buf/buf0dump.cc4
-rw-r--r--storage/innobase/handler/ha_innodb.cc63
-rw-r--r--storage/innobase/lock/lock0lock.cc4
-rw-r--r--storage/innobase/log/log0log.cc13
-rw-r--r--storage/innobase/srv/srv0srv.cc14
-rw-r--r--storage/innobase/trx/trx0purge.cc17
-rw-r--r--storage/xtradb/buf/buf0dump.cc4
-rw-r--r--storage/xtradb/handler/ha_innodb.cc57
-rw-r--r--storage/xtradb/lock/lock0lock.cc5
-rw-r--r--storage/xtradb/log/log0log.cc13
-rw-r--r--storage/xtradb/srv/srv0srv.cc14
-rw-r--r--storage/xtradb/trx/trx0purge.cc18
52 files changed, 1070 insertions, 147 deletions
diff --git a/debian/control b/debian/control
index 173b8e55584..47dd568e06d 100644
--- a/debian/control
+++ b/debian/control
@@ -571,7 +571,7 @@ Section: database
Architecture: any
Breaks: mariadb-backup-10.1
Replaces: mariadb-backup-10.1
-Depends: mariadb-server-10.2,
+Depends: mariadb-client-core-10.2 (= ${binary:Version}),
${misc:Depends},
${shlibs:Depends}
Description: Backup tool for MariaDB server
diff --git a/mysql-test/r/func_isnull.result b/mysql-test/r/func_isnull.result
index 15d87997e29..8cbd528f2de 100644
--- a/mysql-test/r/func_isnull.result
+++ b/mysql-test/r/func_isnull.result
@@ -106,5 +106,25 @@ Note 1003 select `test`.`t2`.`d1` AS `d1`,`test`.`t1`.`d1` AS `d1` from `test`.`
DROP VIEW v1;
DROP TABLE t1,t2;
#
+# MDEV-15475: Assertion `!table || (!table->read_set ||
+# bitmap_is_set(table->read_set, field_index))'
+# failed on EXPLAIN EXTENDED with constant table and view
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=MyISAM;
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1);
+EXPLAIN EXTENDED SELECT ISNULL(pk) FROM v1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select /*always not null*/ 1 is null AS `ISNULL(pk)` from dual
+EXPLAIN EXTENDED SELECT IFNULL(pk,0) FROM v1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select ifnull(1,0) AS `IFNULL(pk,0)` from dual
+DROP VIEW v1;
+DROP TABLE t1;
+#
# End of 5.5 tests
#
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 55c2c93eb56..3edd4ad1fdc 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -2797,6 +2797,11 @@ SEC_TO_TIME(MAKEDATE(0,RAND(~0)))
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '20000101'
+SELECT PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli'));
+PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli'))
+24257
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: '-3S\xFA\xDE?\x00\x00\xCA\xB3\xEEE\xA4\xD1\xC1\xA8'
#
# End of 5.5 tests
#
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index 36a44b05817..b3b660c4170 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -3893,5 +3893,22 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index a a 13 NULL 2 Using where; Using index
drop table t1;
#
+# MDEV-15433: Optimizer does not use group by optimization with distinct
+#
+CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, a INT NOT NULL, KEY(a));
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+EXPLAIN SELECT DISTINCT a FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range NULL a 4 NULL 5 Using index for group-by
+SELECT DISTINCT a FROM t1;
+a
+1
+2
+3
+4
+drop table t1;
+#
# End of 10.1 tests
#
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index 09f014da627..06ef7e95bc9 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -538,8 +538,6 @@ a
#
# End of 10.1 tests
#
-ERROR 1300 (HY000): Invalid utf8 character string: 'test\xF0\x9F\x98\x81 '
-ERROR 1300 (HY000): Invalid binary character string: 'test\xF0\x9F\x98\x81 '
ERROR 1300 (HY000) at line 2: Invalid utf8 character string: 'test\xF0\x9F\x98\x81'
set GLOBAL sql_mode=default;
diff --git a/mysql-test/r/mysql_not_windows.result b/mysql-test/r/mysql_not_windows.result
index 1df62d9a12d..96210a366a6 100644
--- a/mysql-test/r/mysql_not_windows.result
+++ b/mysql-test/r/mysql_not_windows.result
@@ -9,3 +9,5 @@ End of tests
2
X
3
+ERROR 1300 (HY000): Invalid utf8 character string: 'test\xF0\x9F\x98\x81 '
+ERROR 1300 (HY000): Invalid binary character string: 'test\xF0\x9F\x98\x81 '
diff --git a/mysql-test/r/subselect_extra_no_semijoin.result b/mysql-test/r/subselect_extra_no_semijoin.result
index 8ed260cb31a..2552bcc1859 100644
--- a/mysql-test/r/subselect_extra_no_semijoin.result
+++ b/mysql-test/r/subselect_extra_no_semijoin.result
@@ -482,3 +482,25 @@ DROP TABLE t1,t2;
set optimizer_switch= @tmp_subselect_extra_derived;
set optimizer_switch= @subselect_extra_no_sj_tmp;
set @optimizer_switch_for_subselect_extra_test=null;
+#
+# MDEV-6439: Server crashes in Explain_union::print_explain with explain in slow log, tis620 charset
+#
+connect con1,localhost,root,,;
+SET NAMES tis620;
+set @tmp= @@global.slow_query_log;
+SET GLOBAL slow_query_log = 1;
+SET long_query_time = 0.000001;
+SET log_slow_verbosity = 'explain';
+CREATE TABLE t1 (a VARCHAR(3)) ENGINE=MyISAM;
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo');
+a
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' );
+ERROR HY000: Illegal mix of collations (tis620_thai_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<='
+create table t2 (b int);
+insert into t2 values (1),(2),(3);
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' FROM t2);
+ERROR HY000: Illegal mix of collations (tis620_thai_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<='
+drop table t1,t2;
+SET GLOBAL slow_query_log=@tmp;
+disconnect con1;
+connection default;
diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result
index 369d175a8c9..dd80cd719e8 100644
--- a/mysql-test/r/subselect_mat.result
+++ b/mysql-test/r/subselect_mat.result
@@ -499,7 +499,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or /*always not null*/ 1 is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or /*always not null*/ 1 is null) and '1 - 01' is null and '2 - 01' is null)))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
a1 a2
1 - 01 2 - 01
@@ -509,7 +509,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or /*always not null*/ 1 is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or /*always not null*/ 1 is null) and '1 - 01' is null and '2 - 01' is null)))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
a1 a2
1 - 01 2 - 01
@@ -1925,7 +1925,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(`<subquery2>`.`MAX(c)` is null) or `<subquery2>`.`MAX(c)` = 7)
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(/*always not null*/ 1 is null) or `<subquery2>`.`MAX(c)` = 7)
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
a b
diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result
index 84198885ed3..5dc094a500d 100644
--- a/mysql-test/r/subselect_sj_mat.result
+++ b/mysql-test/r/subselect_sj_mat.result
@@ -520,7 +520,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or /*always not null*/ 1 is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or /*always not null*/ 1 is null) and '1 - 01' is null and '2 - 01' is null)))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
a1 a2
1 - 01 2 - 01
@@ -530,7 +530,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or /*always not null*/ 1 is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or /*always not null*/ 1 is null) and '1 - 01' is null and '2 - 01' is null)))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
a1 a2
1 - 01 2 - 01
@@ -1963,7 +1963,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(`<subquery2>`.`MAX(c)` is null) or `<subquery2>`.`MAX(c)` = 7)
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(/*always not null*/ 1 is null) or `<subquery2>`.`MAX(c)` = 7)
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
a b
diff --git a/mysql-test/suite/galera/r/MW-44.result b/mysql-test/suite/galera/r/MW-44.result
index 459a61030a4..a1e55318422 100644
--- a/mysql-test/suite/galera/r/MW-44.result
+++ b/mysql-test/suite/galera/r/MW-44.result
@@ -1,21 +1,10 @@
SET GLOBAL general_log='OFF';
TRUNCATE TABLE mysql.general_log;
-SELECT COUNT(*) from mysql.general_log;
-COUNT(*)
-0
-SELECT * FROM mysql.general_log;
-event_time user_host thread_id server_id command_type argument
SET GLOBAL general_log='OFF';
TRUNCATE TABLE mysql.general_log;
-SELECT COUNT(*) from mysql.general_log;
-COUNT(*)
-0
-SELECT * FROM mysql.general_log;
-event_time user_host thread_id server_id command_type argument
SET GLOBAL general_log='ON';
-SELECT COUNT(*) from mysql.general_log;
-COUNT(*)
-1
+SELECT argument from mysql.general_log WHERE argument NOT LIKE 'SELECT%';
+argument
SET SESSION wsrep_osu_method=TOI;
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
SET SESSION wsrep_osu_method=RSU;
diff --git a/mysql-test/suite/galera/r/galera_binlog_stmt_autoinc.result b/mysql-test/suite/galera/r/galera_binlog_stmt_autoinc.result
new file mode 100644
index 00000000000..78b40228eb0
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_binlog_stmt_autoinc.result
@@ -0,0 +1,161 @@
+connection node_1;
+connection node_2;
+connection node_2;
+SET GLOBAL wsrep_forced_binlog_format='STATEMENT';
+connection node_1;
+SET GLOBAL wsrep_forced_binlog_format='STATEMENT';
+CREATE TABLE t1 (
+i int(11) NOT NULL AUTO_INCREMENT,
+c char(32) DEFAULT 'dummy_text',
+PRIMARY KEY (i)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+insert into t1(i) values(null);
+select * from t1;
+i c
+1 dummy_text
+insert into t1(i) values(null), (null), (null);
+select * from t1;
+i c
+1 dummy_text
+3 dummy_text
+5 dummy_text
+7 dummy_text
+connection node_2;
+select * from t1;
+i c
+1 dummy_text
+3 dummy_text
+5 dummy_text
+7 dummy_text
+SET GLOBAL wsrep_forced_binlog_format='none';
+connection node_1;
+SET GLOBAL wsrep_forced_binlog_format='none';
+drop table t1;
+SET SESSION binlog_format='STATEMENT';
+show variables like 'binlog_format';
+Variable_name Value
+binlog_format STATEMENT
+SET GLOBAL wsrep_auto_increment_control='OFF';
+SET SESSION auto_increment_increment = 3;
+SET SESSION auto_increment_offset = 1;
+CREATE TABLE t1 (
+i int(11) NOT NULL AUTO_INCREMENT,
+c char(32) DEFAULT 'dummy_text',
+PRIMARY KEY (i)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+insert into t1(i) values(null);
+select * from t1;
+i c
+1 dummy_text
+insert into t1(i) values(null), (null), (null);
+select * from t1;
+i c
+1 dummy_text
+4 dummy_text
+7 dummy_text
+10 dummy_text
+connection node_2;
+select * from t1;
+i c
+1 dummy_text
+4 dummy_text
+7 dummy_text
+10 dummy_text
+connection node_1;
+SET GLOBAL wsrep_auto_increment_control='ON';
+SET SESSION binlog_format='ROW';
+show variables like 'binlog_format';
+Variable_name Value
+binlog_format ROW
+show variables like '%auto_increment%';
+Variable_name Value
+auto_increment_increment 2
+auto_increment_offset 1
+wsrep_auto_increment_control ON
+SET GLOBAL wsrep_auto_increment_control='OFF';
+show variables like '%auto_increment%';
+Variable_name Value
+auto_increment_increment 3
+auto_increment_offset 1
+wsrep_auto_increment_control OFF
+SET GLOBAL wsrep_auto_increment_control='ON';
+drop table t1;
+connection node_2;
+SET GLOBAL wsrep_forced_binlog_format='ROW';
+connection node_1;
+SET GLOBAL wsrep_forced_binlog_format='ROW';
+CREATE TABLE t1 (
+i int(11) NOT NULL AUTO_INCREMENT,
+c char(32) DEFAULT 'dummy_text',
+PRIMARY KEY (i)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+insert into t1(i) values(null);
+select * from t1;
+i c
+1 dummy_text
+insert into t1(i) values(null), (null), (null);
+select * from t1;
+i c
+1 dummy_text
+3 dummy_text
+5 dummy_text
+7 dummy_text
+connection node_2;
+select * from t1;
+i c
+1 dummy_text
+3 dummy_text
+5 dummy_text
+7 dummy_text
+SET GLOBAL wsrep_forced_binlog_format='none';
+connection node_1;
+SET GLOBAL wsrep_forced_binlog_format='none';
+drop table t1;
+SET SESSION binlog_format='ROW';
+show variables like 'binlog_format';
+Variable_name Value
+binlog_format ROW
+SET GLOBAL wsrep_auto_increment_control='OFF';
+SET SESSION auto_increment_increment = 3;
+SET SESSION auto_increment_offset = 1;
+CREATE TABLE t1 (
+i int(11) NOT NULL AUTO_INCREMENT,
+c char(32) DEFAULT 'dummy_text',
+PRIMARY KEY (i)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+insert into t1(i) values(null);
+select * from t1;
+i c
+1 dummy_text
+insert into t1(i) values(null), (null), (null);
+select * from t1;
+i c
+1 dummy_text
+4 dummy_text
+7 dummy_text
+10 dummy_text
+connection node_2;
+select * from t1;
+i c
+1 dummy_text
+4 dummy_text
+7 dummy_text
+10 dummy_text
+connection node_1;
+SET GLOBAL wsrep_auto_increment_control='ON';
+show variables like 'binlog_format';
+Variable_name Value
+binlog_format ROW
+show variables like '%auto_increment%';
+Variable_name Value
+auto_increment_increment 2
+auto_increment_offset 1
+wsrep_auto_increment_control ON
+SET GLOBAL wsrep_auto_increment_control='OFF';
+show variables like '%auto_increment%';
+Variable_name Value
+auto_increment_increment 3
+auto_increment_offset 1
+wsrep_auto_increment_control OFF
+SET GLOBAL wsrep_auto_increment_control='ON';
+drop table t1;
diff --git a/mysql-test/suite/galera/r/galera_var_desync_on.result b/mysql-test/suite/galera/r/galera_var_desync_on.result
index a26acbd4d6b..26798e51926 100644
--- a/mysql-test/suite/galera/r/galera_var_desync_on.result
+++ b/mysql-test/suite/galera/r/galera_var_desync_on.result
@@ -2,7 +2,6 @@ CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
connection node_2;
SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=1';
-SET GLOBAL wsrep_desync = TRUE;
FLUSH TABLES WITH READ LOCK;
connection node_1;
INSERT INTO t1 VALUES (2);
@@ -19,7 +18,6 @@ SET SESSION wsrep_sync_wait = 0;
SELECT COUNT(*) = 1 FROM t1;
COUNT(*) = 1
1
-SET GLOBAL wsrep_desync = FALSE;
UNLOCK TABLES;
SET SESSION wsrep_sync_wait = 1;
SELECT COUNT(*) = 10 FROM t1;
diff --git a/mysql-test/suite/galera/t/MW-44.test b/mysql-test/suite/galera/t/MW-44.test
index 7c988a29548..e8caa28c80e 100644
--- a/mysql-test/suite/galera/t/MW-44.test
+++ b/mysql-test/suite/galera/t/MW-44.test
@@ -8,20 +8,21 @@
--connection node_1
SET GLOBAL general_log='OFF';
TRUNCATE TABLE mysql.general_log;
-SELECT COUNT(*) from mysql.general_log;
-SELECT * FROM mysql.general_log;
+--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.general_log;
+--source include/wait_condition.inc
--sleep 1
--connection node_2
SET GLOBAL general_log='OFF';
TRUNCATE TABLE mysql.general_log;
-SELECT COUNT(*) from mysql.general_log;
-SELECT * FROM mysql.general_log;
+--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.general_log;
+--source include/wait_condition.inc
--sleep 1
--connection node_1
SET GLOBAL general_log='ON';
-SELECT COUNT(*) from mysql.general_log;
+SELECT argument from mysql.general_log WHERE argument NOT LIKE 'SELECT%';
+
SET SESSION wsrep_osu_method=TOI;
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
SET SESSION wsrep_osu_method=RSU;
diff --git a/mysql-test/suite/galera/t/galera_binlog_stmt_autoinc.test b/mysql-test/suite/galera/t/galera_binlog_stmt_autoinc.test
new file mode 100644
index 00000000000..aab4fea9f2e
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_binlog_stmt_autoinc.test
@@ -0,0 +1,223 @@
+##
+## Tests the auto-increment with binlog in STATEMENT mode.
+##
+
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+--let $node_1=node_1
+--let $node_2=node_2
+--source include/auto_increment_offset_save.inc
+
+##
+## Verify the correct operation of the auto-increment when the binlog
+## format artificially set to the 'STATEMENT' (although this mode is
+## not recommended in the current version):
+##
+
+--connection node_2
+SET GLOBAL wsrep_forced_binlog_format='STATEMENT';
+
+--connection node_1
+SET GLOBAL wsrep_forced_binlog_format='STATEMENT';
+
+CREATE TABLE t1 (
+ i int(11) NOT NULL AUTO_INCREMENT,
+ c char(32) DEFAULT 'dummy_text',
+ PRIMARY KEY (i)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+insert into t1(i) values(null);
+
+select * from t1;
+
+insert into t1(i) values(null), (null), (null);
+
+select * from t1;
+
+--connection node_2
+
+select * from t1;
+
+SET GLOBAL wsrep_forced_binlog_format='none';
+
+--connection node_1
+
+SET GLOBAL wsrep_forced_binlog_format='none';
+
+drop table t1;
+
+##
+## Check the operation when the automatic control over the auto-increment
+## settings is switched off, that is, when we use the increment step and
+## the offset specified by the user. In the current session, the binlog
+## format is set to 'STATEMENT'. It is important that the values of the
+## auto-increment options does not changed on other node - it allows us
+## to check the correct transmission of the auto-increment options to
+## other nodes:
+##
+
+--disable_warnings
+SET SESSION binlog_format='STATEMENT';
+--enable_warnings
+
+show variables like 'binlog_format';
+
+SET GLOBAL wsrep_auto_increment_control='OFF';
+
+SET SESSION auto_increment_increment = 3;
+SET SESSION auto_increment_offset = 1;
+
+CREATE TABLE t1 (
+ i int(11) NOT NULL AUTO_INCREMENT,
+ c char(32) DEFAULT 'dummy_text',
+ PRIMARY KEY (i)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+insert into t1(i) values(null);
+
+select * from t1;
+
+insert into t1(i) values(null), (null), (null);
+
+select * from t1;
+
+--connection node_2
+
+select * from t1;
+
+--connection node_1
+
+##
+## Verify the return to automatic calculation of the step
+## and offset of the auto-increment:
+##
+
+SET GLOBAL wsrep_auto_increment_control='ON';
+
+SET SESSION binlog_format='ROW';
+
+show variables like 'binlog_format';
+show variables like '%auto_increment%';
+
+##
+## Verify the recovery of original user-defined values after
+## stopping the automatic control over auto-increment:
+##
+
+SET GLOBAL wsrep_auto_increment_control='OFF';
+
+show variables like '%auto_increment%';
+
+##
+## Restore original options and drop test table:
+##
+
+SET GLOBAL wsrep_auto_increment_control='ON';
+
+drop table t1;
+
+##
+## Verify the correct operation of the auto-increment when the binlog
+## format set to the 'ROW':
+##
+
+--connection node_2
+SET GLOBAL wsrep_forced_binlog_format='ROW';
+
+--connection node_1
+SET GLOBAL wsrep_forced_binlog_format='ROW';
+
+CREATE TABLE t1 (
+ i int(11) NOT NULL AUTO_INCREMENT,
+ c char(32) DEFAULT 'dummy_text',
+ PRIMARY KEY (i)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+insert into t1(i) values(null);
+
+select * from t1;
+
+insert into t1(i) values(null), (null), (null);
+
+select * from t1;
+
+--connection node_2
+
+select * from t1;
+
+SET GLOBAL wsrep_forced_binlog_format='none';
+
+--connection node_1
+
+SET GLOBAL wsrep_forced_binlog_format='none';
+
+drop table t1;
+
+##
+## Check the operation when the automatic control over the auto-increment
+## settings is switched off, that is, when we use the increment step and
+## the offset specified by the user. In the current session, the binlog
+## format is set to 'ROW'. It is important that the values of the
+## auto-increment options does not changed on other node - it allows us
+## to check the correct transmission of the auto-increment options to
+## other nodes:
+##
+
+SET SESSION binlog_format='ROW';
+
+show variables like 'binlog_format';
+
+SET GLOBAL wsrep_auto_increment_control='OFF';
+
+SET SESSION auto_increment_increment = 3;
+SET SESSION auto_increment_offset = 1;
+
+CREATE TABLE t1 (
+ i int(11) NOT NULL AUTO_INCREMENT,
+ c char(32) DEFAULT 'dummy_text',
+ PRIMARY KEY (i)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+insert into t1(i) values(null);
+
+select * from t1;
+
+insert into t1(i) values(null), (null), (null);
+
+select * from t1;
+
+--connection node_2
+
+select * from t1;
+
+--connection node_1
+
+##
+## Verify the return to automatic calculation of the step
+## and offset of the auto-increment:
+##
+
+SET GLOBAL wsrep_auto_increment_control='ON';
+
+show variables like 'binlog_format';
+show variables like '%auto_increment%';
+
+##
+## Verify the recovery of original user-defined values after
+## stopping the automatic control over auto-increment:
+##
+
+SET GLOBAL wsrep_auto_increment_control='OFF';
+
+show variables like '%auto_increment%';
+
+##
+## Restore original options and drop test table:
+##
+
+SET GLOBAL wsrep_auto_increment_control='ON';
+
+drop table t1;
+
+--source include/auto_increment_offset_restore.inc
diff --git a/mysql-test/suite/galera/t/galera_var_desync_on.test b/mysql-test/suite/galera/t/galera_var_desync_on.test
index 06c5d30a769..fbf660d3ab5 100644
--- a/mysql-test/suite/galera/t/galera_var_desync_on.test
+++ b/mysql-test/suite/galera/t/galera_var_desync_on.test
@@ -1,5 +1,7 @@
#
-# Test wsrep_desync = ON . Node should temporarily not participate in flow control
+# Desync will be done once the global read lock is acquired and resync will be done when
+# it is released.
+# Node should temporarily not participate in flow control
# so even if fc_limit has been reached, the master should be able to continue to
# commit transactions.
#
@@ -13,7 +15,6 @@ INSERT INTO t1 VALUES (1);
--connection node_2
--let $wsrep_provider_options_orig = `SELECT @@wsrep_provider_options`
SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=1';
-SET GLOBAL wsrep_desync = TRUE;
# Block the slave applier thread
FLUSH TABLES WITH READ LOCK;
@@ -37,8 +38,6 @@ SET SESSION wsrep_sync_wait = 0;
# No updates have arrived after the FLUSH TABLES
SELECT COUNT(*) = 1 FROM t1;
-# Resync the slave
-SET GLOBAL wsrep_desync = FALSE;
--disable_query_log
--eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_orig';
--enable_query_log
diff --git a/mysql-test/suite/rpl/r/rpl_row_spatial.result b/mysql-test/suite/rpl/r/rpl_row_spatial.result
new file mode 100644
index 00000000000..86bac89a174
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_spatial.result
@@ -0,0 +1,16 @@
+include/master-slave.inc
+[connection master]
+CREATE TABLE t1 (g POINT NOT NULL, SPATIAL INDEX(g));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(1 1)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(2 1)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(1 2)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(2 2)'));
+DELETE FROM t1 where MBREqual(g, ST_GEOMFROMTEXT('Point(1 2)'));
+connection slave;
+select count(*) from t1;
+count(*)
+3
+connection master;
+DELETE FROM t1;
+drop table t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_row_spatial.test b/mysql-test/suite/rpl/t/rpl_row_spatial.test
new file mode 100644
index 00000000000..00c3dd7c54d
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_spatial.test
@@ -0,0 +1,17 @@
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+CREATE TABLE t1 (g POINT NOT NULL, SPATIAL INDEX(g));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(1 1)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(2 1)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(1 2)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(2 2)'));
+DELETE FROM t1 where MBREqual(g, ST_GEOMFROMTEXT('Point(1 2)'));
+
+--sync_slave_with_master
+select count(*) from t1;
+
+--connection master
+DELETE FROM t1;
+drop table t1;
+--source include/rpl_end.inc
diff --git a/mysql-test/t/func_isnull.test b/mysql-test/t/func_isnull.test
index 4c59fa3cbe8..7d1a7e83a1a 100644
--- a/mysql-test/t/func_isnull.test
+++ b/mysql-test/t/func_isnull.test
@@ -83,6 +83,22 @@ SELECT * FROM t2 LEFT JOIN v1 ON t2.d1=v1.d1 WHERE v1.d1 IS NULL;
DROP VIEW v1;
DROP TABLE t1,t2;
+
+--echo #
+--echo # MDEV-15475: Assertion `!table || (!table->read_set ||
+--echo # bitmap_is_set(table->read_set, field_index))'
+--echo # failed on EXPLAIN EXTENDED with constant table and view
+--echo #
+
+CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=MyISAM;
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1);
+EXPLAIN EXTENDED SELECT ISNULL(pk) FROM v1;
+EXPLAIN EXTENDED SELECT IFNULL(pk,0) FROM v1;
+# Cleanup
+DROP VIEW v1;
+DROP TABLE t1;
+
--echo #
--echo # End of 5.5 tests
--echo #
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 3503b6d5bc6..f12eda8cb9b 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -1702,6 +1702,10 @@ DO TO_DAYS(SEC_TO_TIME(TIME(CEILING(UUID()))));
DO TO_DAYS(SEC_TO_TIME(MAKEDATE('',RAND(~('')))));
SELECT SEC_TO_TIME(MAKEDATE(0,RAND(~0)));
+#
+# MDEV-16810 AddressSanitizer: stack-buffer-overflow in int10_to_str
+#
+SELECT PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli'));
--echo #
--echo # End of 5.5 tests
diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
index b0bc42d7f8c..adad9073235 100644
--- a/mysql-test/t/group_min_max.test
+++ b/mysql-test/t/group_min_max.test
@@ -1609,5 +1609,32 @@ explain select min(a) from t1 where a between "abbbbbbbbbbbbbbbbbbbb" and "Cafe2
drop table t1;
--echo #
+--echo # MDEV-15433: Optimizer does not use group by optimization with distinct
+--echo #
+
+CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, a INT NOT NULL, KEY(a));
+--disable_query_log
+INSERT INTO t1(a) VALUES (1), (2), (3), (4);
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+--enable_query_log
+OPTIMIZE TABLE t1;
+EXPLAIN SELECT DISTINCT a FROM t1;
+SELECT DISTINCT a FROM t1;
+drop table t1;
+
+--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index fc2ae849aa6..e3219c21517 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -638,10 +638,7 @@ EOF
--echo # End of 10.1 tests
--echo #
---error 1
---exec $MYSQL --default-character-set=utf8 -e "select 1" "test😁 " 2>&1
---error 1
---exec $MYSQL --default-character-set=binary -e "select 1" "test😁 " 2>&1
+
--write_file $MYSQLTEST_VARDIR/tmp/mdev-6572.sql
SET NAMES utf8;
USE test😁 ;
diff --git a/mysql-test/t/mysql_not_windows.test b/mysql-test/t/mysql_not_windows.test
index 591de74cbbf..816160c4f3e 100644
--- a/mysql-test/t/mysql_not_windows.test
+++ b/mysql-test/t/mysql_not_windows.test
@@ -22,3 +22,10 @@ exec $MYSQL test -e "select
let $query = select 3
as X;
exec $MYSQL test -e "$query";
+
+# Not ran on Windows, since non-ASCII does not work on command line.
+# (MDEV-16220)
+--error 1
+--exec $MYSQL --default-character-set=utf8 -e "select 1" "test😁 " 2>&1
+--error 1
+--exec $MYSQL --default-character-set=binary -e "select 1" "test😁 " 2>&1
diff --git a/mysql-test/t/subselect_extra_no_semijoin.test b/mysql-test/t/subselect_extra_no_semijoin.test
index 8aba3dde72b..d8809c7f981 100644
--- a/mysql-test/t/subselect_extra_no_semijoin.test
+++ b/mysql-test/t/subselect_extra_no_semijoin.test
@@ -6,4 +6,33 @@ set @optimizer_switch_for_subselect_extra_test='semijoin=off,firstmatch=off,loo
set optimizer_switch= @subselect_extra_no_sj_tmp;
-set @optimizer_switch_for_subselect_extra_test=null; \ No newline at end of file
+set @optimizer_switch_for_subselect_extra_test=null;
+
+--echo #
+--echo # MDEV-6439: Server crashes in Explain_union::print_explain with explain in slow log, tis620 charset
+--echo #
+
+## Using a separate client connection is easier than restoring state
+connect(con1,localhost,root,,);
+
+SET NAMES tis620;
+set @tmp= @@global.slow_query_log;
+SET GLOBAL slow_query_log = 1;
+SET long_query_time = 0.000001;
+SET log_slow_verbosity = 'explain';
+
+CREATE TABLE t1 (a VARCHAR(3)) ENGINE=MyISAM;
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo');
+--error ER_CANT_AGGREGATE_2COLLATIONS
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' );
+
+create table t2 (b int);
+insert into t2 values (1),(2),(3);
+
+--error ER_CANT_AGGREGATE_2COLLATIONS
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' FROM t2);
+
+drop table t1,t2;
+SET GLOBAL slow_query_log=@tmp;
+disconnect con1;
+connection default;
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index 88b1352db2e..2824593a0a9 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -41,6 +41,8 @@ cleanup_joiner()
kill -9 $RSYNC_REAL_PID >/dev/null 2>&1 || \
:
rm -rf "$RSYNC_CONF"
+ rm -f "$STUNNEL_CONF"
+ rm -f "$STUNNEL_PID"
rm -rf "$MAGIC_FILE"
rm -rf "$RSYNC_PID"
wsrep_log_info "Joiner cleanup done."
@@ -68,7 +70,7 @@ check_pid_and_port()
local port_info="$(sockstat -46lp ${rsync_port} 2>/dev/null | \
grep ":${rsync_port}")"
local is_rsync="$(echo $port_info | \
- grep '[[:space:]]\+rsync[[:space:]]\+'"$rsync_pid" 2>/dev/null)"
+ grep -wE '[[:space:]]\+(rsync|stunnel)[[:space:]]\+'"$rsync_pid" 2>/dev/null)"
;;
*)
if ! which lsof > /dev/null; then
@@ -79,7 +81,7 @@ check_pid_and_port()
local port_info="$(lsof -i :$rsync_port -Pn 2>/dev/null | \
grep "(LISTEN)")"
local is_rsync="$(echo $port_info | \
- grep -w '^rsync[[:space:]]\+'"$rsync_pid" 2>/dev/null)"
+ grep -wE '^(rsync|stunnel)[[:space:]]\+'"$rsync_pid" 2>/dev/null)"
;;
esac
@@ -119,6 +121,12 @@ is_local_ip()
$get_addr_bin | grep "$address" > /dev/null
}
+STUNNEL_CONF="$WSREP_SST_OPT_DATA/stunnel.conf"
+rm -f "$STUNNEL_CONF"
+
+STUNNEL_PID="$WSREP_SST_OPT_DATA/stunnel.pid"
+rm -f "$STUNNEL_PID"
+
MAGIC_FILE="$WSREP_SST_OPT_DATA/rsync_sst_complete"
rm -rf "$MAGIC_FILE"
@@ -156,9 +164,28 @@ fi
FILTER="-f '- /lost+found' -f '- /.fseventsd' -f '- /.Trashes'
-f '+ /wsrep_sst_binlog.tar' -f '+ /ib_lru_dump' -f '+ /ibdata*' -f '+ /*/' -f '- /*'"
+SSTKEY=$(parse_cnf sst tkey "")
+SSTCERT=$(parse_cnf sst tcert "")
+STUNNEL=""
+if [ -f "$SSTKEY" ] && [ -f "$SSTCERT" ] && wsrep_check_programs stunnel
+then
+ STUNNEL="stunnel ${STUNNEL_CONF}"
+fi
+
if [ "$WSREP_SST_OPT_ROLE" = "donor" ]
then
+cat << EOF > "$STUNNEL_CONF"
+CApath = ${SSTCERT%/*}
+foreground = yes
+pid = $STUNNEL_PID
+debug = warning
+client = yes
+connect = ${WSREP_SST_OPT_ADDR%/*}
+TIMEOUTclose = 0
+verifyPeer = yes
+EOF
+
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
then
@@ -220,7 +247,8 @@ then
# first, the normal directories, so that we can detect incompatible protocol
RC=0
- eval rsync --owner --group --perms --links --specials \
+ eval rsync ${STUNNEL:+--rsh="$STUNNEL"} \
+ --owner --group --perms --links --specials \
--ignore-times --inplace --dirs --delete --quiet \
$WHOLE_FILE_OPT ${FILTER} "$WSREP_SST_OPT_DATA/" \
rsync://$WSREP_SST_OPT_ADDR >&2 || RC=$?
@@ -243,7 +271,8 @@ then
fi
# second, we transfer InnoDB log files
- rsync --owner --group --perms --links --specials \
+ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
+ --owner --group --perms --links --specials \
--ignore-times --inplace --dirs --delete --quiet \
$WHOLE_FILE_OPT -f '+ /ib_logfile[0-9]*' -f '- **' "$WSREP_LOG_DIR/" \
rsync://$WSREP_SST_OPT_ADDR-log_dir >&2 || RC=$?
@@ -263,7 +292,8 @@ then
find . -maxdepth 1 -mindepth 1 -type d -not -name "lost+found" \
-print0 | xargs -I{} -0 -P $count \
- rsync --owner --group --perms --links --specials \
+ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
+ --owner --group --perms --links --specials \
--ignore-times --inplace --recursive --delete --quiet \
$WHOLE_FILE_OPT --exclude '*/ib_logfile*' "$WSREP_SST_OPT_DATA"/{}/ \
rsync://$WSREP_SST_OPT_ADDR/{} >&2 || RC=$?
@@ -286,7 +316,8 @@ then
echo "continue" # now server can resume updating data
echo "$STATE" > "$MAGIC_FILE"
- rsync --archive --quiet --checksum "$MAGIC_FILE" rsync://$WSREP_SST_OPT_ADDR
+ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
+ --archive --quiet --checksum "$MAGIC_FILE" rsync://$WSREP_SST_OPT_ADDR
echo "done $STATE"
@@ -341,20 +372,41 @@ $SILENT
path = $WSREP_LOG_DIR
EOF
+cat << EOF > "$STUNNEL_CONF"
+key = $SSTKEY
+cert = $SSTCERT
+foreground = yes
+pid = $STUNNEL_PID
+debug = warning
+client = no
+[rsync]
+accept = $RSYNC_PORT
+exec = $(which rsync)
+execargs = rsync --server --daemon --config=$RSYNC_CONF .
+EOF
+
# rm -rf "$DATA"/ib_logfile* # we don't want old logs around
readonly RSYNC_PORT=${WSREP_SST_OPT_PORT:-4444}
- # If the IP is local listen only in it
- if is_local_ip "$RSYNC_ADDR"
+
+ if [ -z "$STUNNEL" ]
then
- rsync --daemon --no-detach --address "$RSYNC_ADDR" --port "$RSYNC_PORT" --config "$RSYNC_CONF" &
+ # If the IP is local listen only in it
+ if is_local_ip "$RSYNC_ADDR"
+ then
+ rsync --daemon --no-detach --address "$RSYNC_ADDR" --port "$RSYNC_PORT" --config "$RSYNC_CONF" &
+ else
+ # Not local, possibly a NAT, listen in all interfaces
+ rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" &
+ # Overwrite address with all
+ RSYNC_ADDR=""
+ fi
+ RSYNC_REAL_PID=$!
else
- # Not local, possibly a NAT, listen in all interface
- rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" &
- # Overwrite address with all
- RSYNC_ADDR="*"
+ stunnel "$STUNNEL_CONF" &
+ RSYNC_REAL_PID=$!
+ RSYNC_PID=$STUNNEL_PID
fi
- RSYNC_REAL_PID=$!
until check_pid_and_port "$RSYNC_PID" "$RSYNC_REAL_PID" "$RSYNC_ADDR" "$RSYNC_PORT"
do
diff --git a/sql/field.h b/sql/field.h
index 22c276478b6..ae6adec07e8 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1448,6 +1448,17 @@ public:
/* Hash value */
virtual void hash(ulong *nr, ulong *nr2);
+ /**
+ Get the upper limit of the MySQL integral and floating-point type.
+
+ @return maximum allowed value for the field
+ */
+ virtual ulonglong get_max_int_value() const
+ {
+ DBUG_ASSERT(false);
+ return 0ULL;
+ }
+
/**
Checks whether a string field is part of write_set.
@@ -2006,6 +2017,11 @@ public:
*to= *from;
return from + 1;
}
+
+ virtual ulonglong get_max_int_value() const
+ {
+ return unsigned_flag ? 0xFFULL : 0x7FULL;
+ }
};
@@ -2047,6 +2063,10 @@ public:
virtual const uchar *unpack(uchar* to, const uchar *from,
const uchar *from_end, uint param_data)
{ return unpack_int16(to, from, from_end); }
+ virtual ulonglong get_max_int_value() const
+ {
+ return unsigned_flag ? 0xFFFFULL : 0x7FFFULL;
+ }
};
class Field_medium :public Field_integer {
@@ -2080,6 +2100,10 @@ public:
{
return Field::pack(to, from, max_length);
}
+ virtual ulonglong get_max_int_value() const
+ {
+ return unsigned_flag ? 0xFFFFFFULL : 0x7FFFFFULL;
+ }
};
@@ -2125,6 +2149,10 @@ public:
{
return unpack_int32(to, from, from_end);
}
+ virtual ulonglong get_max_int_value() const
+ {
+ return unsigned_flag ? 0xFFFFFFFFULL : 0x7FFFFFFFULL;
+ }
};
@@ -2174,6 +2202,10 @@ public:
{
return unpack_int64(to, from, from_end);
}
+ virtual ulonglong get_max_int_value() const
+ {
+ return unsigned_flag ? 0xFFFFFFFFFFFFFFFFULL : 0x7FFFFFFFFFFFFFFFULL;
+ }
};
@@ -2213,6 +2245,13 @@ public:
uint32 pack_length() const { return sizeof(float); }
uint row_pack_length() const { return pack_length(); }
void sql_type(String &str) const;
+ virtual ulonglong get_max_int_value() const
+ {
+ /*
+ We use the maximum as per IEEE754-2008 standard, 2^24
+ */
+ return 0x1000000ULL;
+ }
private:
int do_save_field_metadata(uchar *first_byte);
};
@@ -2265,6 +2304,13 @@ public:
uint32 pack_length() const { return sizeof(double); }
uint row_pack_length() const { return pack_length(); }
void sql_type(String &str) const;
+ virtual ulonglong get_max_int_value() const
+ {
+ /*
+ We use the maximum as per IEEE754-2008 standard, 2^53
+ */
+ return 0x20000000000000ULL;
+ }
private:
int do_save_field_metadata(uchar *first_byte);
};
diff --git a/sql/handler.cc b/sql/handler.cc
index 36babb96415..2fadef3044f 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -2853,9 +2853,15 @@ compute_next_insert_id(ulonglong nr,struct system_variables *variables)
nr= nr + 1; // optimization of the formula below
else
{
+ /*
+ Calculating the number of complete auto_increment_increment extents:
+ */
nr= (((nr+ variables->auto_increment_increment -
variables->auto_increment_offset)) /
(ulonglong) variables->auto_increment_increment);
+ /*
+ Adding an offset to the auto_increment_increment extent boundary:
+ */
nr= (nr* (ulonglong) variables->auto_increment_increment +
variables->auto_increment_offset);
}
@@ -2911,8 +2917,14 @@ prev_insert_id(ulonglong nr, struct system_variables *variables)
}
if (variables->auto_increment_increment == 1)
return nr; // optimization of the formula below
+ /*
+ Calculating the number of complete auto_increment_increment extents:
+ */
nr= (((nr - variables->auto_increment_offset)) /
(ulonglong) variables->auto_increment_increment);
+ /*
+ Adding an offset to the auto_increment_increment extent boundary:
+ */
return (nr * (ulonglong) variables->auto_increment_increment +
variables->auto_increment_offset);
}
@@ -3135,10 +3147,23 @@ int handler::update_auto_increment()
if (unlikely(tmp)) // Out of range value in store
{
/*
- It's better to return an error here than getting a confusing
- 'duplicate key error' later.
+ first test if the query was aborted due to strict mode constraints
+ */
+ if (thd->killed == KILL_BAD_DATA ||
+ nr > table->next_number_field->get_max_int_value())
+ DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
+
+ /*
+ field refused this value (overflow) and truncated it, use the result of
+ the truncation (which is going to be inserted); however we try to
+ decrease it to honour auto_increment_* variables.
+ That will shift the left bound of the reserved interval, we don't
+ bother shifting the right bound (anyway any other value from this
+ interval will cause a duplicate key).
*/
- result= HA_ERR_AUTOINC_ERANGE;
+ nr= prev_insert_id(table->next_number_field->val_int(), variables);
+ if (unlikely(table->next_number_field->store((longlong) nr, TRUE)))
+ nr= table->next_number_field->val_int();
}
if (append)
{
diff --git a/sql/item.cc b/sql/item.cc
index 58d2b7dbfc0..7d8baf81d3b 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -7402,7 +7402,7 @@ Item_direct_view_ref::derived_grouping_field_transformer_for_where(THD *thd,
void Item_field::print(String *str, enum_query_type query_type)
{
if (field && field->table->const_table &&
- !(query_type & QT_NO_DATA_EXPANSION))
+ !(query_type & (QT_NO_DATA_EXPANSION | QT_VIEW_INTERNAL)))
{
print_value(str);
return;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 6834820c0b5..577a98df0d2 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -5119,7 +5119,11 @@ longlong Item_func_isnull::val_int()
void Item_func_isnull::print(String *str, enum_query_type query_type)
{
- args[0]->print_parenthesised(str, query_type, precedence());
+ if (const_item() && !args[0]->maybe_null &&
+ !(query_type & (QT_NO_DATA_EXPANSION | QT_VIEW_INTERNAL)))
+ str->append("/*always not null*/ 1");
+ else
+ args[0]->print_parenthesised(str, query_type, precedence());
str->append(STRING_WITH_LEN(" is null"));
}
diff --git a/sql/key.cc b/sql/key.cc
index 08bd6e8f65d..116f2954d9e 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -146,7 +146,8 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
{
key_length-= HA_KEY_BLOB_LENGTH;
length= MY_MIN(key_length, key_part->length);
- uint bytes= key_part->field->get_key_image(to_key, length, Field::itRAW);
+ uint bytes= key_part->field->get_key_image(to_key, length,
+ key_info->flags & HA_SPATIAL ? Field::itMBR : Field::itRAW);
if (with_zerofill && bytes < length)
bzero((char*) to_key + bytes, length - bytes);
to_key+= HA_KEY_BLOB_LENGTH;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 2ad4e6f2a61..1c45d07beed 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1469,9 +1469,9 @@ static NTService Service; ///< Service object for WinNT
#endif /* __WIN__ */
#ifdef _WIN32
+#include <sddl.h> /* ConvertStringSecurityDescriptorToSecurityDescriptor */
static char pipe_name[512];
static SECURITY_ATTRIBUTES saPipeSecurity;
-static SECURITY_DESCRIPTOR sdPipeDescriptor;
static HANDLE hPipe = INVALID_HANDLE_VALUE;
#endif
@@ -2719,21 +2719,20 @@ static void network_init(void)
strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
mysqld_unix_port, NullS);
- bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));
- bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor));
- if (!InitializeSecurityDescriptor(&sdPipeDescriptor,
- SECURITY_DESCRIPTOR_REVISION))
+ /*
+ Create a security descriptor for pipe.
+ - Use low integrity level, so that it is possible to connect
+ from any process.
+ - Give Everyone read/write access to pipe.
+ */
+ if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
+ "S:(ML;; NW;;; LW) D:(A;; FRFW;;; WD)",
+ SDDL_REVISION_1, &saPipeSecurity.lpSecurityDescriptor, NULL))
{
sql_perror("Can't start server : Initialize security descriptor");
unireg_abort(1);
}
- if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE))
- {
- sql_perror("Can't start server : Set security descriptor");
- unireg_abort(1);
- }
saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
- saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
saPipeSecurity.bInheritHandle = FALSE;
if ((hPipe= CreateNamedPipe(pipe_name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
@@ -4320,6 +4319,20 @@ static int init_common_variables()
DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname,
server_version, SYSTEM_TYPE,MACHINE_TYPE));
+#ifdef WITH_WSREP
+ /*
+ We need to initialize auxiliary variables, that will be
+ further keep the original values of auto-increment options
+ as they set by the user. These variables used to restore
+ user-defined values of the auto-increment options after
+ setting of the wsrep_auto_increment_control to 'OFF'.
+ */
+ global_system_variables.saved_auto_increment_increment=
+ global_system_variables.auto_increment_increment;
+ global_system_variables.saved_auto_increment_offset=
+ global_system_variables.auto_increment_offset;
+#endif /* WITH_WSREP */
+
#ifdef HAVE_LINUX_LARGE_PAGES
/* Initialize large page size */
if (opt_large_pages)
@@ -6901,6 +6914,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
connect->host= my_localhost;
create_new_thread(connect);
}
+ LocalFree(saPipeSecurity.lpSecurityDescriptor);
CloseHandle(connectOverlapped.hEvent);
DBUG_LEAVE;
decrement_handler_count();
diff --git a/sql/protocol.cc b/sql/protocol.cc
index b9d9f28831e..256cecac6bb 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -710,7 +710,7 @@ uchar *net_store_data(uchar *to, const uchar *from, size_t length)
uchar *net_store_data(uchar *to,int32 from)
{
- char buff[20];
+ char buff[22];
uint length=(uint) (int10_to_str(from,buff,10)-buff);
to=net_store_length_fast(to,length);
memcpy(to,buff,length);
@@ -1136,7 +1136,7 @@ bool Protocol_text::store_tiny(longlong from)
DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
field_pos++;
#endif
- char buff[20];
+ char buff[22];
return net_store_data((uchar*) buff,
(size_t) (int10_to_str((int) from, buff, -10) - buff));
}
@@ -1150,7 +1150,7 @@ bool Protocol_text::store_short(longlong from)
field_types[field_pos] == MYSQL_TYPE_SHORT);
field_pos++;
#endif
- char buff[20];
+ char buff[22];
return net_store_data((uchar*) buff,
(size_t) (int10_to_str((int) from, buff, -10) -
buff));
@@ -1165,7 +1165,7 @@ bool Protocol_text::store_long(longlong from)
field_types[field_pos] == MYSQL_TYPE_LONG);
field_pos++;
#endif
- char buff[20];
+ char buff[22];
return net_store_data((uchar*) buff,
(size_t) (int10_to_str((long int)from, buff,
(from <0)?-10:10)-buff));
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 4888b38bc30..9a10083a998 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -569,6 +569,17 @@ typedef struct system_variables
ha_rows max_join_size;
ha_rows expensive_subquery_limit;
ulong auto_increment_increment, auto_increment_offset;
+#ifdef WITH_WSREP
+ /*
+ Variables with stored values of the auto_increment_increment
+ and auto_increment_offset options that are will be needed when
+ wsrep_auto_increment_control will be set to 'OFF', because the
+ setting it to 'ON' leads to overwriting of the original values
+ (which are set by the user) by calculated values (which are
+ based on the cluster's size):
+ */
+ ulong saved_auto_increment_increment, saved_auto_increment_offset;
+#endif /* WITH_WSREP */
uint eq_range_index_dive_limit;
ulong lock_wait_timeout;
ulong join_cache_level;
diff --git a/sql/sql_list.h b/sql/sql_list.h
index c27ed44cb9c..47590920510 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -311,10 +311,13 @@ public:
*/
inline void swap(base_list &rhs)
{
+ list_node **rhs_last=rhs.last;
swap_variables(list_node *, first, rhs.first);
- swap_variables(list_node **, last, rhs.last);
swap_variables(uint, elements, rhs.elements);
+ rhs.last= last == &first ? &rhs.first : last;
+ last = rhs_last == &rhs.first ? &first : rhs_last;
}
+
inline list_node* last_node() { return *last; }
inline list_node* first_node() { return first;}
inline void *head() { return first->info; }
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index b94ca496b95..0124a782de0 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1564,6 +1564,14 @@ JOIN::optimize_inner()
error= 1;
DBUG_RETURN(1);
}
+ if (!group_list)
+ {
+ /* The output has only one row */
+ order=0;
+ simple_order=1;
+ group_optimized_away= 1;
+ select_distinct=0;
+ }
}
/* Calculate how to do the join */
@@ -6099,7 +6107,7 @@ add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
Item_field *cur_item;
key_map possible_keys(0);
- if (join->group_list || join->simple_group)
+ if (join->group_list)
{ /* Collect all query fields referenced in the GROUP clause. */
for (cur_group= join->group_list; cur_group; cur_group= cur_group->next)
(*cur_group->item)->walk(&Item::collect_item_field_processor, 0,
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index b9c90f7fb4b..6af64b3bb11 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2474,7 +2474,7 @@ static int show_create_view(THD *thd, TABLE_LIST *table, String *buff)
We can't just use table->query, because our SQL_MODE may trigger
a different syntax, like when ANSI_QUOTES is defined.
*/
- table->view->unit.print(buff, enum_query_type(QT_ORDINARY |
+ table->view->unit.print(buff, enum_query_type(QT_VIEW_INTERNAL |
QT_ITEM_ORIGINAL_FUNC_NULLIF));
if (table->with_check != VIEW_CHECK_NONE)
diff --git a/sql/sql_time.cc b/sql/sql_time.cc
index e3116f73edc..cdb9f4e5b79 100644
--- a/sql/sql_time.cc
+++ b/sql/sql_time.cc
@@ -190,7 +190,7 @@ bool get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month,
ulong convert_period_to_month(ulong period)
{
ulong a,b;
- if (period == 0)
+ if (period == 0 || period > 999912)
return 0L;
if ((a=period/100) < YY_PART_YEAR)
a+=2000;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 391772d1191..5541efbcead 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -347,13 +347,56 @@ static Sys_var_long Sys_pfs_connect_attrs_size(
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
+#ifdef WITH_WSREP
+
+/*
+ We need to keep the original values set by the user, as they will
+ be lost if wsrep_auto_increment_control set to 'ON':
+*/
+static bool update_auto_increment_increment (sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.saved_auto_increment_increment=
+ global_system_variables.auto_increment_increment;
+ else
+ thd->variables.saved_auto_increment_increment=
+ thd->variables.auto_increment_increment;
+ return false;
+}
+
+#endif /* WITH_WSREP */
+
static Sys_var_ulong Sys_auto_increment_increment(
"auto_increment_increment",
"Auto-increment columns are incremented by this",
SESSION_VAR(auto_increment_increment),
CMD_LINE(OPT_ARG),
VALID_RANGE(1, 65535), DEFAULT(1), BLOCK_SIZE(1),
+#ifdef WITH_WSREP
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_auto_increment_increment));
+#else
NO_MUTEX_GUARD, IN_BINLOG);
+#endif /* WITH_WSREP */
+
+#ifdef WITH_WSREP
+
+/*
+ We need to keep the original values set by the user, as they will
+ be lost if wsrep_auto_increment_control set to 'ON':
+*/
+static bool update_auto_increment_offset (sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.saved_auto_increment_offset=
+ global_system_variables.auto_increment_offset;
+ else
+ thd->variables.saved_auto_increment_offset=
+ thd->variables.auto_increment_offset;
+ return false;
+}
+
+#endif /* WITH_WSREP */
static Sys_var_ulong Sys_auto_increment_offset(
"auto_increment_offset",
@@ -362,7 +405,12 @@ static Sys_var_ulong Sys_auto_increment_offset(
SESSION_VAR(auto_increment_offset),
CMD_LINE(OPT_ARG),
VALID_RANGE(1, 65535), DEFAULT(1), BLOCK_SIZE(1),
+#ifdef WITH_WSREP
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_auto_increment_offset));
+#else
NO_MUTEX_GUARD, IN_BINLOG);
+#endif /* WITH_WSREP */
static Sys_var_mybool Sys_automatic_sp_privileges(
"automatic_sp_privileges",
@@ -4976,11 +5024,54 @@ static Sys_var_ulong Sys_wsrep_retry_autocommit(
SESSION_VAR(wsrep_retry_autocommit), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, 10000), DEFAULT(1), BLOCK_SIZE(1));
+static bool update_wsrep_auto_increment_control (sys_var *self, THD *thd, enum_var_type type)
+{
+ if (wsrep_auto_increment_control)
+ {
+ /*
+ The variables that control auto increment shall be calculated
+ automaticaly based on the size of the cluster. This usually done
+ within the wsrep_view_handler_cb callback. However, if the user
+ manually sets the value of wsrep_auto_increment_control to 'ON',
+ then we should to re-calculate these variables again (because
+ these values may be required before wsrep_view_handler_cb will
+ be re-invoked, which is rarely invoked if the cluster stays in
+ the stable state):
+ */
+ global_system_variables.auto_increment_increment=
+ wsrep_cluster_size ? wsrep_cluster_size : 1;
+ global_system_variables.auto_increment_offset=
+ wsrep_local_index >= 0 ? wsrep_local_index + 1 : 1;
+ thd->variables.auto_increment_increment=
+ global_system_variables.auto_increment_increment;
+ thd->variables.auto_increment_offset=
+ global_system_variables.auto_increment_offset;
+ }
+ else
+ {
+ /*
+ We must restore the last values of the variables that
+ are explicitly specified by the user:
+ */
+ global_system_variables.auto_increment_increment=
+ global_system_variables.saved_auto_increment_increment;
+ global_system_variables.auto_increment_offset=
+ global_system_variables.saved_auto_increment_offset;
+ thd->variables.auto_increment_increment=
+ thd->variables.saved_auto_increment_increment;
+ thd->variables.auto_increment_offset=
+ thd->variables.saved_auto_increment_offset;
+ }
+ return false;
+}
+
static Sys_var_mybool Sys_wsrep_auto_increment_control(
"wsrep_auto_increment_control", "To automatically control the "
"assignment of autoincrement variables",
GLOBAL_VAR(wsrep_auto_increment_control),
- CMD_LINE(OPT_ARG), DEFAULT(TRUE));
+ CMD_LINE(OPT_ARG), DEFAULT(TRUE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_wsrep_auto_increment_control));
static Sys_var_mybool Sys_wsrep_drupal_282555_workaround(
"wsrep_drupal_282555_workaround", "Enable a workaround to handle the "
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 8d92621001b..b8143e92ccb 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -160,6 +160,10 @@ extern "C" query_id_t wsrep_thd_query_id(THD *thd);
extern "C" query_id_t wsrep_thd_wsrep_last_query_id(THD *thd);
extern "C" void wsrep_thd_set_wsrep_last_query_id(THD *thd, query_id_t id);
+extern "C" void wsrep_thd_auto_increment_variables(THD*,
+ unsigned long long *offset,
+ unsigned long long *increment);
+
extern void wsrep_close_client_connections(my_bool wait_to_end);
extern int wsrep_wait_committing_connections_close(int wait_time);
extern void wsrep_close_applier(THD *thd);
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index 15eed2e10e6..1621559bb8a 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -677,3 +677,25 @@ bool wsrep_thd_has_explicit_locks(THD *thd)
assert(thd);
return thd->mdl_context.has_explicit_locks();
}
+
+/*
+ Get auto increment variables for THD. Use global settings for
+ applier threads.
+ */
+extern "C"
+void wsrep_thd_auto_increment_variables(THD* thd,
+ unsigned long long* offset,
+ unsigned long long* increment)
+{
+ if (thd->wsrep_exec_mode == REPL_RECV &&
+ thd->wsrep_conflict_state != REPLAYING)
+ {
+ *offset= global_system_variables.auto_increment_offset;
+ *increment= global_system_variables.auto_increment_increment;
+ }
+ else
+ {
+ *offset= thd->variables.auto_increment_offset;
+ *increment= thd->variables.auto_increment_increment;
+ }
+}
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc
index bd33847762d..9c7698aec39 100644
--- a/sql/wsrep_var.cc
+++ b/sql/wsrep_var.cc
@@ -617,6 +617,12 @@ bool wsrep_desync_check (sys_var *self, THD* thd, set_var* var)
return true;
}
+ if (thd->global_read_lock.is_acquired())
+ {
+ my_message (ER_CANNOT_USER, "Global read lock acquired. Can't set 'wsrep_desync'", MYF(0));
+ return true;
+ }
+
bool new_wsrep_desync= (bool) var->save_result.ulonglong_value;
if (wsrep_desync == new_wsrep_desync) {
if (new_wsrep_desync) {
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index d733ecdad17..2a59c01d6db 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -391,7 +391,7 @@ buf_dump(
/* leave tmp_filename to exist */
return;
}
- if ( (j % 1024) == 0) {
+ if (SHUTTING_DOWN() && !(j % 1024)) {
service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
"Dumping buffer pool "
ULINTPF "/" ULINTPF ", "
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index d9463cee140..c3a6bd663b3 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -8233,7 +8233,7 @@ ha_innobase::write_row(
/* We need the upper limit of the col type to check for
whether we update the table autoinc counter or not. */
- col_max_value = innobase_get_int_col_max_value(table->next_number_field);
+ col_max_value = table->next_number_field->get_max_int_value();
/* Get the value that MySQL attempted to store in the table.*/
auto_inc = table->next_number_field->val_uint();
@@ -8308,14 +8308,30 @@ set_max_autoinc:
/* This should filter out the negative
values set explicitly by the user. */
if (auto_inc <= col_max_value) {
- ut_a(m_prebuilt->autoinc_increment > 0);
-
ulonglong offset;
ulonglong increment;
dberr_t err;
- offset = m_prebuilt->autoinc_offset;
- increment = m_prebuilt->autoinc_increment;
+#ifdef WITH_WSREP
+ /* Applier threads which are
+ processing ROW events and don't go
+ through server level autoinc
+ processing, therefore m_prebuilt
+ autoinc values don't get
+ properly assigned. Fetch values from
+ server side. */
+ if (wsrep_on(m_user_thd) &&
+ wsrep_thd_exec_mode(m_user_thd) == REPL_RECV) {
+ wsrep_thd_auto_increment_variables(m_user_thd, &offset, &increment);
+ } else {
+#endif /* WITH_WSREP */
+ ut_a(m_prebuilt->autoinc_increment > 0);
+
+ offset = m_prebuilt->autoinc_offset;
+ increment = m_prebuilt->autoinc_increment;
+#ifdef WITH_WSREP
+ }
+#endif /* WITH_WSREP */
auto_inc = innobase_next_autoinc(
auto_inc,
@@ -8995,12 +9011,27 @@ ha_innobase::update_row(
/* A value for an AUTO_INCREMENT column
was specified in the UPDATE statement. */
+ ulonglong offset, increment;
+#ifdef WITH_WSREP
+ /* Applier threads which are processing ROW events and
+ don't go through server level autoinc processing,
+ therefore m_prebuilt autoinc values don't get properly
+ assigned. Fetch values from server side. */
+ if (wsrep_on(m_user_thd)
+ && wsrep_thd_exec_mode(m_user_thd) == REPL_RECV) {
+ wsrep_thd_auto_increment_variables(
+ m_user_thd, &offset, &increment);
+ } else {
+#endif /* WITH_WSREP */
+ offset = m_prebuilt->autoinc_offset;
+ increment = m_prebuilt->autoinc_increment;
+#ifdef WITH_WSREP
+ }
+#endif /* WITH_WSREP */
+
autoinc = innobase_next_autoinc(
- autoinc, 1,
- m_prebuilt->autoinc_increment,
- m_prebuilt->autoinc_offset,
- innobase_get_int_col_max_value(
- table->found_next_number_field));
+ autoinc, 1, increment, offset,
+ table->found_next_number_field->get_max_int_value());
error = innobase_set_max_autoinc(autoinc);
@@ -16787,16 +16818,16 @@ ha_innobase::get_auto_increment(
"THD: %ld, current: %llu, autoinc: %llu",
m_prebuilt->autoinc_increment,
increment,
- thd_get_thread_id(ha_thd()),
+ thd_get_thread_id(m_user_thd),
current, autoinc);
- if (!wsrep_on(ha_thd())) {
- current = autoinc - m_prebuilt->autoinc_increment;
+ if (!wsrep_on(m_user_thd)) {
+ current = innobase_next_autoinc(
+ autoinc
+ - m_prebuilt->autoinc_increment,
+ 1, increment, offset, col_max_value);
}
- current = innobase_next_autoinc(
- current, 1, increment, offset, col_max_value);
-
dict_table_autoinc_initialize(
m_prebuilt->table, current);
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index b82f323d8f9..02fcbc74757 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -3661,7 +3661,7 @@ lock_table_create(
UT_LIST_ADD_LAST(trx->lock.trx_locks, lock);
#ifdef WITH_WSREP
- if (c_lock) {
+ if (c_lock && wsrep_on_trx(trx)) {
if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
ut_list_insert(table->locks, c_lock, lock,
TableLockGetNode());
@@ -3891,7 +3891,7 @@ lock_table_enqueue_waiting(
}
#ifdef WITH_WSREP
- if (trx->lock.was_chosen_as_deadlock_victim) {
+ if (trx->lock.was_chosen_as_deadlock_victim && wsrep_on_trx(trx)) {
return(DB_DEADLOCK);
}
#endif /* WITH_WSREP */
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 47c4f2584aa..abd18a6f559 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -1137,12 +1137,6 @@ log_write_up_to(
return;
}
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
- service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
- "log write up to: " LSN_PF,
- lsn);
- }
-
loop:
ut_ad(++loop_count < 128);
@@ -1273,6 +1267,13 @@ loop:
}
}
+ if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE)) {
+ service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "InnoDB log write: "
+ LSN_PF "," LSN_PF,
+ log_sys->write_lsn, lsn);
+ }
+
if (log_sys->is_encrypted()) {
log_crypt(write_buf + area_start, log_sys->write_lsn,
area_end - area_start);
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 424e8fecd6d..fbc7f6276f8 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -2512,9 +2512,17 @@ srv_purge_should_exit(ulint n_purged)
}
/* Slow shutdown was requested. */
if (n_purged) {
- service_manager_extend_timeout(
- INNODB_EXTEND_TIMEOUT_INTERVAL,
- "InnoDB " ULINTPF " pages purged", n_purged);
+#if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY
+ static ib_time_t progress_time;
+ ib_time_t time = ut_time();
+ if (time - progress_time >= 15) {
+ progress_time = time;
+ service_manager_extend_timeout(
+ INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "InnoDB: to purge " ULINTPF " transactions",
+ trx_sys->rseg_history_len);
+ }
+#endif
/* The previous round still did some work. */
return(false);
}
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 603b967484e..012ac9684dd 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -277,7 +277,12 @@ trx_purge_add_update_undo_to_history(
hist_size + undo->size, MLOG_4BYTES, mtr);
}
- /* Before any transaction-generating background threads or the
+ /* After the purge thread has been given permission to exit,
+ we may roll back transactions (trx->undo_no==0)
+ in THD::cleanup() invoked from unlink_thd() in fast shutdown,
+ or in trx_rollback_resurrected() in slow shutdown.
+
+ Before any transaction-generating background threads or the
purge have been started, recv_recovery_rollback_active() can
start transactions in row_merge_drop_temp_indexes() and
fts_drop_orphaned_tables(), and roll back recovered transactions.
@@ -287,18 +292,16 @@ trx_purge_add_update_undo_to_history(
innodb_force_recovery=2 or innodb_force_recovery=3.
DROP TABLE may be executed at any innodb_force_recovery level.
- After the purge thread has been given permission to exit,
- in fast shutdown, we may roll back transactions (trx->undo_no==0)
- in THD::cleanup() invoked from unlink_thd(), and we may also
- continue to execute user transactions. */
+ During fast shutdown, we may also continue to execute
+ user transactions. */
ut_ad(srv_undo_sources
+ || trx->undo_no == 0
|| ((srv_startup_is_before_trx_rollback_phase
|| trx_rollback_or_clean_is_active)
&& purge_sys->state == PURGE_STATE_INIT)
|| (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND
&& purge_sys->state == PURGE_STATE_DISABLED)
- || ((trx->undo_no == 0 || trx->in_mysql_trx_list
- || trx->internal)
+ || ((trx->in_mysql_trx_list || trx->internal)
&& srv_fast_shutdown));
/* Add the log as the first in the history list */
diff --git a/storage/xtradb/buf/buf0dump.cc b/storage/xtradb/buf/buf0dump.cc
index 90358d34b04..e9168d9f5d5 100644
--- a/storage/xtradb/buf/buf0dump.cc
+++ b/storage/xtradb/buf/buf0dump.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -334,7 +334,7 @@ buf_dump(
i + 1, srv_buf_pool_instances,
j + 1, n_pages);
}
- if ( (j % 1024) == 0) {
+ if (SHUTTING_DOWN() && !(j % 1024)) {
service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
"Dumping buffer pool "
ULINTPF "/" ULINTPF ", "
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 988b10522a4..c34f832d5f6 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -8951,8 +8951,25 @@ set_max_autoinc:
ulonglong increment;
dberr_t err;
- offset = prebuilt->autoinc_offset;
- increment = prebuilt->autoinc_increment;
+#ifdef WITH_WSREP
+ /* Applier threads which are
+ processing ROW events and don't go
+ through server level autoinc
+ processing, therefore m_prebuilt
+ autoinc values don't get
+ properly assigned. Fetch values from
+ server side. */
+ if (wsrep_on(current_thd) &&
+ wsrep_thd_exec_mode(current_thd) == REPL_RECV) {
+ wsrep_thd_auto_increment_variables(current_thd, &offset, &increment);
+ } else {
+#endif /* WITH_WSREP */
+ ut_a(prebuilt->autoinc_increment > 0);
+ offset = prebuilt->autoinc_offset;
+ increment = prebuilt->autoinc_increment;
+#ifdef WITH_WSREP
+ }
+#endif /* WITH_WSREP */
auto_inc = innobase_next_autoinc(
auto_inc,
@@ -9465,16 +9482,32 @@ ha_innobase::update_row(
/* We need the upper limit of the col type to check for
whether we update the table autoinc counter or not. */
- col_max_value = innobase_get_int_col_max_value(
- table->next_number_field);
+ col_max_value =
+ table->next_number_field->get_max_int_value();
if (auto_inc <= col_max_value && auto_inc != 0) {
ulonglong offset;
ulonglong increment;
- offset = prebuilt->autoinc_offset;
- increment = prebuilt->autoinc_increment;
+#ifdef WITH_WSREP
+ /* Applier threads which are processing
+ ROW events and don't go through server
+ level autoinc processing, therefore
+ m_prebuilt autoinc values don't get
+ properly assigned. Fetch values from
+ server side. */
+ if (wsrep_on(current_thd) &&
+ wsrep_thd_exec_mode(current_thd) == REPL_RECV) {
+ wsrep_thd_auto_increment_variables(
+ current_thd, &offset, &increment);
+ } else {
+#endif /* WITH_WSREP */
+ offset = prebuilt->autoinc_offset;
+ increment = prebuilt->autoinc_increment;
+#ifdef WITH_WSREP
+ }
+#endif /* WITH_WSREP */
auto_inc = innobase_next_autoinc(
auto_inc, 1, increment, offset, col_max_value);
@@ -16705,13 +16738,13 @@ ha_innobase::get_auto_increment(
increment,
thd_get_thread_id(ha_thd()),
current, autoinc);
- if (!wsrep_on(ha_thd()))
- {
- current = autoinc - prebuilt->autoinc_increment;
- }
- current = innobase_next_autoinc(
- current, 1, increment, offset, col_max_value);
+ if (!wsrep_on(ha_thd())) {
+ current = autoinc - prebuilt->autoinc_increment;
+
+ current = innobase_next_autoinc(
+ current, 1, increment, offset, col_max_value);
+ }
dict_table_autoinc_initialize(prebuilt->table, current);
diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc
index 549cc411f69..2183d281b78 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -5003,7 +5003,7 @@ lock_table_create(
UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock);
#ifdef WITH_WSREP
- if (c_lock) {
+ if (c_lock && wsrep_on_trx(trx)) {
if (wsrep_thd_is_wsrep(trx->mysql_thd)
&& wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
UT_LIST_INSERT_AFTER(
@@ -5244,9 +5244,10 @@ lock_table_enqueue_waiting(
/* Enqueue the lock request that will wait to be granted */
#ifdef WITH_WSREP
- if (trx->lock.was_chosen_as_deadlock_victim) {
+ if (trx->lock.was_chosen_as_deadlock_victim && wsrep_on_trx(trx)) {
return(DB_DEADLOCK);
}
+
lock = lock_table_create(c_lock, table, mode | LOCK_WAIT, trx);
#else
lock = lock_table_create(table, mode | LOCK_WAIT, trx);
diff --git a/storage/xtradb/log/log0log.cc b/storage/xtradb/log/log0log.cc
index 1420f5a3a12..19b4ac3732a 100644
--- a/storage/xtradb/log/log0log.cc
+++ b/storage/xtradb/log/log0log.cc
@@ -1561,12 +1561,6 @@ log_write_up_to(
return;
}
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
- service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
- "log write up to: " LSN_PF,
- lsn);
- }
-
loop:
ut_ad(++loop_count < 100);
@@ -1679,6 +1673,13 @@ loop:
log_sys->buf_free += OS_FILE_LOG_BLOCK_SIZE;
log_sys->write_end_offset = log_sys->buf_free;
+ if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE)) {
+ service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "InnoDB log write: "
+ LSN_PF "," LSN_PF,
+ log_sys->write_lsn, lsn);
+ }
+
group = UT_LIST_GET_FIRST(log_sys->log_groups);
/* Do the write to the log files */
diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index 3e3b44d9106..25f7e71a583 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -3231,9 +3231,17 @@ srv_purge_should_exit(ulint n_purged)
}
/* Slow shutdown was requested. */
if (n_purged) {
- service_manager_extend_timeout(
- INNODB_EXTEND_TIMEOUT_INTERVAL,
- "InnoDB " ULINTPF " pages purged", n_purged);
+#if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY
+ static ib_time_t progress_time;
+ ib_time_t time = ut_time();
+ if (time - progress_time >= 15) {
+ progress_time = time;
+ service_manager_extend_timeout(
+ INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "InnoDB: to purge " ULINTPF " transactions",
+ trx_sys->rseg_history_len);
+ }
+#endif
/* The previous round still did some work. */
return(false);
}
diff --git a/storage/xtradb/trx/trx0purge.cc b/storage/xtradb/trx/trx0purge.cc
index cbf783628f9..893dc8f398c 100644
--- a/storage/xtradb/trx/trx0purge.cc
+++ b/storage/xtradb/trx/trx0purge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -247,18 +247,20 @@ trx_purge_add_update_undo_to_history(
hist_size + undo->size, MLOG_4BYTES, mtr);
}
- /* Before any transaction-generating background threads or the
+ /* After the purge thread has been given permission to exit,
+ we may roll back transactions (trx->undo_no==0)
+ in THD::cleanup() invoked from unlink_thd() in fast shutdown,
+ or in trx_rollback_resurrected() in slow shutdown.
+
+ Before any transaction-generating background threads or the
purge have been started, recv_recovery_rollback_active() can
start transactions in row_merge_drop_temp_indexes() and
- fts_drop_orphaned_tables(), and roll back recovered transactions.
- After the purge thread has been given permission to exit,
- in fast shutdown, we may roll back transactions (trx->undo_no==0)
- in THD::cleanup() invoked from unlink_thd(). */
+ fts_drop_orphaned_tables(), and roll back recovered transactions. */
ut_ad(srv_undo_sources
+ || trx->undo_no == 0
|| ((srv_startup_is_before_trx_rollback_phase
|| trx_rollback_or_clean_is_active)
- && purge_sys->state == PURGE_STATE_INIT)
- || (trx->undo_no == 0 && srv_fast_shutdown));
+ && purge_sys->state == PURGE_STATE_INIT));
/* Add the log as the first in the history list */
flst_add_first(rseg_header + TRX_RSEG_HISTORY,