summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2023-04-27 09:39:53 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2023-04-27 09:39:53 +0300
commit902c62221583e3c7247050099981b48dd067e3ef (patch)
treef39666955ef88a543b0de53468f110b4fcdfd774
parent6fccf8ba05a19e42ef7ec0e88d98fdcf165648bb (diff)
parentb942f41438339bf6ba33d9156471b29a19fb4121 (diff)
downloadmariadb-git-902c62221583e3c7247050099981b48dd067e3ef.tar.gz
Merge 10.4 into 10.5
-rw-r--r--libmysqld/lib_sql.cc2
-rw-r--r--mysql-test/main/analyze_format_json_emb.result11
-rw-r--r--mysql-test/main/analyze_format_json_emb.test18
-rw-r--r--mysql-test/main/derived_cond_pushdown.result83
-rw-r--r--mysql-test/main/derived_cond_pushdown.test30
-rw-r--r--mysql-test/main/mysqld--help,win.rdiff28
-rw-r--r--mysql-test/main/mysqld--help.result3
-rw-r--r--mysql-test/main/selectivity_innodb.result4
-rw-r--r--mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.cnf (renamed from mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.cnf)0
-rw-r--r--mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.result (renamed from mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.result)1
-rw-r--r--mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.test (renamed from mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.test)30
-rw-r--r--mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.cnf8
-rw-r--r--mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.result84
-rw-r--r--mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.test154
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded.result4
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result4
-rw-r--r--mysql-test/suite/versioning/r/rpl.result24
-rw-r--r--mysql-test/suite/versioning/t/rpl.test34
-rw-r--r--sql/item.h17
-rw-r--r--sql/log.cc3
-rw-r--r--sql/log_event_server.cc21
-rw-r--r--sql/mysqld.cc5
-rw-r--r--sql/rpl_parallel.cc8
-rw-r--r--sql/sys_vars.cc7
24 files changed, 533 insertions, 50 deletions
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index e8dbd696767..e631888cde8 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -565,6 +565,8 @@ int init_embedded_server(int argc, char **argv, char **groups)
if (ho_error != 0)
return 1;
+ my_timer_init(&sys_timer_info);
+
if (init_common_variables())
{
mysql_server_end();
diff --git a/mysql-test/main/analyze_format_json_emb.result b/mysql-test/main/analyze_format_json_emb.result
new file mode 100644
index 00000000000..d61e205f031
--- /dev/null
+++ b/mysql-test/main/analyze_format_json_emb.result
@@ -0,0 +1,11 @@
+#
+# MDEV-31121: ANALYZE statement produces 0 for all timings in embedded serve
+#
+create table t1 (a int);
+insert into t1 values (0),(0);
+set @js='$out';
+set @out=(select json_extract(@js,'$**.query_block.r_total_time_ms'));
+select cast(json_extract(@out,'$[0]') as DOUBLE) > 0;
+cast(json_extract(@out,'$[0]') as DOUBLE) > 0
+1
+drop table t1;
diff --git a/mysql-test/main/analyze_format_json_emb.test b/mysql-test/main/analyze_format_json_emb.test
new file mode 100644
index 00000000000..dcf6f24dd8e
--- /dev/null
+++ b/mysql-test/main/analyze_format_json_emb.test
@@ -0,0 +1,18 @@
+--source include/is_embedded.inc
+--source include/big_test.inc
+
+--echo #
+--echo # MDEV-31121: ANALYZE statement produces 0 for all timings in embedded serve
+--echo #
+create table t1 (a int);
+insert into t1 values (0),(0);
+let $out=`
+analyze format=json select sleep(1+a) from t1
+`;
+
+evalp set @js='$out';
+set @out=(select json_extract(@js,'$**.query_block.r_total_time_ms'));
+select cast(json_extract(@out,'$[0]') as DOUBLE) > 0;
+
+drop table t1;
+
diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result
index 4fc9a0a213f..f7119ca55a5 100644
--- a/mysql-test/main/derived_cond_pushdown.result
+++ b/mysql-test/main/derived_cond_pushdown.result
@@ -18247,4 +18247,87 @@ id select_type table type possible_keys key key_len ref rows Extra
3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary
drop view v1;
drop table t1;
+#
+# MDEV-31102: execution of PS for query where pushdown of condition
+# into view defined as union is applied
+#
+create table t1 (
+n int,
+lv varchar(31) charset latin1,
+mv varchar(31) charset utf8mb3
+) engine=myisam;
+insert into t1 values (1,'aa','xxx'), ('2','bb','yyy'), (3,'cc','zzz');
+create view v1 as
+select case when n=1 then lv when n=2 then mv else NULL end as r from t1
+union
+select 'a';
+select * from v1 where r < 'x';
+r
+aa
+a
+explain extended select * from v1 where r < 'x';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 /* select#1 */ select `v1`.`r` AS `r` from `test`.`v1` where `v1`.`r` < 'x'
+explain format=json select * from v1 where r < 'x';
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "v1.r < 'x'",
+ "materialized": {
+ "query_block": {
+ "union_result": {
+ "table_name": "<union2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "case when t1.n = 1 then convert(t1.lv using utf8) when t1.n = 2 then t1.mv else NULL end < 'x'"
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "UNION",
+ "table": {
+ "message": "No tables used"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
+prepare stmt from "select * from v1 where r < 'x'";
+execute stmt;
+r
+aa
+a
+execute stmt;
+r
+aa
+a
+deallocate prepare stmt;
+drop view v1;
+drop table t1;
# End of 10.4 tests
diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test
index 6cfe23b7866..b4e131dbe79 100644
--- a/mysql-test/main/derived_cond_pushdown.test
+++ b/mysql-test/main/derived_cond_pushdown.test
@@ -3942,4 +3942,34 @@ explain select * from v1;
drop view v1;
drop table t1;
+--echo #
+--echo # MDEV-31102: execution of PS for query where pushdown of condition
+--echo # into view defined as union is applied
+--echo #
+
+create table t1 (
+ n int,
+ lv varchar(31) charset latin1,
+ mv varchar(31) charset utf8mb3
+) engine=myisam;
+insert into t1 values (1,'aa','xxx'), ('2','bb','yyy'), (3,'cc','zzz');
+create view v1 as
+select case when n=1 then lv when n=2 then mv else NULL end as r from t1
+union
+select 'a';
+
+let $q=
+select * from v1 where r < 'x';
+
+eval $q;
+eval explain extended $q;
+eval explain format=json $q;
+eval prepare stmt from "$q";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+drop view v1;
+drop table t1;
+
--echo # End of 10.4 tests
diff --git a/mysql-test/main/mysqld--help,win.rdiff b/mysql-test/main/mysqld--help,win.rdiff
index 337755252ba..bcfefbab1a8 100644
--- a/mysql-test/main/mysqld--help,win.rdiff
+++ b/mysql-test/main/mysqld--help,win.rdiff
@@ -1,6 +1,12 @@
---- a/mysql-test/r/mysqld--help.result
-+++ b/mysql-test/r/mysqld--help.result
-@@ -647,6 +646,7 @@
+@@ -180,6 +180,7 @@
+ --console Write error output on screen; don't remove the console
+ window on windows.
+ --core-file Write core on crashes
++ (Defaults to on; use --skip-core-file to disable.)
+ -h, --datadir=name Path to the database root directory
+ --date-format=name The DATE format (ignored)
+ --datetime-format=name
+@@ -650,6 +651,7 @@
Use MySQL-5.6 (instead of MariaDB-5.3) format for TIME,
DATETIME, TIMESTAMP columns.
(Defaults to on; use --skip-mysql56-temporal-format to disable.)
@@ -8,7 +14,7 @@
--net-buffer-length=#
Buffer length for TCP/IP and socket communication
--net-read-timeout=#
-@@ -1236,6 +1236,10 @@
+@@ -1281,6 +1283,10 @@
Log slow queries to given log file. Defaults logging to
'hostname'-slow.log. Must be enabled to activate other
slow log options
@@ -19,7 +25,7 @@
--socket=name Socket file to use for connection
--sort-buffer-size=#
Each thread that needs to do a sort allocates a buffer of
-@@ -1260,6 +1264,7 @@
+@@ -1305,6 +1311,7 @@
deleting or updating every row in a table.
--stack-trace Print a symbolic stack trace on failure
(Defaults to on; use --skip-stack-trace to disable.)
@@ -27,7 +33,7 @@
--standard-compliant-cte
Allow only CTEs compliant to SQL standard
(Defaults to on; use --skip-standard-compliant-cte to disable.)
-@@ -1330,6 +1335,11 @@
+@@ -1380,6 +1387,11 @@
--thread-pool-max-threads=#
Maximum allowed number of worker threads in the thread
pool
@@ -39,7 +45,7 @@
--thread-pool-oversubscribe=#
How many additional active worker threads in a group are
allowed.
-@@ -1370,8 +1380,8 @@
+@@ -1418,8 +1430,8 @@
automatically convert it to an on-disk MyISAM or Aria
table.
-t, --tmpdir=name Path for temporary files. Several paths may be specified,
@@ -50,7 +56,7 @@
--transaction-alloc-block-size=#
Allocation block size for transactions to be stored in
binary log
-@@ -1587,6 +1596,7 @@
+@@ -1634,6 +1646,7 @@
myisam-stats-method NULLS_UNEQUAL
myisam-use-mmap FALSE
mysql56-temporal-format TRUE
@@ -58,7 +64,7 @@
net-buffer-length 16384
net-read-timeout 30
net-retry-count 10
-@@ -1726,6 +1736,7 @@
+@@ -1788,6 +1801,7 @@
slave-type-conversions
slow-launch-time 2
slow-query-log FALSE
@@ -66,8 +72,8 @@
sort-buffer-size 2097152
sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
sql-safe-updates FALSE
-@@ -1753,6 +1764,8 @@
- thread-cache-size 151
+@@ -1814,6 +1828,8 @@
+ thread-pool-exact-stats FALSE
thread-pool-idle-timeout 60
thread-pool-max-threads 65536
+thread-pool-min-threads 1
diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result
index 60ee8426ccd..1b8e618f41c 100644
--- a/mysql-test/main/mysqld--help.result
+++ b/mysql-test/main/mysqld--help.result
@@ -179,7 +179,7 @@ The following specify which files/extra groups are read (specified before remain
ALWAYS
--console Write error output on screen; don't remove the console
window on windows.
- --core-file Write core on errors.
+ --core-file Write core on crashes
-h, --datadir=name Path to the database root directory
--date-format=name The DATE format (ignored)
--datetime-format=name
@@ -1490,6 +1490,7 @@ column-compression-zlib-wrap FALSE
completion-type NO_CHAIN
concurrent-insert AUTO
console TRUE
+core-file TRUE
date-format %Y-%m-%d
datetime-format %Y-%m-%d %H:%i:%s
deadlock-search-depth-long 15
diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result
index ea7afc08bb3..70d4994a9f5 100644
--- a/mysql-test/main/selectivity_innodb.result
+++ b/mysql-test/main/selectivity_innodb.result
@@ -1866,7 +1866,7 @@ WHERE A.a=t1.a AND t2.b < 20);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL a 5 NULL 100 Using where; Using index
2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index
-2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
+2 DEPENDENT SUBQUERY t2 ref|filter a,b a|b 5|5 test.A.id 1 (19%) Using where; Using rowid filter
EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE A const PRIMARY,a PRIMARY 4 const 1
@@ -1878,7 +1878,7 @@ WHERE A.a=t1.a AND t2.b < 20);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL a 5 NULL 100 Using where; Using index
2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index
-2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
+2 DEPENDENT SUBQUERY t2 ref|filter a,b a|b 5|5 test.A.id 1 (19%) Using where; Using rowid filter
set optimizer_switch= @save_optimizer_switch;
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
drop table t1,t2;
diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.cnf b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.cnf
index 73c9ad655bf..73c9ad655bf 100644
--- a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.cnf
+++ b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.cnf
diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.result b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.result
index d632c565ad2..33c1f1413b4 100644
--- a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.result
+++ b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.result
@@ -4,6 +4,7 @@
include/rpl_init.inc [topology=1->2]
connection server_2;
include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=NO;
#####################################################
# Part 1: unencrypted master
#####################################################
diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.test b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.test
index 1e1b0cbd353..a34c9715239 100644
--- a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.test
+++ b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.test
@@ -1,14 +1,19 @@
#
-# TODO: write here what the test checks after MDEV-11288 is fixed
-#
-# The test starts with unencrypted master.
+# The test starts with unencrypted master.
# It stops replication, generates a few statement and row events
-# on the master, then restarts the server with encrypted binlog,
-# generates some more events and restarts it back without encryption
+# on the master, then restarts the server with encrypted binlog,
+# generates some more events and restarts it back without encryption
# (no encryption plugin).
-# Then it resumes replication and checks what happens when the server
-# tries to feed the binary logs (included the encrypted ones)
-# to the slave.
+# Then it resumes replication and should error with
+# ER_MASTER_FATAL_ERROR_READING_BINLOG because the encrypted binlog is
+# sent and unable to be decrypted.
+#
+# Note this variation of encrypted_master_switch_to_unencrypted tests
+# using MASTER_USE_GTID=NO. In contrast to the GTID variant of this
+# test, at part 3 (the error case), the master will scan binlogs
+# starting from the first one (which is unencrypted initially, so
+# replication is okay) and continue until the slave encounters the
+# first encrypted event, which causes the slave to error.
#
--source include/have_binlog_format_mixed.inc
@@ -27,6 +32,7 @@
--connection server_2
--disable_connect_log
--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=NO;
--enable_connect_log
--echo #####################################################
@@ -41,7 +47,7 @@ CREATE TABLE table1_no_encryption (
pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL,
b BLOB
-) ENGINE=MyISAM;
+) ENGINE=MyISAM;
INSERT INTO table1_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
@@ -74,7 +80,7 @@ CREATE TABLE table2_to_encrypt (
pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL,
b BLOB
-) ENGINE=MyISAM;
+) ENGINE=MyISAM;
INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt');
INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
@@ -101,7 +107,7 @@ CREATE TABLE table3_no_encryption (
pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL,
b BLOB
-) ENGINE=MyISAM;
+) ENGINE=MyISAM;
INSERT INTO table3_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
@@ -113,7 +119,7 @@ INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
--connection server_2
start slave;
-# The slave should be able to synchronize with master up to
+# The slave should be able to synchronize with master up to
# the previously saved position (when the log was still unencrypted)
--sync_with_master
diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.cnf b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.cnf
new file mode 100644
index 00000000000..ad1b8b44c24
--- /dev/null
+++ b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.cnf
@@ -0,0 +1,8 @@
+!include my.cnf
+
+[mysqld.1]
+encrypt-binlog=0
+skip-file-key-management
+
+[mysqld.2]
+gtid-domain-id=1
diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.result b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.result
new file mode 100644
index 00000000000..16ea30557e7
--- /dev/null
+++ b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.result
@@ -0,0 +1,84 @@
+#################
+# Initialization
+#################
+include/rpl_init.inc [topology=1->2]
+connection server_2;
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS;
+call mtr.add_suppression(" Got fatal error 1236 from master when reading data from binary log: 'Could not set up decryption for binlog.'");
+#####################################################
+# Part 1: unencrypted master
+#####################################################
+connection server_1;
+CREATE TABLE table1_no_encryption (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+ts TIMESTAMP NULL,
+b BLOB
+) ENGINE=MyISAM;
+INSERT INTO table1_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
+INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
+FLUSH BINARY LOGS;
+SET binlog_format=ROW;
+INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
+INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
+NOT FOUND /table1_no_encryption/ in master-bin.0*
+#####################################################
+# Part 2: restart master, now with binlog encryption
+#####################################################
+connection default;
+connection server_1;
+CREATE TABLE table2_to_encrypt (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+ts TIMESTAMP NULL,
+b BLOB
+) ENGINE=MyISAM;
+INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt');
+INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
+FLUSH BINARY LOGS;
+SET binlog_format=ROW;
+INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
+INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
+NOT FOUND /table2_to_encrypt/ in master-bin.0*
+#####################################################
+# Part 3: restart master again without encryption
+#####################################################
+connection default;
+connection server_1;
+CREATE TABLE table3_no_encryption (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+ts TIMESTAMP NULL,
+b BLOB
+) ENGINE=MyISAM;
+INSERT INTO table3_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
+INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
+INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
+#####################################################
+# Check: resume replication and check how it goes
+#####################################################
+connection server_2;
+start slave;
+include/wait_for_slave_io_error.inc [errno=1236]
+# Ensuring slave was unable to replicate any transactions..
+# ..success
+SHOW TABLES;
+Tables_in_test
+include/stop_slave.inc
+reset slave;
+##########
+# Cleanup
+##########
+connection server_1;
+reset master;
+SELECT COUNT(*) FROM table1_no_encryption;
+COUNT(*)
+8
+SELECT COUNT(*) FROM table2_to_encrypt;
+COUNT(*)
+8
+SELECT COUNT(*) FROM table3_no_encryption;
+COUNT(*)
+4
+DROP TABLE table1_no_encryption, table2_to_encrypt, table3_no_encryption;
+connection server_2;
+include/start_slave.inc
+include/rpl_end.inc
diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.test b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.test
new file mode 100644
index 00000000000..f882e8f3440
--- /dev/null
+++ b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.test
@@ -0,0 +1,154 @@
+#
+# The test starts with unencrypted master.
+# It stops replication, generates a few statement and row events
+# on the master, then restarts the server with encrypted binlog,
+# generates some more events and restarts it back without encryption
+# (no encryption plugin).
+# Then it resumes replication and should error with
+# ER_MASTER_FATAL_ERROR_READING_BINLOG because the encrypted binlog is
+# sent and unable to be decrypted.
+#
+# Note this variation of encrypted_master_switch_to_unencrypted tests
+# using MASTER_USE_GTID=SLAVE_POS. encrypted_master_switch_to_unencrypted
+# was the original test which only used binlog coordinates. When tested
+# using MASTER_USE_GTID=Slave_Pos, the master optimizes the detection of
+# an undecryptable binlog. I.e, the master will initially look for a
+# Gtid_list_log_event, but fail to decrypt it and fail immediately in
+# part 3.
+#
+
+--source include/have_binlog_format_mixed.inc
+
+--echo #################
+--echo # Initialization
+--echo #################
+
+--let $rpl_topology= 1->2
+--source include/rpl_init.inc
+
+--enable_connect_log
+
+# We stop replication because we want it to happen after the switch
+
+--connection server_2
+--disable_connect_log
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS;
+--enable_connect_log
+call mtr.add_suppression(" Got fatal error 1236 from master when reading data from binary log: 'Could not set up decryption for binlog.'");
+
+--echo #####################################################
+--echo # Part 1: unencrypted master
+--echo #####################################################
+
+--connection server_1
+
+CREATE TABLE table1_no_encryption (
+ pk INT AUTO_INCREMENT PRIMARY KEY,
+ ts TIMESTAMP NULL,
+ b BLOB
+) ENGINE=MyISAM;
+
+INSERT INTO table1_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
+INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
+FLUSH BINARY LOGS;
+SET binlog_format=ROW;
+INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
+INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
+
+# Make sure that binary logs are not encrypted
+
+--let SEARCH_RANGE = 500000
+--let SEARCH_FILE= master-bin.0*
+--let SEARCH_PATTERN= table1_no_encryption
+--source include/search_pattern_in_file.inc
+
+--echo #####################################################
+--echo # Part 2: restart master, now with binlog encryption
+--echo #####################################################
+
+--let $rpl_server_parameters= --encrypt-binlog=1 --plugin-load-add=$FILE_KEY_MANAGEMENT_SO --file-key-management --loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt
+
+--let $rpl_server_number= 1
+--source restart_server.inc
+
+CREATE TABLE table2_to_encrypt (
+ pk INT AUTO_INCREMENT PRIMARY KEY,
+ ts TIMESTAMP NULL,
+ b BLOB
+) ENGINE=MyISAM;
+
+INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt');
+INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
+FLUSH BINARY LOGS;
+SET binlog_format=ROW;
+INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
+INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
+
+# Make sure that binary logs are encrypted
+
+--let SEARCH_FILE= master-bin.0*
+--let SEARCH_PATTERN= table2_to_encrypt
+--source include/search_pattern_in_file.inc
+
+--echo #####################################################
+--echo # Part 3: restart master again without encryption
+--echo #####################################################
+
+--let $rpl_server_parameters= --encrypt-binlog=0
+--let $rpl_server_number= 1
+--source restart_server.inc
+
+CREATE TABLE table3_no_encryption (
+ pk INT AUTO_INCREMENT PRIMARY KEY,
+ ts TIMESTAMP NULL,
+ b BLOB
+) ENGINE=MyISAM;
+
+INSERT INTO table3_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
+INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
+INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
+
+--echo #####################################################
+--echo # Check: resume replication and check how it goes
+--echo #####################################################
+
+--connection server_2
+start slave;
+# Make slave to try to synchronize. It shouldn't work, the slave IO thread is
+# expected to abort with an error
+--let $slave_io_errno= 1236
+--source include/wait_for_slave_io_error.inc
+
+--echo # Ensuring slave was unable to replicate any transactions..
+--let $gsp= `SELECT @@global.gtid_slave_pos`
+if (`SELECT strcmp("$gsp","")`)
+{
+ die Slave without encryption configured should fail to read encrypted binlog;
+}
+--echo # ..success
+
+--sorted_result
+SHOW TABLES;
+
+--disable_connect_log
+--source include/stop_slave.inc
+--enable_connect_log
+reset slave;
+
+--echo ##########
+--echo # Cleanup
+--echo ##########
+
+--connection server_1
+reset master;
+
+SELECT COUNT(*) FROM table1_no_encryption;
+SELECT COUNT(*) FROM table2_to_encrypt;
+SELECT COUNT(*) FROM table3_no_encryption;
+DROP TABLE table1_no_encryption, table2_to_encrypt, table3_no_encryption;
+
+--connection server_2
+--disable_connect_log
+--source include/start_slave.inc
+--source include/rpl_end.inc
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 488d2bcf5de..2b158bd4fa5 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -655,13 +655,13 @@ COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME CORE_FILE
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN
-VARIABLE_COMMENT write a core-file on crashes
+VARIABLE_COMMENT Write core on crashes
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST OFF,ON
READ_ONLY YES
-COMMAND_LINE_ARGUMENT NULL
+COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME DATADIR
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 843b9d9c8af..91ce5d8ebc1 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -655,13 +655,13 @@ COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME CORE_FILE
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN
-VARIABLE_COMMENT write a core-file on crashes
+VARIABLE_COMMENT Write core on crashes
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST OFF,ON
READ_ONLY YES
-COMMAND_LINE_ARGUMENT NULL
+COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME DATADIR
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE VARCHAR
diff --git a/mysql-test/suite/versioning/r/rpl.result b/mysql-test/suite/versioning/r/rpl.result
index a6fa6b3fca7..17372c63e99 100644
--- a/mysql-test/suite/versioning/r/rpl.result
+++ b/mysql-test/suite/versioning/r/rpl.result
@@ -164,4 +164,28 @@ update t1 set i = 0;
connection slave;
connection master;
drop table t1;
+# check versioned -> versioned replication without any keys on duplicate records
+connection master;
+create table t1 (a INT) with system versioning;
+insert into t1 values (1);
+insert into t1 values (1);
+delete from t1;
+connection slave;
+include/diff_tables.inc [master:test.t1,slave:test.t1]
+connection master;
+drop table t1;
+connection slave;
+# check unversioned -> versioned replication with non-unique keys on duplicate records
+connection master;
+set statement sql_log_bin=0 for create table t1 (a INT NOT NULL, b INT, INDEX(a,b));
+connection slave;
+set statement sql_log_bin=0 for create table t1 (a INT NOT NULL, b INT, INDEX(a,b)) with system versioning;
+connection master;
+insert into t1 values (1,1);
+insert into t1 values (1,1);
+delete from t1;
+connection slave;
+include/diff_tables.inc [master:test.t1,slave:test.t1]
+connection master;
+drop table t1;
include/rpl_end.inc
diff --git a/mysql-test/suite/versioning/t/rpl.test b/mysql-test/suite/versioning/t/rpl.test
index b5be68feece..7d78b60e6fa 100644
--- a/mysql-test/suite/versioning/t/rpl.test
+++ b/mysql-test/suite/versioning/t/rpl.test
@@ -133,4 +133,38 @@ sync_slave_with_master;
connection master;
drop table t1;
+
+#
+# MDEV-30430: Enabling system versioning on tables without primary key breaks replication
+# Note that bugs are only present with row binlog format
+#
+--echo # check versioned -> versioned replication without any keys on duplicate records
+connection master;
+create table t1 (a INT) with system versioning;
+insert into t1 values (1);
+insert into t1 values (1);
+delete from t1;
+sync_slave_with_master;
+--let $diff_tables= master:test.t1,slave:test.t1
+--source include/diff_tables.inc
+connection master;
+drop table t1;
+sync_slave_with_master;
+
+--echo # check unversioned -> versioned replication with non-unique keys on duplicate records
+connection master;
+set statement sql_log_bin=0 for create table t1 (a INT NOT NULL, b INT, INDEX(a,b));
+connection slave;
+set statement sql_log_bin=0 for create table t1 (a INT NOT NULL, b INT, INDEX(a,b)) with system versioning;
+connection master;
+insert into t1 values (1,1);
+insert into t1 values (1,1);
+delete from t1;
+sync_slave_with_master;
+--let $diff_tables= master:test.t1,slave:test.t1
+--source include/diff_tables.inc
+
+connection master;
+drop table t1;
+
--source include/rpl_end.inc
diff --git a/sql/item.h b/sql/item.h
index 79e93fda35f..6ac8ed9b509 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -7639,7 +7639,7 @@ public:
Item *get_tmp_table_item(THD *thd)
{ return m_item->get_tmp_table_item(thd); }
Item *get_copy(THD *thd)
- { return m_item->get_copy(thd); }
+ { return get_item_copy<Item_direct_ref_to_item>(thd, this); }
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields,
COND_EQUAL **cond_equal_ref)
@@ -7707,7 +7707,20 @@ public:
bool excl_dep_on_grouping_fields(st_select_lex *sel)
{ return m_item->excl_dep_on_grouping_fields(sel); }
bool is_expensive() { return m_item->is_expensive(); }
- Item* build_clone(THD *thd) { return get_copy(thd); }
+ void set_item(Item *item) { m_item= item; }
+ Item *build_clone(THD *thd)
+ {
+ Item *clone_item= m_item->build_clone(thd);
+ if (clone_item)
+ {
+ Item_direct_ref_to_item *copy= (Item_direct_ref_to_item *) get_copy(thd);
+ if (!copy)
+ return 0;
+ copy->set_item(clone_item);
+ return copy;
+ }
+ return 0;
+ }
void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &fields, uint flags)
diff --git a/sql/log.cc b/sql/log.cc
index 76d93363dd7..608d47547b1 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -11082,7 +11082,10 @@ get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list)
if (typ == START_ENCRYPTION_EVENT)
{
if (fdle->start_decryption((Start_encryption_log_event*) ev))
+ {
errormsg= "Could not set up decryption for binlog.";
+ break;
+ }
}
delete ev;
if (typ == ROTATE_EVENT || typ == STOP_EVENT ||
diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc
index a2b78bc241d..f19bebd9863 100644
--- a/sql/log_event_server.cc
+++ b/sql/log_event_server.cc
@@ -7570,7 +7570,7 @@ uint8 Write_rows_log_event::get_trg_event_map()
Returns TRUE if different.
*/
-static bool record_compare(TABLE *table)
+static bool record_compare(TABLE *table, bool vers_from_plain= false)
{
bool result= FALSE;
/**
@@ -7603,10 +7603,19 @@ static bool record_compare(TABLE *table)
/* Compare fields */
for (Field **ptr=table->field ; *ptr ; ptr++)
{
- if (table->versioned() && (*ptr)->vers_sys_field())
- {
+ /*
+ If the table is versioned, don't compare using the version if there is a
+ primary key. If there isn't a primary key, we need the version to
+ identify the correct record if there are duplicate rows in the data set.
+ However, if the primary server is unversioned (vers_from_plain is true),
+ then we implicitly use row_end as the primary key on our side. This is
+ because the implicit row_end value will be set to the maximum value for
+ the latest row update (which is what we care about).
+ */
+ if (table->versioned() && (*ptr)->vers_sys_field() &&
+ (table->s->primary_key < MAX_KEY ||
+ (vers_from_plain && table->vers_start_field() == (*ptr))))
continue;
- }
/**
We only compare field contents that are not null.
NULL fields (i.e., their null bits) were compared
@@ -8003,7 +8012,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
/* We use this to test that the correct key is used in test cases. */
DBUG_EXECUTE_IF("slave_crash_if_index_scan", abort(););
- while (record_compare(table))
+ while (record_compare(table, m_vers_from_plain))
{
while ((error= table->file->ha_index_next(table->record[0])))
{
@@ -8056,7 +8065,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
goto end;
}
}
- while (record_compare(table));
+ while (record_compare(table, m_vers_from_plain));
/*
Note: above record_compare will take into accout all record fields
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index a54575a2004..1348ed625d9 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -6453,8 +6453,6 @@ struct my_option my_long_options[]=
{"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.",
&opt_console, &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
- {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
- NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef DBUG_OFF
{"debug", '#', "Built in DBUG debugger. Disabled in this build.",
&current_dbug_option, &current_dbug_option, 0, GET_STR, OPT_ARG,
@@ -8221,9 +8219,6 @@ mysqld_get_one_option(const struct my_option *opt, const char *argument,
case (int) OPT_SKIP_HOST_CACHE:
opt_specialflag|= SPECIAL_NO_HOST_CACHE;
break;
- case (int) OPT_WANT_CORE:
- test_flags |= TEST_CORE_ON_SIGNAL;
- break;
case OPT_CONSOLE:
if (opt_console)
opt_error_log= 0; // Force logs to stdout
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index 3df6c2d9f66..a9b4f046988 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -2325,14 +2325,16 @@ rpl_parallel::find(uint32 domain_id)
e->domain_id= domain_id;
e->stop_on_error_sub_id= (uint64)ULONGLONG_MAX;
e->pause_sub_id= (uint64)ULONGLONG_MAX;
+ mysql_mutex_init(key_LOCK_parallel_entry, &e->LOCK_parallel_entry,
+ MY_MUTEX_INIT_FAST);
+ mysql_cond_init(key_COND_parallel_entry, &e->COND_parallel_entry, NULL);
if (my_hash_insert(&domain_hash, (uchar *)e))
{
+ mysql_cond_destroy(&e->COND_parallel_entry);
+ mysql_mutex_destroy(&e->LOCK_parallel_entry);
my_free(e);
return NULL;
}
- mysql_mutex_init(key_LOCK_parallel_entry, &e->LOCK_parallel_entry,
- MY_MUTEX_INIT_FAST);
- mysql_cond_init(key_COND_parallel_entry, &e->COND_parallel_entry, NULL);
}
else
e->force_abort= false;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 02e6f612f21..4768ad7dfb7 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -602,10 +602,9 @@ bool check_has_super(sys_var *self, THD *thd, set_var *var)
return false;
}
-static Sys_var_bit Sys_core_file("core_file", "write a core-file on crashes",
- READ_ONLY GLOBAL_VAR(test_flags), NO_CMD_LINE,
- TEST_CORE_ON_SIGNAL, DEFAULT(IF_WIN(TRUE,FALSE)), NO_MUTEX_GUARD, NOT_IN_BINLOG,
- 0,0,0);
+static Sys_var_bit Sys_core_file("core_file", "Write core on crashes",
+ READ_ONLY GLOBAL_VAR(test_flags), CMD_LINE(OPT_ARG),
+ TEST_CORE_ON_SIGNAL, DEFAULT(IF_WIN(TRUE,FALSE)));
static bool binlog_format_check(sys_var *self, THD *thd, set_var *var)
{