summaryrefslogtreecommitdiffstats
path: root/mysql-test/suite/s3
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:24:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:24:36 +0000
commit06eaf7232e9a920468c0f8d74dcf2fe8b555501c (patch)
treee2c7b5777f728320e5b5542b6213fd3591ba51e2 /mysql-test/suite/s3
parentInitial commit. (diff)
downloadmariadb-06eaf7232e9a920468c0f8d74dcf2fe8b555501c.tar.xz
mariadb-06eaf7232e9a920468c0f8d74dcf2fe8b555501c.zip
Adding upstream version 1:10.11.6.upstream/1%10.11.6
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mysql-test/suite/s3')
-rw-r--r--mysql-test/suite/s3/alter.result132
-rw-r--r--mysql-test/suite/s3/alter.test99
-rw-r--r--mysql-test/suite/s3/alter2.result49
-rw-r--r--mysql-test/suite/s3/alter2.test64
-rw-r--r--mysql-test/suite/s3/amazon.result7
-rw-r--r--mysql-test/suite/s3/amazon.test27
-rw-r--r--mysql-test/suite/s3/arguments.result58
-rw-r--r--mysql-test/suite/s3/arguments.test54
-rw-r--r--mysql-test/suite/s3/backup.result18
-rw-r--r--mysql-test/suite/s3/backup.test33
-rw-r--r--mysql-test/suite/s3/basic.result156
-rw-r--r--mysql-test/suite/s3/basic.test88
-rw-r--r--mysql-test/suite/s3/create_database.inc10
-rw-r--r--mysql-test/suite/s3/disabled.def0
-rw-r--r--mysql-test/suite/s3/discovery.result57
-rw-r--r--mysql-test/suite/s3/discovery.test84
-rw-r--r--mysql-test/suite/s3/drop_database.inc9
-rw-r--r--mysql-test/suite/s3/encryption.opt4
-rw-r--r--mysql-test/suite/s3/encryption.result23
-rw-r--r--mysql-test/suite/s3/encryption.test36
-rw-r--r--mysql-test/suite/s3/innodb.result31
-rw-r--r--mysql-test/suite/s3/innodb.test35
-rw-r--r--mysql-test/suite/s3/my.cnf33
-rw-r--r--mysql-test/suite/s3/mysqldump.result64
-rw-r--r--mysql-test/suite/s3/mysqldump.test33
-rw-r--r--mysql-test/suite/s3/no_s3-master.opt1
-rw-r--r--mysql-test/suite/s3/no_s3.result11
-rw-r--r--mysql-test/suite/s3/no_s3.test25
-rw-r--r--mysql-test/suite/s3/partition.result164
-rw-r--r--mysql-test/suite/s3/partition.test118
-rw-r--r--mysql-test/suite/s3/partition_create_fail.result15
-rw-r--r--mysql-test/suite/s3/partition_create_fail.test39
-rw-r--r--mysql-test/suite/s3/partition_move.result74
-rw-r--r--mysql-test/suite/s3/partition_move.test80
-rw-r--r--mysql-test/suite/s3/replication.inc209
-rw-r--r--mysql-test/suite/s3/replication_delayed.cnf3
-rw-r--r--mysql-test/suite/s3/replication_delayed.result124
-rw-r--r--mysql-test/suite/s3/replication_delayed.test115
-rw-r--r--mysql-test/suite/s3/replication_mixed.cnf3
-rw-r--r--mysql-test/suite/s3/replication_mixed.result300
-rw-r--r--mysql-test/suite/s3/replication_mixed.test11
-rw-r--r--mysql-test/suite/s3/replication_partition.cnf3
-rw-r--r--mysql-test/suite/s3/replication_partition.result290
-rw-r--r--mysql-test/suite/s3/replication_partition.test170
-rw-r--r--mysql-test/suite/s3/replication_stmt.cnf3
-rw-r--r--mysql-test/suite/s3/replication_stmt.result300
-rw-r--r--mysql-test/suite/s3/replication_stmt.test11
-rw-r--r--mysql-test/suite/s3/select.result8
-rw-r--r--mysql-test/suite/s3/select.test17
-rw-r--r--mysql-test/suite/s3/slave.cnf34
-rw-r--r--mysql-test/suite/s3/suite.pm67
-rw-r--r--mysql-test/suite/s3/unsupported.result15
-rw-r--r--mysql-test/suite/s3/unsupported.test43
53 files changed, 3457 insertions, 0 deletions
diff --git a/mysql-test/suite/s3/alter.result b/mysql-test/suite/s3/alter.result
new file mode 100644
index 00000000..1a931b71
--- /dev/null
+++ b/mysql-test/suite/s3/alter.result
@@ -0,0 +1,132 @@
+drop table if exists t1,t2,t3;
+#
+# Test ALTER TABLE to and from s3
+#
+create table t1 (a int, b int) engine=aria;
+insert into t1 select seq,seq+10 from seq_1_to_1000;
+alter table t1 engine=s3;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+alter table t1 comment="hello";
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 COMMENT='hello'
+alter table t1 engine=aria;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 COMMENT='hello'
+alter table t1 engine=s3;
+alter table t1 engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 COMMENT='hello'
+select count(*), sum(a), sum(b) from t1;
+count(*) sum(a) sum(b)
+1000 500500 510500
+drop table t1;
+#
+# Test ALTER TABLE to and from s3 with rename
+#
+create table t1 (a int, b int) engine=aria select seq as a,seq+10 as b from seq_1_to_10;
+alter table t1 rename to t2, engine=s3;
+select count(*), sum(a), sum(b) from t2;
+count(*) sum(a) sum(b)
+10 55 155
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+alter table t2 rename to t3, engine=aria;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+select count(*), sum(a), sum(b) from t3;
+count(*) sum(a) sum(b)
+10 55 155
+drop table t3;
+#
+# Test changing options for a s3 table
+#
+create table t1 (a int, b int) engine=aria select seq as a,seq+10 as b from seq_1_to_1000;
+alter table t1 engine=s3;
+alter table t1 engine=s3, compression_algorithm="zlib";
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 `compression_algorithm`='zlib'
+select count(*), sum(a), sum(b) from t1;
+count(*) sum(a) sum(b)
+1000 500500 510500
+drop table t1;
+#
+# Test ALTER TABLE for S3
+#
+create table t1 (a int, b int) engine=aria select seq as a,seq+10 as b from seq_1_to_10;
+alter table t1 add column c int, engine=s3;
+alter table t1 add column d int;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+select count(*), sum(a), sum(b), sum(c), sum(d) from t1;
+count(*) sum(a) sum(b) sum(c) sum(d)
+10 55 155 NULL NULL
+drop table t1;
+#
+# Test ALTER TABLE with locked table for S3
+#
+create table t1 (a int, b int) engine=aria select seq as a,seq+10 as b from seq_1_to_10;
+lock table t1 write;
+alter table t1 add column c int, engine=s3;
+Warnings:
+Warning 1036 Table 't1' is read only
+Warning 1213 Deadlock found when trying to get lock; try restarting transaction
+unlock tables;
+select count(*), sum(a), sum(b), sum(c) from t1;
+count(*) sum(a) sum(b) sum(c)
+10 55 155 NULL
+lock table t1 write;
+ERROR HY000: Table 't1' is read only
+lock table t1 read;
+select count(*), sum(a), sum(b), sum(c) from t1;
+count(*) sum(a) sum(b) sum(c)
+10 55 155 NULL
+unlock tables;
+drop table t1;
+#
+# Test RENAME TABLE
+#
+create table t1 (a int, b int) engine=aria select seq as a, seq+10 as b from seq_1_to_10;
+alter table t1 engine=s3;
+rename table t1 to t3;
+alter table t3 rename t2;
+select count(*), sum(a), sum(b) from t2;
+count(*) sum(a) sum(b)
+10 55 155
+select count(*), sum(a), sum(b) from t1;
+ERROR 42S02: Table 'database.t1' doesn't exist
+drop table t2;
diff --git a/mysql-test/suite/s3/alter.test b/mysql-test/suite/s3/alter.test
new file mode 100644
index 00000000..7882d14e
--- /dev/null
+++ b/mysql-test/suite/s3/alter.test
@@ -0,0 +1,99 @@
+--source include/have_s3.inc
+--source include/have_sequence.inc
+--source include/have_innodb.inc
+
+#
+# Create unique database for running the tests
+#
+--source create_database.inc
+--disable_warnings
+drop table if exists t1,t2,t3;
+--enable_warnings
+
+--echo #
+--echo # Test ALTER TABLE to and from s3
+--echo #
+
+create table t1 (a int, b int) engine=aria;
+insert into t1 select seq,seq+10 from seq_1_to_1000;
+alter table t1 engine=s3;
+show create table t1;
+alter table t1 comment="hello";
+show create table t1;
+alter table t1 engine=aria;
+show create table t1;
+alter table t1 engine=s3;
+alter table t1 engine=innodb;
+show create table t1;
+select count(*), sum(a), sum(b) from t1;
+drop table t1;
+
+--echo #
+--echo # Test ALTER TABLE to and from s3 with rename
+--echo #
+
+create table t1 (a int, b int) engine=aria select seq as a,seq+10 as b from seq_1_to_10;
+alter table t1 rename to t2, engine=s3;
+select count(*), sum(a), sum(b) from t2;
+show create table t2;
+alter table t2 rename to t3, engine=aria;
+show create table t3;
+select count(*), sum(a), sum(b) from t3;
+drop table t3;
+
+--echo #
+--echo # Test changing options for a s3 table
+--echo #
+
+create table t1 (a int, b int) engine=aria select seq as a,seq+10 as b from seq_1_to_1000;
+alter table t1 engine=s3;
+alter table t1 engine=s3, compression_algorithm="zlib";
+show create table t1;
+select count(*), sum(a), sum(b) from t1;
+drop table t1;
+
+--echo #
+--echo # Test ALTER TABLE for S3
+--echo #
+
+create table t1 (a int, b int) engine=aria select seq as a,seq+10 as b from seq_1_to_10;
+alter table t1 add column c int, engine=s3;
+alter table t1 add column d int;
+show create table t1;
+select count(*), sum(a), sum(b), sum(c), sum(d) from t1;
+drop table t1;
+
+--echo #
+--echo # Test ALTER TABLE with locked table for S3
+--echo #
+
+create table t1 (a int, b int) engine=aria select seq as a,seq+10 as b from seq_1_to_10;
+lock table t1 write;
+alter table t1 add column c int, engine=s3;
+unlock tables;
+select count(*), sum(a), sum(b), sum(c) from t1;
+--error ER_OPEN_AS_READONLY
+lock table t1 write;
+lock table t1 read;
+select count(*), sum(a), sum(b), sum(c) from t1;
+unlock tables;
+drop table t1;
+
+--echo #
+--echo # Test RENAME TABLE
+--echo #
+
+create table t1 (a int, b int) engine=aria select seq as a, seq+10 as b from seq_1_to_10;
+alter table t1 engine=s3;
+rename table t1 to t3;
+alter table t3 rename t2;
+select count(*), sum(a), sum(b) from t2;
+--replace_result $database database
+--error ER_NO_SUCH_TABLE
+select count(*), sum(a), sum(b) from t1;
+drop table t2;
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/alter2.result b/mysql-test/suite/s3/alter2.result
new file mode 100644
index 00000000..8d2cae03
--- /dev/null
+++ b/mysql-test/suite/s3/alter2.result
@@ -0,0 +1,49 @@
+#
+# MDEV-19575 Assertion `page_st == 1' failed upon SELECT from S3
+# table which is being converted into Aria
+#
+CREATE TABLE t1 (f INT);
+insert into t1 values (1),(2);
+ALTER TABLE t1 ENGINE=S3;
+select * from t1;
+f
+1
+2
+connect con1,localhost,root,,$database;
+ALTER TABLE t1 ENGINE=Aria;
+connection default;
+SELECT * FROM t1;
+f
+1
+2
+connection con1;
+disconnect con1;
+connection default;
+DROP TABLE t1;
+#
+# MDEV-20302 Server hangs upon concurrent SELECT from partitioned S3
+# table
+#
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT,
+c CHAR(12),
+PRIMARY KEY(pk),
+KEY(c)
+) ENGINE=Aria
+PARTITION BY KEY(pk) PARTITIONS 2;
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (NULL,'ill'),(NULL,'loop');
+ALTER TABLE t1 ENGINE=S3;
+connect con1,localhost,root,,$database;
+SELECT * FROM t1 WHERE c BETWEEN 'bar' AND 'foo';
+connection default;
+SELECT pk FROM v1;
+pk
+1
+2
+connection con1;
+pk c
+disconnect con1;
+connection default;
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/s3/alter2.test b/mysql-test/suite/s3/alter2.test
new file mode 100644
index 00000000..856b1415
--- /dev/null
+++ b/mysql-test/suite/s3/alter2.test
@@ -0,0 +1,64 @@
+--source include/have_s3.inc
+--source include/have_partition.inc
+--source create_database.inc
+
+--echo #
+--echo # MDEV-19575 Assertion `page_st == 1' failed upon SELECT from S3
+--echo # table which is being converted into Aria
+--echo #
+
+CREATE TABLE t1 (f INT);
+insert into t1 values (1),(2);
+
+ALTER TABLE t1 ENGINE=S3;
+select * from t1;
+--connect (con1,localhost,root,,$database)
+--send
+ ALTER TABLE t1 ENGINE=Aria;
+
+--connection default
+SELECT * FROM t1;
+
+# Cleanup
+
+--connection con1
+--reap
+--disconnect con1
+--connection default
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-20302 Server hangs upon concurrent SELECT from partitioned S3
+--echo # table
+--echo #
+
+CREATE TABLE t1 (
+ pk INT AUTO_INCREMENT,
+ c CHAR(12),
+ PRIMARY KEY(pk),
+ KEY(c)
+) ENGINE=Aria
+ PARTITION BY KEY(pk) PARTITIONS 2;
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (NULL,'ill'),(NULL,'loop');
+ALTER TABLE t1 ENGINE=S3;
+--connect (con1,localhost,root,,$database)
+--send
+ SELECT * FROM t1 WHERE c BETWEEN 'bar' AND 'foo';
+
+--connection default
+SELECT pk FROM v1;
+
+--connection con1
+--reap
+
+--disconnect con1
+--connection default
+DROP VIEW v1;
+DROP TABLE t1;
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/amazon.result b/mysql-test/suite/s3/amazon.result
new file mode 100644
index 00000000..29075118
--- /dev/null
+++ b/mysql-test/suite/s3/amazon.result
@@ -0,0 +1,7 @@
+set @save_s3_protocol_version=@@global.s3_protocol_version;
+set @@global.s3_protocol_version="Original";
+create table t1 (pk int primary key, a int);
+insert into t1 values (1,1),(2,2),(3,3),(4,4);
+alter table t1 engine=S3;
+drop table t1;
+set @@global.s3_protocol_version=@save_s3_protocol_version;
diff --git a/mysql-test/suite/s3/amazon.test b/mysql-test/suite/s3/amazon.test
new file mode 100644
index 00000000..3c64cc28
--- /dev/null
+++ b/mysql-test/suite/s3/amazon.test
@@ -0,0 +1,27 @@
+--source include/have_s3.inc
+
+if (`SELECT @@s3_host_name <> "s3.amazonaws.com"`)
+{
+ skip Not connected to AWS;
+}
+
+--source create_database.inc
+
+#
+# Check options against amazon
+#
+
+set @save_s3_protocol_version=@@global.s3_protocol_version;
+set @@global.s3_protocol_version="Original";
+
+create table t1 (pk int primary key, a int);
+insert into t1 values (1,1),(2,2),(3,3),(4,4);
+--replace_result $database database
+alter table t1 engine=S3;
+drop table t1;
+
+#
+# clean up
+#
+set @@global.s3_protocol_version=@save_s3_protocol_version;
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/arguments.result b/mysql-test/suite/s3/arguments.result
new file mode 100644
index 00000000..8133af4b
--- /dev/null
+++ b/mysql-test/suite/s3/arguments.result
@@ -0,0 +1,58 @@
+drop table if exists t1;
+#
+# Test options
+#
+create or replace table t1 (a int, b int, key(a)) engine=aria;
+insert into t1 select seq,seq+10 from seq_1_to_10;
+alter table t1 engine=s3, s3_block_size=819200, compression_algorithm="zlib";
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ KEY `a` (`a`)
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 `s3_block_size`=819200 `compression_algorithm`='zlib'
+alter table t1 engine=s3, s3_block_size=8192;
+ERROR HY000: Incorrect value '8192' for option 's3_block_size'
+alter table t1 engine=s3, s3_block_size=65536;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ KEY `a` (`a`)
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 `compression_algorithm`='zlib' `s3_block_size`=65536
+alter table t1 engine=s3, s3_block_size=100000;
+ERROR HY000: Incorrect value '100000' for option 's3_block_size'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ KEY `a` (`a`)
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 `compression_algorithm`='zlib' `s3_block_size`=65536
+alter table t1 engine=s3, compression_algorithm="wss";
+ERROR HY000: Incorrect value 'wss' for option 'compression_algorithm'
+drop table t1;
+# Check that key variables are not shown to the end user
+show variables like "s3%key";
+Variable_name Value
+s3_access_key *****
+s3_secret_key *****
+# Show some "static" s3 variables
+set @tmp= @@global.s3_block_size;
+show variables like "s3_block_size";
+Variable_name Value
+s3_block_size 4194304
+set @@global.s3_block_size=65536;
+show variables like "s3_block_size";
+Variable_name Value
+s3_block_size 65536
+set @@global.s3_block_size= @tmp;
+set @@s3_block_size=65536;
+ERROR HY000: Variable 's3_block_size' is a GLOBAL variable and should be set with SET GLOBAL
+# Check s3 variables that can't be changed by end user
+set @@s3_access_key="abc";
+ERROR HY000: Variable 's3_access_key' is a read only variable
+set @@s3_secret_key="abc";
+ERROR HY000: Variable 's3_secret_key' is a read only variable
diff --git a/mysql-test/suite/s3/arguments.test b/mysql-test/suite/s3/arguments.test
new file mode 100644
index 00000000..76ef4c96
--- /dev/null
+++ b/mysql-test/suite/s3/arguments.test
@@ -0,0 +1,54 @@
+--source include/have_s3.inc
+--source include/have_sequence.inc
+
+#
+# Create unique database for running the tests
+#
+--source create_database.inc
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+--echo #
+--echo # Test options
+--echo #
+
+create or replace table t1 (a int, b int, key(a)) engine=aria;
+insert into t1 select seq,seq+10 from seq_1_to_10;
+alter table t1 engine=s3, s3_block_size=819200, compression_algorithm="zlib";
+show create table t1;
+--error ER_BAD_OPTION_VALUE
+alter table t1 engine=s3, s3_block_size=8192;
+alter table t1 engine=s3, s3_block_size=65536;
+show create table t1;
+--error ER_BAD_OPTION_VALUE
+alter table t1 engine=s3, s3_block_size=100000;
+show create table t1;
+--error ER_BAD_OPTION_VALUE
+alter table t1 engine=s3, compression_algorithm="wss";
+drop table t1;
+
+--echo # Check that key variables are not shown to the end user
+
+show variables like "s3%key";
+
+--echo # Show some "static" s3 variables
+set @tmp= @@global.s3_block_size;
+show variables like "s3_block_size";
+set @@global.s3_block_size=65536;
+show variables like "s3_block_size";
+set @@global.s3_block_size= @tmp;
+--error ER_GLOBAL_VARIABLE
+set @@s3_block_size=65536;
+
+--echo # Check s3 variables that can't be changed by end user
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set @@s3_access_key="abc";
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set @@s3_secret_key="abc";
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/backup.result b/mysql-test/suite/s3/backup.result
new file mode 100644
index 00000000..55065d7b
--- /dev/null
+++ b/mysql-test/suite/s3/backup.result
@@ -0,0 +1,18 @@
+#
+# MDEV-19585 Assertion `!is_set() || (m_status == DA_OK_BULK &&
+# is_bulk_op())' failed upon SELECT from S3 table with concurrent
+# BACKUP stage
+#
+CREATE TABLE t1 (a INT);
+ALTER TABLE t1 ENGINE=S3;
+connect con1,localhost,root,,test;
+BACKUP STAGE START;
+connection default;
+SELECT * FROM t1;
+connection con1;
+BACKUP STAGE BLOCK_COMMIT;
+BACKUP STAGE END;
+disconnect con1;
+connection default;
+a
+DROP TABLE t1;
diff --git a/mysql-test/suite/s3/backup.test b/mysql-test/suite/s3/backup.test
new file mode 100644
index 00000000..06f61429
--- /dev/null
+++ b/mysql-test/suite/s3/backup.test
@@ -0,0 +1,33 @@
+--source include/have_s3.inc
+--source create_database.inc
+
+--echo #
+--echo # MDEV-19585 Assertion `!is_set() || (m_status == DA_OK_BULK &&
+--echo # is_bulk_op())' failed upon SELECT from S3 table with concurrent
+--echo # BACKUP stage
+--echo #
+
+CREATE TABLE t1 (a INT);
+ALTER TABLE t1 ENGINE=S3;
+
+--connect (con1,localhost,root,,test)
+BACKUP STAGE START;
+
+--connection default
+--send
+SELECT * FROM t1;
+
+--connection con1
+BACKUP STAGE BLOCK_COMMIT;
+
+# Cleanup
+BACKUP STAGE END;
+--disconnect con1
+--connection default
+--reap
+DROP TABLE t1;
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/basic.result b/mysql-test/suite/s3/basic.result
new file mode 100644
index 00000000..790806ee
--- /dev/null
+++ b/mysql-test/suite/s3/basic.result
@@ -0,0 +1,156 @@
+drop table if exists t1;
+#
+# Test simple create of s3 table
+#
+create or replace table t1 (a int, b int, c varchar(1000), key (a), key(c)) engine=aria;
+insert into t1 select seq, seq+10, repeat(char(65+ mod(seq, 20)),mod(seq,1000)) from seq_1_to_10000;
+alter table t1 engine=s3;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` varchar(1000) DEFAULT NULL,
+ KEY `a` (`a`),
+ KEY `c` (`c`)
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+select * from information_schema.tables where table_schema="database" and table_name="t1";;
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
+def # t1 BASE TABLE S3 10 Page 10000 567 5677056 # 761856 0 NULL # # # latin1_swedish_ci NULL page_checksum=1 2305843009213685760 #
+show table status like "t1";
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 S3 10 Page 10000 567 5677056 # 761856 0 NULL # # # latin1_swedish_ci NULL page_checksum=1 # N
+select a,b from t1 limit 10;
+a b
+1 11
+2 12
+3 13
+4 14
+5 15
+6 16
+7 17
+8 18
+9 19
+10 20
+select count(*) from t1;
+count(*)
+10000
+select a,b from t1 where a between 10 and 20;
+a b
+10 20
+11 21
+12 22
+13 23
+14 24
+15 25
+16 26
+17 27
+18 28
+19 29
+20 30
+explain select * from t1 where a between 10 and 20;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL # Using index condition
+insert into t1 values (1,1);
+ERROR HY000: Table 't1' is read only
+update t1 set b=100 where a=1;
+ERROR HY000: Table 't1' is read only
+delete from t1 where a>10;
+ERROR HY000: Table 't1' is read only
+#
+# Analyze, repair, optimize and check table
+#
+set @@use_stat_tables='never';
+truncate mysql.table_stats;
+check table t1 fast;
+Table Op Msg_type Msg_text
+database.t1 check status Table is already up to date
+check table t1 quick;
+Table Op Msg_type Msg_text
+database.t1 check status OK
+check table t1 extended;
+Table Op Msg_type Msg_text
+database.t1 check status OK
+analyze table t1;
+Table Op Msg_type Msg_text
+database.t1 analyze status Table 'database.t1' is read only
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+database.t1 analyze status Table 'database.t1' is read only
+database.t1 analyze status Engine-independent statistics collected
+database.t1 analyze status OK
+repair table t1;
+Table Op Msg_type Msg_text
+database.t1 repair Error Table 't1' is read only
+database.t1 repair status Operation failed
+optimize table t1;
+Table Op Msg_type Msg_text
+database.t1 optimize Error Table 't1' is read only
+database.t1 optimize status Operation failed
+select * from mysql.table_stats;
+db_name table_name cardinality
+database t1 10000
+#
+# Converting table back to Aria
+#
+alter table t1 engine=aria;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` varchar(1000) DEFAULT NULL,
+ KEY `a` (`a`),
+ KEY `c` (`c`)
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+select a,b from t1 limit 10;
+a b
+1 11
+2 12
+3 13
+4 14
+5 15
+6 16
+7 17
+8 18
+9 19
+10 20
+select count(*) from t1;
+count(*)
+10000
+delete from t1 where a=1;
+drop table t1;
+#
+# status
+#
+show variables like "s3%";
+Variable_name Value
+s3_access_key X
+s3_block_size X
+s3_bucket X
+s3_debug X
+s3_host_name X
+s3_pagecache_age_threshold X
+s3_pagecache_buffer_size X
+s3_pagecache_division_limit X
+s3_pagecache_file_hash_size X
+s3_port X
+s3_protocol_version X
+s3_region X
+s3_replicate_alter_as_create_select X
+s3_secret_key X
+s3_slave_ignore_updates X
+s3_use_http X
+show variables like "s3_slave%";
+Variable_name Value
+s3_slave_ignore_updates OFF
+show variables like "s3_replicate%";
+Variable_name Value
+s3_replicate_alter_as_create_select ON
+show status like "s3%";
+Variable_name Value
+S3_pagecache_blocks_not_flushed X
+S3_pagecache_blocks_unused X
+S3_pagecache_blocks_used X
+S3_pagecache_read_requests X
+S3_pagecache_reads X
diff --git a/mysql-test/suite/s3/basic.test b/mysql-test/suite/s3/basic.test
new file mode 100644
index 00000000..99c2d8ad
--- /dev/null
+++ b/mysql-test/suite/s3/basic.test
@@ -0,0 +1,88 @@
+--source include/have_s3.inc
+--source include/have_sequence.inc
+
+#
+# Create unique database for running the tests
+#
+--source create_database.inc
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+--echo #
+--echo # Test simple create of s3 table
+--echo #
+
+create or replace table t1 (a int, b int, c varchar(1000), key (a), key(c)) engine=aria;
+insert into t1 select seq, seq+10, repeat(char(65+ mod(seq, 20)),mod(seq,1000)) from seq_1_to_10000;
+alter table t1 engine=s3;
+show create table t1;
+
+--replace_column 2 # 11 # 15 # 16 # 17 # 23 #
+--replace_result $database database
+--eval select * from information_schema.tables where table_schema="$database" and table_name="t1";
+--replace_column 8 # 12 # 13 # 14 # 19 #
+show table status like "t1";
+select a,b from t1 limit 10;
+select count(*) from t1;
+select a,b from t1 where a between 10 and 20;
+--replace_column 9 #
+explain select * from t1 where a between 10 and 20;
+--error ER_OPEN_AS_READONLY
+insert into t1 values (1,1);
+--error ER_OPEN_AS_READONLY
+update t1 set b=100 where a=1;
+--error ER_OPEN_AS_READONLY
+delete from t1 where a>10;
+
+
+--echo #
+--echo # Analyze, repair, optimize and check table
+--echo #
+
+set @@use_stat_tables='never';
+truncate mysql.table_stats;
+--replace_result $database database
+check table t1 fast;
+--replace_result $database database
+check table t1 quick;
+--replace_result $database database
+check table t1 extended;
+--replace_result $database database
+analyze table t1;
+--replace_result $database database
+analyze table t1 persistent for all;
+--replace_result $database database
+repair table t1;
+--replace_result $database database
+optimize table t1;
+--replace_result $database database
+select * from mysql.table_stats;
+
+--echo #
+--echo # Converting table back to Aria
+--echo #
+
+alter table t1 engine=aria;
+show create table t1;
+select a,b from t1 limit 10;
+select count(*) from t1;
+delete from t1 where a=1;
+drop table t1;
+
+--echo #
+--echo # status
+--echo #
+
+--replace_column 2 X
+show variables like "s3%";
+show variables like "s3_slave%";
+show variables like "s3_replicate%";
+
+--replace_column 2 X
+show status like "s3%";
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/create_database.inc b/mysql-test/suite/s3/create_database.inc
new file mode 100644
index 00000000..880cdd3a
--- /dev/null
+++ b/mysql-test/suite/s3/create_database.inc
@@ -0,0 +1,10 @@
+#
+# Create unique database to not conflict with concurrently running tests as
+# the s3 database is shared
+#
+
+let $database=`select concat("s3_test_",replace(uuid(),"-",""))`;
+--disable_query_log
+--eval create database $database;
+--eval use $database;
+--enable_query_log
diff --git a/mysql-test/suite/s3/disabled.def b/mysql-test/suite/s3/disabled.def
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/mysql-test/suite/s3/disabled.def
diff --git a/mysql-test/suite/s3/discovery.result b/mysql-test/suite/s3/discovery.result
new file mode 100644
index 00000000..abc97867
--- /dev/null
+++ b/mysql-test/suite/s3/discovery.result
@@ -0,0 +1,57 @@
+drop table if exists t1,t2;
+#
+# Test discovery of s3
+#
+create table t1 (a int, b int) engine=aria select seq as a, seq+10 as b from seq_1_to_10;
+alter table t1 engine=s3;
+#
+# Check discovery by select
+#
+flush tables;
+select * from t1 limit 1;
+a b
+1 11
+#
+# Check if changes to .frm is copied to S3
+#
+alter table t1 change column b c int not null;
+flush tables;
+select * from t1 limit 1;
+a c
+1 11
+#
+# Check if SHOW TABLES finds the S3 tables
+#
+create table t2 (a int, b int) engine=aria select seq as a, seq+10 as b from seq_1_to_10;
+alter table t2 engine=s3;
+flush tables;
+SHOW TABLES;
+Tables_in_database
+t1
+t2
+drop table t2;
+#
+# Check if DROP TABLE works with discovery
+#
+select count(*) from t1;
+count(*)
+10
+flush tables;
+drop table t1;
+select count(*), sum(a) from t1;
+ERROR 42S02: Table 'database.t1' doesn't exist
+#
+# Check if S3 detects that the .frm is too old
+#
+create table t1 (a int, b int) engine=aria select seq as a, seq+10 as b from seq_1_to_10;
+alter table t1 engine=s3;
+alter table t1 add column c int, engine=s3;
+flush tables;
+select * from t1 limit 1;
+a b c
+1 11 NULL
+flush tables;
+select * from t1 limit 1;
+a b c
+1 11 NULL
+drop table t1;
diff --git a/mysql-test/suite/s3/discovery.test b/mysql-test/suite/s3/discovery.test
new file mode 100644
index 00000000..b85776ac
--- /dev/null
+++ b/mysql-test/suite/s3/discovery.test
@@ -0,0 +1,84 @@
+--source include/have_s3.inc
+--source include/have_sequence.inc
+
+#
+# Create unique database for running the tests
+#
+--source create_database.inc
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
+let $datadir=`select @@datadir`;
+
+--echo #
+--echo # Test discovery of s3
+--echo #
+
+create table t1 (a int, b int) engine=aria select seq as a, seq+10 as b from seq_1_to_10;
+alter table t1 engine=s3;
+
+--echo #
+--echo # Check discovery by select
+--echo #
+
+--remove_file $datadir/$database/t1.frm
+flush tables;
+select * from t1 limit 1;
+
+--echo #
+--echo # Check if changes to .frm is copied to S3
+--echo #
+
+alter table t1 change column b c int not null;
+flush tables;
+--remove_file $datadir/$database/t1.frm
+select * from t1 limit 1;
+
+--echo #
+--echo # Check if SHOW TABLES finds the S3 tables
+--echo #
+
+create table t2 (a int, b int) engine=aria select seq as a, seq+10 as b from seq_1_to_10;
+alter table t2 engine=s3;
+
+flush tables;
+--remove_file $datadir/$database/t1.frm
+--replace_result $database database
+SHOW TABLES;
+drop table t2;
+
+--echo #
+--echo # Check if DROP TABLE works with discovery
+--echo #
+
+select count(*) from t1;
+flush tables;
+--remove_file $datadir/$database/t1.frm
+drop table t1;
+--replace_result $database database
+--error ER_NO_SUCH_TABLE
+select count(*), sum(a) from t1;
+
+--echo #
+--echo # Check if S3 detects that the .frm is too old
+--echo #
+
+create table t1 (a int, b int) engine=aria select seq as a, seq+10 as b from seq_1_to_10;
+alter table t1 engine=s3;
+--copy_file $datadir/$database/t1.frm $datadir/$database/t1.frm-old
+alter table t1 add column c int, engine=s3;
+flush tables;
+--remove_file $datadir/$database/t1.frm
+--copy_file $datadir/$database/t1.frm-old $datadir/$database/t1.frm
+--remove_file $datadir/$database/t1.frm-old
+select * from t1 limit 1;
+flush tables;
+--remove_file $datadir/$database/t1.frm
+select * from t1 limit 1;
+drop table t1;
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/drop_database.inc b/mysql-test/suite/s3/drop_database.inc
new file mode 100644
index 00000000..a5425f4e
--- /dev/null
+++ b/mysql-test/suite/s3/drop_database.inc
@@ -0,0 +1,9 @@
+
+#
+# Drop database created by the s3 tests
+#
+
+--disable_query_log
+use test;
+--eval drop database $database;
+--enable_query_log
diff --git a/mysql-test/suite/s3/encryption.opt b/mysql-test/suite/s3/encryption.opt
new file mode 100644
index 00000000..8f13b08c
--- /dev/null
+++ b/mysql-test/suite/s3/encryption.opt
@@ -0,0 +1,4 @@
+--plugin-load-add=$FILE_KEY_MANAGEMENT_SO
+--aria-encrypt-tables=1
+--loose-file-key-management
+--loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt
diff --git a/mysql-test/suite/s3/encryption.result b/mysql-test/suite/s3/encryption.result
new file mode 100644
index 00000000..f9be4514
--- /dev/null
+++ b/mysql-test/suite/s3/encryption.result
@@ -0,0 +1,23 @@
+#
+# MDEV-20306
+# Assertion `!(end_of_data > info->scan.dir_end)' failed in
+# _ma_scan_block_record upon converting table from S3 to Aria
+# with encryption enabled
+#
+drop table if exists t1;
+CREATE TABLE t1 (a INT) ENGINE=Aria;
+INSERT INTO t1 VALUES (1);
+ALTER TABLE t1 ENGINE=S3;
+select * from t1;
+a
+1
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+ALTER TABLE t1 ENGINE=Aria;
+select * from t1;
+a
+1
+DROP TABLE t1;
diff --git a/mysql-test/suite/s3/encryption.test b/mysql-test/suite/s3/encryption.test
new file mode 100644
index 00000000..82434627
--- /dev/null
+++ b/mysql-test/suite/s3/encryption.test
@@ -0,0 +1,36 @@
+--source include/have_s3.inc
+
+if (`SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'file_key_management' AND PLUGIN_STATUS='ACTIVE'`)
+{
+ --skip Test requires file_key_management plugin
+}
+
+#
+# Create unique database for running the tests
+#
+--source create_database.inc
+
+--echo #
+--echo # MDEV-20306
+--echo # Assertion `!(end_of_data > info->scan.dir_end)' failed in
+--echo # _ma_scan_block_record upon converting table from S3 to Aria
+--echo # with encryption enabled
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT) ENGINE=Aria;
+INSERT INTO t1 VALUES (1);
+ALTER TABLE t1 ENGINE=S3;
+select * from t1;
+show create table t1;
+ALTER TABLE t1 ENGINE=Aria;
+select * from t1;
+DROP TABLE t1;
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/innodb.result b/mysql-test/suite/s3/innodb.result
new file mode 100644
index 00000000..b1aaa9cc
--- /dev/null
+++ b/mysql-test/suite/s3/innodb.result
@@ -0,0 +1,31 @@
+drop table if exists t1,t2,t3;
+#
+# Test ALTER TABLE to and from s3
+#
+create table t1 (a int, b int) engine=innodb;
+insert into t1 select seq,seq+10 from seq_1_to_1000;
+alter table t1 engine=s3;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+alter table t1 comment="hello";
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 COMMENT='hello'
+alter table t1 engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 COMMENT='hello'
+select count(*), sum(a), sum(b) from t1;
+count(*) sum(a) sum(b)
+1000 500500 510500
+drop table t1;
diff --git a/mysql-test/suite/s3/innodb.test b/mysql-test/suite/s3/innodb.test
new file mode 100644
index 00000000..e2687064
--- /dev/null
+++ b/mysql-test/suite/s3/innodb.test
@@ -0,0 +1,35 @@
+--source include/have_s3.inc
+--source include/have_sequence.inc
+--source include/have_innodb.inc
+
+#
+# Testing converting InnoDB tables to S3
+#
+
+#
+# Create unique database for running the tests
+#
+--source create_database.inc
+--disable_warnings
+drop table if exists t1,t2,t3;
+--enable_warnings
+
+--echo #
+--echo # Test ALTER TABLE to and from s3
+--echo #
+
+create table t1 (a int, b int) engine=innodb;
+insert into t1 select seq,seq+10 from seq_1_to_1000;
+alter table t1 engine=s3;
+show create table t1;
+alter table t1 comment="hello";
+show create table t1;
+alter table t1 engine=innodb;
+show create table t1;
+select count(*), sum(a), sum(b) from t1;
+drop table t1;
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/my.cnf b/mysql-test/suite/s3/my.cnf
new file mode 100644
index 00000000..f851aa18
--- /dev/null
+++ b/mysql-test/suite/s3/my.cnf
@@ -0,0 +1,33 @@
+!include include/default_mysqld.cnf
+!include include/default_client.cnf
+
+[mysqld.1]
+plugin-load-add=@ENV.HA_S3_SO
+s3=ON
+s3-host-name=@ENV.S3_HOST_NAME
+s3-protocol-version=@ENV.S3_PROTOCOL_VERSION
+s3-bucket=@ENV.S3_BUCKET
+s3-access-key=@ENV.S3_ACCESS_KEY
+s3-secret-key=@ENV.S3_SECRET_KEY
+s3-region=@ENV.S3_REGION
+s3-port=@ENV.S3_PORT
+s3-use-http=@ENV.S3_USE_HTTP
+
+#s3-host-name=s3.amazonaws.com
+#s3-protocol-version=Amazon
+#s3-bucket=MariaDB
+#s3-access-key=...
+#s3-secret-key=...
+#s3-region=eu-north-1
+
+##
+## Configuration for local MinIO
+##
+#s3-host-name="127.0.0.1"
+## Note: s3-host-name="localhost" doesn't work. It causes
+## libmarias3 to use the wrong variant of the protocol.
+#s3-bucket=storage-engine
+#s3-access-key=minio
+#s3-secret-key=minioadmin
+#s3-port=9000
+#s3-use-http=ON
diff --git a/mysql-test/suite/s3/mysqldump.result b/mysql-test/suite/s3/mysqldump.result
new file mode 100644
index 00000000..3f4c2081
--- /dev/null
+++ b/mysql-test/suite/s3/mysqldump.result
@@ -0,0 +1,64 @@
+create table t1 (pk int primary key, a int);
+insert into t1 values (1,1),(2,2),(3,3),(4,4);
+alter table t1 engine=S3;
+#####
+# mysqldump with --copy-s3-tables=0 (by default)
+###
+#####
+# mysqldump with --copy-s3-tables=0 (by default) XML
+###
+<?xml version="1.0"?>
+<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<database name="database">
+</database>
+</mysqldump>
+#####
+# mysqldump with --copy-s3-tables=1
+###
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL,
+ `a` int(11) DEFAULT NULL,
+ PRIMARY KEY (`pk`)
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t1` VALUES
+(1,1),
+(2,2),
+(3,3),
+(4,4);
+ALTER TABLE `t1` ENGINE=S3;
+#####
+# mysqldump with --copy-s3-tables=1 XML
+###
+<?xml version="1.0"?>
+<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<database name="database">
+ <table_structure name="t1">
+ <field Field="pk" Type="int(11)" Null="NO" Key="PRI" Extra="" Comment="" />
+ <field Field="a" Type="int(11)" Null="YES" Key="" Default="NULL" Extra="" Comment="" />
+ <key Table="t1" Non_unique="0" Key_name="PRIMARY" Seq_in_index="1" Column_name="pk" Collation="A" Cardinality="4" Null="" Index_type="BTREE" Comment="" Index_comment="" Ignored="NO" />
+ <options Name="t1" Engine="Aria" Version="10" Row_format="Page" Rows="4" Avg_row_length="4096" Data_length="16384" Max_data_length="17592186011648" Index_length="16384" Data_free="0" Create_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" Max_index_length="9007199254732800" Temporary="N" />
+ </table_structure>
+ <table_data name="t1">
+ <row>
+ <field name="pk">1</field>
+ <field name="a">1</field>
+ </row>
+ <row>
+ <field name="pk">2</field>
+ <field name="a">2</field>
+ </row>
+ <row>
+ <field name="pk">3</field>
+ <field name="a">3</field>
+ </row>
+ <row>
+ <field name="pk">4</field>
+ <field name="a">4</field>
+ </row>
+ </table_data>
+</database>
+</mysqldump>
+drop table t1;
diff --git a/mysql-test/suite/s3/mysqldump.test b/mysql-test/suite/s3/mysqldump.test
new file mode 100644
index 00000000..83d2310d
--- /dev/null
+++ b/mysql-test/suite/s3/mysqldump.test
@@ -0,0 +1,33 @@
+--source include/have_s3.inc
+--source create_database.inc
+
+create table t1 (pk int primary key, a int);
+insert into t1 values (1,1),(2,2),(3,3),(4,4);
+alter table t1 engine=S3;
+
+--echo #####
+--echo # mysqldump with --copy-s3-tables=0 (by default)
+--echo ###
+--exec $MYSQL_DUMP --compact $database
+--echo #####
+--echo # mysqldump with --copy-s3-tables=0 (by default) XML
+--echo ###
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{2})*/--TIME--/
+--replace_result $database database
+--exec $MYSQL_DUMP --compact -X $database
+--echo #####
+--echo # mysqldump with --copy-s3-tables=1
+--echo ###
+--exec $MYSQL_DUMP --compact --copy-s3-tables=1 $database
+--echo #####
+--echo # mysqldump with --copy-s3-tables=1 XML
+--echo ###
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{2})*/--TIME--/
+--replace_result $database database
+--exec $MYSQL_DUMP --compact --copy-s3-tables=1 -X $database
+
+drop table t1;
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/no_s3-master.opt b/mysql-test/suite/s3/no_s3-master.opt
new file mode 100644
index 00000000..ad13d335
--- /dev/null
+++ b/mysql-test/suite/s3/no_s3-master.opt
@@ -0,0 +1 @@
+--s3-bucket=storage-engine --s3-access-key="" --s3-secret-key="" --s3-region=eu-north-1
diff --git a/mysql-test/suite/s3/no_s3.result b/mysql-test/suite/s3/no_s3.result
new file mode 100644
index 00000000..9333944c
--- /dev/null
+++ b/mysql-test/suite/s3/no_s3.result
@@ -0,0 +1,11 @@
+create table t1 (a int, b int) engine=aria select seq,seq+10 from seq_1_to_2;
+alter table t1 engine=s3;
+ERROR HY000: Can't create table `test`.`t1` (errno: 138 "Unsupported extension used for table")
+drop table t1;
+select * from s3_unique_table;
+ERROR 42000: Table 's3_unique_table' uses an extension that doesn't exist in this MariaDB version
+truncate table s3_unique_table;
+ERROR 42000: Table 's3_unique_table' uses an extension that doesn't exist in this MariaDB version
+rename table s3_unique_table to t1;
+ERROR HY000: Error on rename of './test/s3_unique_table' to './test/t1' (errno: 138 "Unsupported extension used for table")
+drop table s3_unique_table;
diff --git a/mysql-test/suite/s3/no_s3.test b/mysql-test/suite/s3/no_s3.test
new file mode 100644
index 00000000..6c5df76b
--- /dev/null
+++ b/mysql-test/suite/s3/no_s3.test
@@ -0,0 +1,25 @@
+--source include/have_sequence.inc
+
+let $datadir=`select @@datadir`;
+
+if (`select @@global.s3_secret_key <> "" or @@global.s3_access_key <> ""`)
+{
+ skip S3 engine options given (probably from command line);
+}
+
+#
+# Test what happens when we don't have s3 enabled
+#
+create table t1 (a int, b int) engine=aria select seq,seq+10 from seq_1_to_2;
+--error ER_CANT_CREATE_TABLE
+alter table t1 engine=s3;
+drop table t1;
+
+--copy_file std_data/s3_unique_table.frm $datadir/test/s3_unique_table.frm
+--error ER_UNSUPPORTED_EXTENSION
+select * from s3_unique_table;
+--error ER_UNSUPPORTED_EXTENSION
+truncate table s3_unique_table;
+--error ER_ERROR_ON_RENAME
+rename table s3_unique_table to t1;
+drop table s3_unique_table;
diff --git a/mysql-test/suite/s3/partition.result b/mysql-test/suite/s3/partition.result
new file mode 100644
index 00000000..9face3ec
--- /dev/null
+++ b/mysql-test/suite/s3/partition.result
@@ -0,0 +1,164 @@
+# Test for COALESCE PARTITION, ALTER TABLE and ADD PARTITIONS
+# for tables with HASH partitions
+CREATE TABLE t1 (
+c1 INT DEFAULT NULL
+) ENGINE=Aria
+PARTITION BY HASH (c1)
+PARTITIONS 3;
+INSERT INTO t1 VALUE (1), (2), (101), (102), (201), (202);
+ALTER TABLE t1 ENGINE=S3;
+SELECT count(*) FROM t1;
+count(*)
+6
+SHOW TABLES;
+Tables_in_s3
+t1
+ALTER TABLE t1 COALESCE PARTITION 2;
+ERROR 42000: Table 't1' uses an extension that doesn't exist in this MariaDB version
+SHOW WARNINGS;
+Level Code Message
+Error 1112 Table 't1' uses an extension that doesn't exist in this MariaDB version
+ALTER TABLE t1 ADD PARTITION PARTITIONS 6;
+SELECT count(*) FROM t1;
+count(*)
+6
+ALTER TABLE t1 ADD COLUMN c INT;
+SELECT count(*) FROM t1;
+count(*)
+6
+DROP TABLE t1;
+# Test for simple change engine to S3
+CREATE TABLE t1 (
+c1 int DEFAULT NULL,
+c2 int DEFAULT NULL
+) ENGINE=Aria
+PARTITION BY RANGE (c1)
+SUBPARTITION BY HASH(c2)
+SUBPARTITIONS 2
+(PARTITION p0 VALUES LESS THAN (100),
+PARTITION p1 VALUES LESS THAN (200),
+PARTITION p3 VALUES LESS THAN (300));
+INSERT INTO t1 VALUE (1,1), (2,2), (101,101), (102,102), (201,201), (202,202);
+ALTER TABLE t1 ENGINE=S3;
+SELECT count(*) FROM t1;
+count(*)
+6
+# Test for rename table
+RENAME TABLE t1 TO t2;
+SELECT count(*) FROM t2;
+count(*)
+6
+# Test for TRUNCATE, ANALYZE, CHECK, REBUILD, OPTIMIZE, REPAIR,
+# ADD, DROP, REORGANIZE partition
+ALTER TABLE t2 TRUNCATE PARTITION p3;
+ERROR HY000: Table 't2' is read only
+ALTER TABLE t2 ANALYZE PARTITION p3;
+Table Op Msg_type Msg_text
+s3.t2 analyze status Table 's3.t2' is read only
+s3.t2 analyze status Engine-independent statistics collected
+s3.t2 analyze status OK
+SELECT count(*) FROM t2;
+count(*)
+6
+ALTER TABLE t2 CHECK PARTITION p3;
+Table Op Msg_type Msg_text
+s3.t2 check status OK
+SELECT count(*) FROM t2;
+count(*)
+6
+ALTER TABLE t2 REBUILD PARTITION p0, p1;
+ERROR 42000: Table 't2' uses an extension that doesn't exist in this MariaDB version
+ALTER TABLE t2 OPTIMIZE PARTITION p0, p1;
+Table Op Msg_type Msg_text
+s3.t2 optimize Error Table 't2' is read only
+s3.t2 optimize status Operation failed
+SELECT count(*) FROM t2;
+count(*)
+6
+ALTER TABLE t2 REPAIR PARTITION p0, p1;
+Table Op Msg_type Msg_text
+s3.t2 repair Error Table 't2' is read only
+s3.t2 repair status Operation failed
+SELECT count(*) FROM t2;
+count(*)
+6
+ALTER TABLE t2 ADD PARTITION (PARTITION p4 VALUES LESS THAN (400));
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c1` int(11) DEFAULT NULL,
+ `c2` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY RANGE (`c1`)
+SUBPARTITION BY HASH (`c2`)
+SUBPARTITIONS 2
+(PARTITION `p0` VALUES LESS THAN (100) ENGINE = S3,
+ PARTITION `p1` VALUES LESS THAN (200) ENGINE = S3,
+ PARTITION `p3` VALUES LESS THAN (300) ENGINE = S3,
+ PARTITION `p4` VALUES LESS THAN (400) ENGINE = S3)
+ALTER TABLE t2
+REORGANIZE PARTITION p4 INTO (
+PARTITION n0 VALUES LESS THAN (500),
+PARTITION n1 VALUES LESS THAN (600)
+);
+ERROR 42000: Table 't2' uses an extension that doesn't exist in this MariaDB version
+ALTER TABLE t2 DROP PARTITION p3;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c1` int(11) DEFAULT NULL,
+ `c2` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY RANGE (`c1`)
+SUBPARTITION BY HASH (`c2`)
+SUBPARTITIONS 2
+(PARTITION `p0` VALUES LESS THAN (100) ENGINE = S3,
+ PARTITION `p1` VALUES LESS THAN (200) ENGINE = S3,
+ PARTITION `p4` VALUES LESS THAN (400) ENGINE = S3)
+SELECT count(*) from t2;
+count(*)
+4
+# Test for ALTER TABLE
+ALTER TABLE t2 ADD COLUMN c INT;
+SELECT count(*) FROM t2;
+count(*)
+4
+ALTER TABLE t2 DROP COLUMN c;
+SELECT count(*) FROM t2;
+count(*)
+4
+# Test for REMOVE PARTITIONING
+ALTER TABLE t2 REMOVE PARTITIONING;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c1` int(11) DEFAULT NULL,
+ `c2` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+SELECT count(*) FROM t2;
+count(*)
+4
+DROP TABLE t2;
+# Test for EXCHANGE PARTITION
+CREATE TABLE t1 (
+c1 int DEFAULT NULL
+) ENGINE=Aria
+PARTITION BY RANGE (c1)
+(PARTITION p0 VALUES LESS THAN (100),
+PARTITION p1 VALUES LESS THAN (200));
+INSERT INTO t1 VALUE (1), (2), (101), (102);
+ALTER TABLE t1 ENGINE=S3;
+CREATE TABLE t_part (
+c1 int DEFAULT NULL
+) ENGINE=Aria;
+INSERT INTO t_part VALUE (120), (130), (140);
+ALTER TABLE t_part ENGINE=S3;
+ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t_part;
+SELECT count(*) FROM t_part;
+count(*)
+2
+SELECT count(*) FROM t1;
+count(*)
+5
+DROP TABLE t1;
+DROP TABLE t_part;
diff --git a/mysql-test/suite/s3/partition.test b/mysql-test/suite/s3/partition.test
new file mode 100644
index 00000000..03bbc2f0
--- /dev/null
+++ b/mysql-test/suite/s3/partition.test
@@ -0,0 +1,118 @@
+--source include/have_partition.inc
+--source include/have_s3.inc
+--source create_database.inc
+
+--echo # Test for COALESCE PARTITION, ALTER TABLE and ADD PARTITIONS
+--echo # for tables with HASH partitions
+CREATE TABLE t1 (
+ c1 INT DEFAULT NULL
+) ENGINE=Aria
+ PARTITION BY HASH (c1)
+ PARTITIONS 3;
+INSERT INTO t1 VALUE (1), (2), (101), (102), (201), (202);
+ALTER TABLE t1 ENGINE=S3;
+SELECT count(*) FROM t1;
+# Check that partition tables are not shown;
+--replace_result $database s3
+SHOW TABLES;
+
+--replace_result $database s3
+--error ER_UNSUPPORTED_EXTENSION
+ALTER TABLE t1 COALESCE PARTITION 2;
+--replace_result $database s3
+SHOW WARNINGS;
+ALTER TABLE t1 ADD PARTITION PARTITIONS 6;
+SELECT count(*) FROM t1;
+ALTER TABLE t1 ADD COLUMN c INT;
+SELECT count(*) FROM t1;
+DROP TABLE t1;
+
+--echo # Test for simple change engine to S3
+CREATE TABLE t1 (
+ c1 int DEFAULT NULL,
+ c2 int DEFAULT NULL
+) ENGINE=Aria
+ PARTITION BY RANGE (c1)
+ SUBPARTITION BY HASH(c2)
+ SUBPARTITIONS 2
+ (PARTITION p0 VALUES LESS THAN (100),
+ PARTITION p1 VALUES LESS THAN (200),
+ PARTITION p3 VALUES LESS THAN (300));
+
+INSERT INTO t1 VALUE (1,1), (2,2), (101,101), (102,102), (201,201), (202,202);
+ALTER TABLE t1 ENGINE=S3;
+SELECT count(*) FROM t1;
+
+--echo # Test for rename table
+RENAME TABLE t1 TO t2;
+SELECT count(*) FROM t2;
+
+--echo # Test for TRUNCATE, ANALYZE, CHECK, REBUILD, OPTIMIZE, REPAIR,
+--echo # ADD, DROP, REORGANIZE partition
+--error ER_OPEN_AS_READONLY
+ALTER TABLE t2 TRUNCATE PARTITION p3;
+--replace_result $database s3
+ALTER TABLE t2 ANALYZE PARTITION p3;
+SELECT count(*) FROM t2;
+--replace_result $database s3
+ALTER TABLE t2 CHECK PARTITION p3;
+SELECT count(*) FROM t2;
+--replace_result $database s3
+--error ER_UNSUPPORTED_EXTENSION
+ALTER TABLE t2 REBUILD PARTITION p0, p1;
+--replace_result $database s3
+ALTER TABLE t2 OPTIMIZE PARTITION p0, p1;
+SELECT count(*) FROM t2;
+--replace_result $database s3
+ALTER TABLE t2 REPAIR PARTITION p0, p1;
+SELECT count(*) FROM t2;
+--replace_result $database s3
+ALTER TABLE t2 ADD PARTITION (PARTITION p4 VALUES LESS THAN (400));
+SHOW CREATE TABLE t2;
+--replace_result $database s3
+--error ER_UNSUPPORTED_EXTENSION
+ALTER TABLE t2
+ REORGANIZE PARTITION p4 INTO (
+ PARTITION n0 VALUES LESS THAN (500),
+ PARTITION n1 VALUES LESS THAN (600)
+);
+ALTER TABLE t2 DROP PARTITION p3;
+SHOW CREATE TABLE t2;
+SELECT count(*) from t2;
+
+--echo # Test for ALTER TABLE
+ALTER TABLE t2 ADD COLUMN c INT;
+SELECT count(*) FROM t2;
+ALTER TABLE t2 DROP COLUMN c;
+SELECT count(*) FROM t2;
+
+--echo # Test for REMOVE PARTITIONING
+ALTER TABLE t2 REMOVE PARTITIONING;
+SHOW CREATE TABLE t2;
+SELECT count(*) FROM t2;
+DROP TABLE t2;
+
+--echo # Test for EXCHANGE PARTITION
+CREATE TABLE t1 (
+ c1 int DEFAULT NULL
+) ENGINE=Aria
+ PARTITION BY RANGE (c1)
+ (PARTITION p0 VALUES LESS THAN (100),
+ PARTITION p1 VALUES LESS THAN (200));
+INSERT INTO t1 VALUE (1), (2), (101), (102);
+ALTER TABLE t1 ENGINE=S3;
+CREATE TABLE t_part (
+ c1 int DEFAULT NULL
+) ENGINE=Aria;
+INSERT INTO t_part VALUE (120), (130), (140);
+ALTER TABLE t_part ENGINE=S3;
+ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t_part;
+SELECT count(*) FROM t_part;
+SELECT count(*) FROM t1;
+DROP TABLE t1;
+DROP TABLE t_part;
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/partition_create_fail.result b/mysql-test/suite/s3/partition_create_fail.result
new file mode 100644
index 00000000..923a54b5
--- /dev/null
+++ b/mysql-test/suite/s3/partition_create_fail.result
@@ -0,0 +1,15 @@
+SET @saved_dbug = @@debug_dbug;
+CREATE TABLE p0 (
+c1 int primary key,
+c2 int DEFAULT NULL
+) ENGINE=InnoDB;
+insert into p0 select seq,seq from seq_1_to_10;
+SET debug_dbug='+d,failed_create_partitioning_metadata';
+alter table p0 engine=s3
+PARTITION BY RANGE (c1)
+(PARTITION p0 VALUES LESS THAN (100));
+ERROR HY000: Simulated crash
+SET debug_dbug=@saved_dbug;
+drop table p0;
+drop table p0;
+ERROR 42S02: Unknown table 's3.p0'
diff --git a/mysql-test/suite/s3/partition_create_fail.test b/mysql-test/suite/s3/partition_create_fail.test
new file mode 100644
index 00000000..ed77a43e
--- /dev/null
+++ b/mysql-test/suite/s3/partition_create_fail.test
@@ -0,0 +1,39 @@
+--source include/have_partition.inc
+--source include/have_s3.inc
+--source include/have_debug.inc
+--source include/have_innodb.inc
+--source include/have_sequence.inc
+--source create_database.inc
+
+SET @saved_dbug = @@debug_dbug;
+
+# Test failure in create of partition table
+
+CREATE TABLE p0 (
+ c1 int primary key,
+ c2 int DEFAULT NULL
+) ENGINE=InnoDB;
+insert into p0 select seq,seq from seq_1_to_10;
+
+SET debug_dbug='+d,failed_create_partitioning_metadata';
+
+--error 1041
+alter table p0 engine=s3
+ PARTITION BY RANGE (c1)
+(PARTITION p0 VALUES LESS THAN (100));
+
+SET debug_dbug=@saved_dbug;
+
+drop table p0;
+
+# If something went wrong, then we have a copy of the .frm file in S3 and
+# the following drop table will not fail
+
+--replace_result $database s3
+--error ER_BAD_TABLE_ERROR
+drop table p0;
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/partition_move.result b/mysql-test/suite/s3/partition_move.result
new file mode 100644
index 00000000..8bd1b53e
--- /dev/null
+++ b/mysql-test/suite/s3/partition_move.result
@@ -0,0 +1,74 @@
+CREATE TABLE p0 (
+c1 int primary key,
+c2 int DEFAULT NULL
+) ENGINE=InnoDB;
+insert into p0 select seq,seq from seq_1_to_99;
+alter table p0 engine=s3 , rename to archive
+PARTITION BY RANGE (c1)
+(PARTITION p0 VALUES LESS THAN (100));
+show create table archive;
+Table Create Table
+archive CREATE TABLE `archive` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY RANGE (`c1`)
+(PARTITION `p0` VALUES LESS THAN (100) ENGINE = S3)
+CREATE TABLE t1 (
+c1 int primary key,
+c2 int DEFAULT NULL
+) ENGINE=InnoDB
+PARTITION BY RANGE (c1)
+(PARTITION p1 VALUES LESS THAN (200),
+PARTITION p2 VALUES LESS THAN (300),
+PARTITION p3 VALUES LESS THAN (400));
+insert into t1 select seq,seq from seq_100_to_399;
+create table p1 like t1;
+alter table p1 remove partitioning;
+alter table t1 exchange partition p1 with table p1;
+alter table t1 drop partition p1;
+show create table p1;
+Table Create Table
+p1 CREATE TABLE `p1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+select count(*) from p1;
+count(*)
+100
+alter table p1 engine=s3;
+alter table archive add partition (partition p1 values less than (200));
+alter table archive exchange partition p1 with table p1;
+select count(*) from p1;
+count(*)
+0
+drop table p1;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY RANGE (`c1`)
+(PARTITION `p2` VALUES LESS THAN (300) ENGINE = InnoDB,
+ PARTITION `p3` VALUES LESS THAN (400) ENGINE = InnoDB)
+show create table archive;
+Table Create Table
+archive CREATE TABLE `archive` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY RANGE (`c1`)
+(PARTITION `p0` VALUES LESS THAN (100) ENGINE = S3,
+ PARTITION `p1` VALUES LESS THAN (200) ENGINE = S3)
+select count(*) from t1;
+count(*)
+200
+select count(*) from archive;
+count(*)
+199
+drop table t1,archive;
diff --git a/mysql-test/suite/s3/partition_move.test b/mysql-test/suite/s3/partition_move.test
new file mode 100644
index 00000000..35edbd75
--- /dev/null
+++ b/mysql-test/suite/s3/partition_move.test
@@ -0,0 +1,80 @@
+--source include/have_partition.inc
+--source include/have_innodb.inc
+--source include/have_s3.inc
+--source include/have_sequence.inc
+--source create_database.inc
+
+#
+# The purpose of this test is to show how to move an partition from an existing
+# InnoDB partitioned table (t1) to a partitioned table in S3 (archive)
+#
+
+#
+# We start by creating a partioned table in S3 with one existing partion p0
+#
+
+CREATE TABLE p0 (
+ c1 int primary key,
+ c2 int DEFAULT NULL
+) ENGINE=InnoDB;
+insert into p0 select seq,seq from seq_1_to_99;
+
+alter table p0 engine=s3 , rename to archive
+ PARTITION BY RANGE (c1)
+(PARTITION p0 VALUES LESS THAN (100));
+
+show create table archive;
+
+#
+# Then we create the table t1 that contains multiple partitions.
+# Partition p1 is the one that we want to move to 'archive'
+#
+
+CREATE TABLE t1 (
+ c1 int primary key,
+ c2 int DEFAULT NULL
+) ENGINE=InnoDB
+ PARTITION BY RANGE (c1)
+ (PARTITION p1 VALUES LESS THAN (200),
+ PARTITION p2 VALUES LESS THAN (300),
+ PARTITION p3 VALUES LESS THAN (400));
+insert into t1 select seq,seq from seq_100_to_399;
+
+#
+# Then it's time to do the real work.
+#
+
+# First we move partition p1 to a normal InnoDB table
+
+create table p1 like t1;
+alter table p1 remove partitioning;
+alter table t1 exchange partition p1 with table p1;
+alter table t1 drop partition p1;
+
+show create table p1;
+select count(*) from p1;
+
+# Then change the table engine to s3 and move it into archive
+
+alter table p1 engine=s3;
+alter table archive add partition (partition p1 values less than (200));
+alter table archive exchange partition p1 with table p1;
+
+# p1 will be empty as this was the new partition that we just created
+select count(*) from p1;
+drop table p1;
+
+#
+# The p1 partition has now been moved from t1 to archive. Check the result
+#
+
+show create table t1;
+show create table archive;
+select count(*) from t1;
+select count(*) from archive;
+drop table t1,archive;
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/replication.inc b/mysql-test/suite/s3/replication.inc
new file mode 100644
index 00000000..cfa38d93
--- /dev/null
+++ b/mysql-test/suite/s3/replication.inc
@@ -0,0 +1,209 @@
+--source include/have_s3.inc
+--source include/have_sequence.inc
+
+#
+# Tests for S3 replication
+#
+
+sync_slave_with_master;
+let $SLAVE_DATADIR= `select @@datadir`;
+connection master;
+
+#
+# Create unique database for running the tests
+#
+--source create_database.inc
+
+--echo #
+--echo # Test ALTER TABLE ENGINE S3
+--echo #
+
+create table t1 (a int, b int) engine=aria;
+insert into t1 select seq,seq+10 from seq_1_to_10;
+sync_slave_with_master;
+connection master;
+alter table t1 engine=s3;
+show create table t1;
+
+sync_slave_with_master;
+--replace_result $database database
+--eval use $database
+select * from t1 limit 2;
+--file_exists $SLAVE_DATADIR/$database/t1.frm
+
+connection master;
+alter table t1 add column c int;
+
+sync_slave_with_master;
+--error 1
+--file_exists $SLAVE_DATADIR/$database/t1.frm
+--replace_result $database database
+select * from t1,t1 as t1_tmp limit 2;
+
+--echo # Now test when the .frm table is out of date on the slave
+stop slave;
+
+connection master;
+alter table t1 add column d int, engine=s3;
+connection slave;
+select * from t1 limit 2;
+start slave;
+connection master;
+sync_slave_with_master;
+select * from t1 limit 2;
+
+--echo # Same without tables in the table cache;
+stop slave;
+flush tables;
+connection master;
+alter table t1 add column e int, engine=s3;
+connection slave;
+select * from t1 limit 2;
+start slave;
+connection master;
+sync_slave_with_master;
+select * from t1 limit 2;
+connection master;
+
+--echo # Convert S3 table to Aria. Rows should be binary logged
+alter table t1 engine=aria;
+sync_slave_with_master;
+select * from t1 limit 2;
+show create table t1;
+
+--echo # Convert S3 table to Aria with rename. Rows should be binary logged
+connection master;
+alter table t1 engine=s3;
+alter table t1 rename t2, engine=aria;
+sync_slave_with_master;
+select * from t2 limit 2;
+show create table t2;
+
+connection master;
+drop table t2;
+sync_slave_with_master;
+connection master;
+
+--echo #
+--echo # Test RENAME
+--echo #
+
+create table t1 (a int, b int) engine=aria;
+insert into t1 select seq,seq+10 from seq_1_to_10;
+alter table t1 engine=s3;
+
+rename table t1 to t2;
+sync_slave_with_master;
+--replace_result $database database
+--error 1
+--file_exists $SLAVE_DATADIR/$database/t2.frm
+--error ER_NO_SUCH_TABLE
+select * from t1 limit 2;
+select * from t2 limit 2;
+connection master;
+
+alter table t2 add column f int, rename t1;
+select * from t1 limit 2;
+sync_slave_with_master;
+--error 1
+--file_exists $SLAVE_DATADIR/$database/t1.frm
+--error 1
+--file_exists $SLAVE_DATADIR/$database/t2.frm
+select * from t1 limit 2;
+--replace_result $database database
+--error ER_NO_SUCH_TABLE
+select * from t2 limit 2;
+
+# Check rename of table when a new table has replaced the original one
+
+connection slave;
+stop slave;
+connection master;
+rename table t1 to t2;
+# Check the different create options with the table
+create table t1 (a int) engine=aria;
+drop table t1;
+create table if not exists t1 (a int, b int) engine=aria;
+drop table t1;
+create or replace table t1 (a int, b int, c int) engine=aria;
+alter table t1 engine=s3;
+connection slave;
+start slave;
+connection master;
+sync_slave_with_master;
+show create table t1;
+select * from t1 limit 2;
+select * from t2 limit 2;
+connection master;
+
+--echo #
+--echo # Test DROP
+--echo #
+drop table t1,t2;
+
+sync_slave_with_master;
+--error 1
+--file_exists $SLAVE_DATADIR/$database/t1.frm
+--error 1
+--file_exists $SLAVE_DATADIR/$database/t2.frm
+--replace_result $database database
+--error ER_NO_SUCH_TABLE
+select * from t1 limit 2;
+--replace_result $database database
+--error ER_NO_SUCH_TABLE
+select * from t2 limit 2;
+
+connection master;
+
+--echo #
+--echo # Test LIKE
+--echo #
+
+create table t1 (a int,b int);
+alter table t1 engine=s3;
+--replace_result $database database
+--error ER_CANT_CREATE_TABLE
+create table t2 like t1;
+sync_slave_with_master;
+--replace_result $database database
+--error ER_NO_SUCH_TABLE
+show create table t2;
+connection master;
+--replace_result $database database
+drop table if exists t1,t2;
+
+--echo #
+--echo # Check slave binary log
+--echo #
+
+sync_slave_with_master;
+--let $binlog_database=$database
+--source include/show_binlog_events.inc
+connection master;
+
+--echo #
+--echo # MDEV-24351: S3, same-backend replication: Dropping a table on master
+--echo # causes error on slave
+--echo #
+show variables like 's3_replicate_alter_as_create_select';
+
+connection slave;
+create table t3 (a int, b int) engine=aria;
+insert into t3 values (1,1),(2,2),(3,3);
+alter table t3 engine=s3;
+
+connection master;
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+drop table t3;
+--echo # Must show "DROP TABLE IF EXISTS t3", not just "DROP TABLE t3"
+--source include/show_binlog_events.inc
+
+sync_slave_with_master;
+connection master;
+
+--echo #
+--echo # clean up
+--echo #
+--source drop_database.inc
+sync_slave_with_master;
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/s3/replication_delayed.cnf b/mysql-test/suite/s3/replication_delayed.cnf
new file mode 100644
index 00000000..9313546f
--- /dev/null
+++ b/mysql-test/suite/s3/replication_delayed.cnf
@@ -0,0 +1,3 @@
+!include ../rpl/my.cnf
+!include ./my.cnf
+!include ./slave.cnf
diff --git a/mysql-test/suite/s3/replication_delayed.result b/mysql-test/suite/s3/replication_delayed.result
new file mode 100644
index 00000000..706fcfe6
--- /dev/null
+++ b/mysql-test/suite/s3/replication_delayed.result
@@ -0,0 +1,124 @@
+include/master-slave.inc
+[connection master]
+set binlog_format=mixed;
+RESET MASTER;
+connection slave;
+set binlog_format=mixed;
+RESET MASTER;
+connection master;
+connection slave;
+use database;
+connection master;
+#
+# MDEV-23691 S3 storage engine: delayed slave can drop the table
+#
+connection slave;
+stop slave;
+connection master;
+create /*or replace*/ table t100 (
+pk varchar(100)
+) engine = 'innodb';
+insert into t100 values ('old data');
+alter table t100 engine=s3;
+drop table t100;
+create /*or replace*/ table t100 (
+pk varchar(100)
+) engine= innodb;
+insert into t100 select 'new data' from seq_1_to_10;
+alter table t100 engine=s3;
+select count(*), 'before slave start' from t100;
+count(*) before slave start
+10 before slave start
+connection slave;
+start slave;
+connection master;
+connection slave;
+connection master;
+flush tables;
+select count(*), 'after slave start' from t100;
+count(*) after slave start
+10 after slave start
+show create table t100;
+Table Create Table
+t100 CREATE TABLE `t100` (
+ `pk` varchar(100) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+connection slave;
+select count(*) from t100;
+count(*)
+10
+connection master;
+drop table t100;
+#
+# Test delayed slave with inserts
+#
+connection slave;
+stop slave;
+connection master;
+create table t1 (a int) engine=innodb;
+insert into t1 values (1),(2),(3);
+insert into t1 select * from seq_4_to_6;
+alter table t1 engine=s3;
+connection slave;
+start slave;
+connection master;
+connection slave;
+select * from t1;
+a
+1
+2
+3
+4
+5
+6
+connection master;
+drop table t1;
+#
+# Check slave binary log
+#
+connection slave;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # create database database
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create /*or replace*/ table t100 (
+pk varchar(100)
+) engine = 'innodb'
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t100 values ('old data')
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t100 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t100` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create /*or replace*/ table t100 (
+pk varchar(100)
+) engine= innodb
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t100 select 'new data' from seq_1_to_10
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t100 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; flush tables
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t100` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table t1 (a int) engine=innodb
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t1 values (1),(2),(3)
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t1 select * from seq_4_to_6
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+connection master;
+#
+# clean up
+#
+include/rpl_end.inc
diff --git a/mysql-test/suite/s3/replication_delayed.test b/mysql-test/suite/s3/replication_delayed.test
new file mode 100644
index 00000000..0ae93b85
--- /dev/null
+++ b/mysql-test/suite/s3/replication_delayed.test
@@ -0,0 +1,115 @@
+--source include/have_s3.inc
+--source include/have_innodb.inc
+--source include/have_binlog_format_mixed.inc
+--source include/master-slave.inc
+--source include/have_sequence.inc
+
+# First clear the binlog
+set binlog_format=mixed;
+RESET MASTER;
+connection slave;
+set binlog_format=mixed;
+RESET MASTER;
+connection master;
+
+#
+# Create unique database for running the tests
+#
+--source create_database.inc
+sync_slave_with_master;
+--replace_result $database database
+--eval use $database
+connection master;
+
+--echo #
+--echo # MDEV-23691 S3 storage engine: delayed slave can drop the table
+--echo #
+
+connection slave;
+stop slave;
+connection master;
+
+#
+# Create version 1 of the table
+#
+
+create /*or replace*/ table t100 (
+ pk varchar(100)
+) engine = 'innodb';
+
+insert into t100 values ('old data');
+alter table t100 engine=s3;
+
+#
+# Create version 2 of the table
+#
+drop table t100;
+create /*or replace*/ table t100 (
+ pk varchar(100)
+) engine= innodb;
+insert into t100 select 'new data' from seq_1_to_10;
+alter table t100 engine=s3;
+
+select count(*), 'before slave start' from t100;
+
+#
+# Now, start the slave
+#
+connection slave;
+start slave;
+connection master;
+sync_slave_with_master;
+#select count(*) from t100;
+connection master;
+
+flush tables;
+select count(*), 'after slave start' from t100;
+show create table t100;
+
+connection slave;
+
+select count(*) from t100;
+
+connection master;
+
+drop table t100;
+
+--echo #
+--echo # Test delayed slave with inserts
+--echo #
+
+
+# Stop slave
+
+connection slave;
+stop slave;
+connection master;
+
+# Create tables with data while slave is stopped
+create table t1 (a int) engine=innodb;
+insert into t1 values (1),(2),(3);
+insert into t1 select * from seq_4_to_6;
+alter table t1 engine=s3;
+
+connection slave;
+start slave;
+connection master;
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+
+--echo #
+--echo # Check slave binary log
+--echo #
+
+sync_slave_with_master;
+--let $binlog_database=$database
+--source include/show_binlog_events.inc
+connection master;
+
+--echo #
+--echo # clean up
+--echo #
+--source drop_database.inc
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/s3/replication_mixed.cnf b/mysql-test/suite/s3/replication_mixed.cnf
new file mode 100644
index 00000000..9313546f
--- /dev/null
+++ b/mysql-test/suite/s3/replication_mixed.cnf
@@ -0,0 +1,3 @@
+!include ../rpl/my.cnf
+!include ./my.cnf
+!include ./slave.cnf
diff --git a/mysql-test/suite/s3/replication_mixed.result b/mysql-test/suite/s3/replication_mixed.result
new file mode 100644
index 00000000..80a32b28
--- /dev/null
+++ b/mysql-test/suite/s3/replication_mixed.result
@@ -0,0 +1,300 @@
+include/master-slave.inc
+[connection master]
+set binlog_format=mixed;
+RESET MASTER;
+connection slave;
+set binlog_format=mixed;
+RESET MASTER;
+connection master;
+connection slave;
+connection master;
+#
+# Test ALTER TABLE ENGINE S3
+#
+create table t1 (a int, b int) engine=aria;
+insert into t1 select seq,seq+10 from seq_1_to_10;
+connection slave;
+connection master;
+alter table t1 engine=s3;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+connection slave;
+use database;
+select * from t1 limit 2;
+a b
+1 11
+2 12
+connection master;
+alter table t1 add column c int;
+connection slave;
+select * from t1,t1 as t1_tmp limit 2;
+a b c a b c
+1 11 NULL 1 11 NULL
+2 12 NULL 1 11 NULL
+# Now test when the .frm table is out of date on the slave
+stop slave;
+connection master;
+alter table t1 add column d int, engine=s3;
+connection slave;
+select * from t1 limit 2;
+a b c d
+1 11 NULL NULL
+2 12 NULL NULL
+start slave;
+connection master;
+connection slave;
+select * from t1 limit 2;
+a b c d
+1 11 NULL NULL
+2 12 NULL NULL
+# Same without tables in the table cache;
+stop slave;
+flush tables;
+connection master;
+alter table t1 add column e int, engine=s3;
+connection slave;
+select * from t1 limit 2;
+a b c d e
+1 11 NULL NULL NULL
+2 12 NULL NULL NULL
+start slave;
+connection master;
+connection slave;
+select * from t1 limit 2;
+a b c d e
+1 11 NULL NULL NULL
+2 12 NULL NULL NULL
+connection master;
+# Convert S3 table to Aria. Rows should be binary logged
+alter table t1 engine=aria;
+connection slave;
+select * from t1 limit 2;
+a b c d e
+1 11 NULL NULL NULL
+2 12 NULL NULL NULL
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+# Convert S3 table to Aria with rename. Rows should be binary logged
+connection master;
+alter table t1 engine=s3;
+alter table t1 rename t2, engine=aria;
+connection slave;
+select * from t2 limit 2;
+a b c d e
+1 11 NULL NULL NULL
+2 12 NULL NULL NULL
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+connection master;
+drop table t2;
+connection slave;
+connection master;
+#
+# Test RENAME
+#
+create table t1 (a int, b int) engine=aria;
+insert into t1 select seq,seq+10 from seq_1_to_10;
+alter table t1 engine=s3;
+rename table t1 to t2;
+connection slave;
+select * from t1 limit 2;
+ERROR 42S02: Table 'database.t1' doesn't exist
+select * from t2 limit 2;
+a b
+1 11
+2 12
+connection master;
+alter table t2 add column f int, rename t1;
+select * from t1 limit 2;
+a b f
+1 11 NULL
+2 12 NULL
+connection slave;
+select * from t1 limit 2;
+a b f
+1 11 NULL
+2 12 NULL
+select * from t2 limit 2;
+ERROR 42S02: Table 'database.t2' doesn't exist
+connection slave;
+stop slave;
+connection master;
+rename table t1 to t2;
+create table t1 (a int) engine=aria;
+drop table t1;
+create table if not exists t1 (a int, b int) engine=aria;
+drop table t1;
+create or replace table t1 (a int, b int, c int) engine=aria;
+alter table t1 engine=s3;
+connection slave;
+start slave;
+connection master;
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+select * from t1 limit 2;
+a b c
+select * from t2 limit 2;
+a b f
+1 11 NULL
+2 12 NULL
+connection master;
+#
+# Test DROP
+#
+drop table t1,t2;
+connection slave;
+select * from t1 limit 2;
+ERROR 42S02: Table 'database.t1' doesn't exist
+select * from t2 limit 2;
+ERROR 42S02: Table 'database.t2' doesn't exist
+connection master;
+#
+# Test LIKE
+#
+create table t1 (a int,b int);
+alter table t1 engine=s3;
+create table t2 like t1;
+ERROR HY000: Can't create table `database`.`t2` (errno: 131 "Command not supported by the engine")
+connection slave;
+show create table t2;
+ERROR 42S02: Table 'database.t2' doesn't exist
+connection master;
+drop table if exists t1,t2;
+Warnings:
+Note 1051 Unknown table 'database.t2'
+#
+# Check slave binary log
+#
+connection slave;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # create database database
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table t1 (a int, b int) engine=aria
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t1 select seq,seq+10 from seq_1_to_10
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table t1 add column c int
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table t1 add column d int, engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; flush tables
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table t1 add column e int, engine=s3
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Query # # use `database`; CREATE OR REPLACE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+slave-bin.000001 # Annotate_rows # # alter table t1 engine=aria
+slave-bin.000001 # Table_map # # table_id: # (database.t1)
+slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Query # # use `database`; CREATE OR REPLACE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+slave-bin.000001 # Annotate_rows # # alter table t1 rename t2, engine=aria
+slave-bin.000001 # Table_map # # table_id: # (database.t2)
+slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t2` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table t1 (a int, b int) engine=aria
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t1 select seq,seq+10 from seq_1_to_10
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; rename table t1 to t2
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table t2 add column f int, rename t1
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; rename table t1 to t2
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table t1 (a int) engine=aria
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table if not exists t1 (a int, b int) engine=aria
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create or replace table t1 (a int, b int, c int) engine=aria
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table t1 (a int,b int)
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by server */
+connection master;
+#
+# MDEV-24351: S3, same-backend replication: Dropping a table on master
+# causes error on slave
+#
+show variables like 's3_replicate_alter_as_create_select';
+Variable_name Value
+s3_replicate_alter_as_create_select ON
+connection slave;
+create table t3 (a int, b int) engine=aria;
+insert into t3 values (1,1),(2,2),(3,3);
+alter table t3 engine=s3;
+connection master;
+drop table t3;
+# Must show "DROP TABLE IF EXISTS t3", not just "DROP TABLE t3"
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t3` /* generated by server */
+connection slave;
+connection master;
+#
+# clean up
+#
+connection slave;
+include/rpl_end.inc
diff --git a/mysql-test/suite/s3/replication_mixed.test b/mysql-test/suite/s3/replication_mixed.test
new file mode 100644
index 00000000..d10d586d
--- /dev/null
+++ b/mysql-test/suite/s3/replication_mixed.test
@@ -0,0 +1,11 @@
+--source include/have_binlog_format_mixed.inc
+--source include/master-slave.inc
+
+set binlog_format=mixed;
+RESET MASTER;
+connection slave;
+set binlog_format=mixed;
+RESET MASTER;
+connection master;
+
+--source replication.inc
diff --git a/mysql-test/suite/s3/replication_partition.cnf b/mysql-test/suite/s3/replication_partition.cnf
new file mode 100644
index 00000000..9313546f
--- /dev/null
+++ b/mysql-test/suite/s3/replication_partition.cnf
@@ -0,0 +1,3 @@
+!include ../rpl/my.cnf
+!include ./my.cnf
+!include ./slave.cnf
diff --git a/mysql-test/suite/s3/replication_partition.result b/mysql-test/suite/s3/replication_partition.result
new file mode 100644
index 00000000..18f5ae7c
--- /dev/null
+++ b/mysql-test/suite/s3/replication_partition.result
@@ -0,0 +1,290 @@
+include/master-slave.inc
+[connection master]
+connection slave;
+use database;
+connection master;
+#
+# Check replication of parititioned S3 tables
+#
+CREATE TABLE t1 (
+c1 INT DEFAULT NULL
+) ENGINE=Aria
+PARTITION BY HASH (c1)
+PARTITIONS 3;
+INSERT INTO t1 VALUE (1), (2), (101), (102), (201), (202);
+ALTER TABLE t1 ENGINE=S3;
+connection slave;
+connection master;
+ALTER TABLE t1 ADD PARTITION PARTITIONS 6;
+select sum(c1) from t1;
+sum(c1)
+609
+connection slave;
+connection master;
+ALTER TABLE t1 ADD COLUMN c INT;
+select sum(c1) from t1;
+sum(c1)
+609
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY HASH (`c1`)
+PARTITIONS 9
+select sum(c1) from t1;
+sum(c1)
+609
+connection master;
+drop table t1;
+#
+# Checking that the slave is keeping in sync with changed partitions
+#
+CREATE TABLE t1 (
+c1 int primary key,
+c2 int DEFAULT NULL
+) ENGINE=InnoDB
+PARTITION BY RANGE (c1)
+(PARTITION p1 VALUES LESS THAN (200),
+PARTITION p2 VALUES LESS THAN (300),
+PARTITION p3 VALUES LESS THAN (400));
+insert into t1 select seq*100,seq*100 from seq_1_to_3;
+alter table t1 engine=S3;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY RANGE (`c1`)
+(PARTITION `p1` VALUES LESS THAN (200) ENGINE = S3,
+ PARTITION `p2` VALUES LESS THAN (300) ENGINE = S3,
+ PARTITION `p3` VALUES LESS THAN (400) ENGINE = S3)
+connection slave;
+select sum(c1) from t1;
+sum(c1)
+600
+stop slave;
+connection master;
+ALTER TABLE t1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (500));
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY RANGE (`c1`)
+(PARTITION `p1` VALUES LESS THAN (200) ENGINE = S3,
+ PARTITION `p2` VALUES LESS THAN (300) ENGINE = S3,
+ PARTITION `p3` VALUES LESS THAN (400) ENGINE = S3,
+ PARTITION `p4` VALUES LESS THAN (500) ENGINE = S3)
+select sum(c1) from t1;
+sum(c1)
+600
+start slave;
+connection master;
+connection slave;
+select sum(c1)+0 from t1;
+sum(c1)+0
+600
+stop slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY RANGE (`c1`)
+(PARTITION `p1` VALUES LESS THAN (200) ENGINE = S3,
+ PARTITION `p2` VALUES LESS THAN (300) ENGINE = S3,
+ PARTITION `p3` VALUES LESS THAN (400) ENGINE = S3,
+ PARTITION `p4` VALUES LESS THAN (500) ENGINE = S3)
+connection master;
+drop table t1;
+connection slave;
+select sum(c1) from t1;
+ERROR 42S02: Table 'database.t1' doesn't exist
+start slave;
+connection master;
+connection slave;
+connection master;
+#
+# Check altering partitioned table to S3 and back
+# Checks also rename partitoned table and drop partition
+#
+CREATE TABLE t2 (
+c1 int primary key,
+c2 int DEFAULT NULL
+) ENGINE=InnoDB
+PARTITION BY RANGE (c1)
+(PARTITION p1 VALUES LESS THAN (200),
+PARTITION p2 VALUES LESS THAN (300),
+PARTITION p3 VALUES LESS THAN (400));
+insert into t2 select seq*100,seq*100 from seq_1_to_3;
+alter table t2 engine=S3;
+rename table t2 to t1;
+alter table t1 drop partition p1;
+connection slave;
+select sum(c1) from t1;
+sum(c1)
+500
+connection master;
+alter table t1 engine=innodb;
+connection slave;
+select sum(c1) from t1;
+sum(c1)
+500
+connection master;
+drop table t1;
+#
+# Check that slaves ignores changes to S3 tables.
+#
+connection master;
+CREATE TABLE t1 (
+c1 int primary key,
+c2 int DEFAULT NULL
+) ENGINE=InnoDB
+PARTITION BY RANGE (c1)
+(PARTITION p1 VALUES LESS THAN (200),
+PARTITION p2 VALUES LESS THAN (300),
+PARTITION p3 VALUES LESS THAN (400));
+insert into t1 select seq*100,seq*100 from seq_1_to_3;
+create table t2 like t1;
+alter table t2 remove partitioning;
+insert into t2 values (450,450);
+connection slave;
+stop slave;
+connection master;
+alter table t1 engine=s3;
+alter table t2 engine=s3;
+ALTER TABLE t1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (500));
+alter table t1 exchange partition p4 with table t2;
+select count(*) from t1;
+count(*)
+4
+drop table t1,t2;
+connection slave;
+start slave;
+connection master;
+connection slave;
+select sum(c1) from t1;
+ERROR 42S02: Table 'database.t1' doesn't exist
+connection master;
+#
+# Check slave binary log
+#
+connection slave;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # create database database
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; CREATE TABLE t1 (
+c1 INT DEFAULT NULL
+) ENGINE=Aria
+PARTITION BY HASH (c1)
+PARTITIONS 3
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; INSERT INTO t1 VALUE (1), (2), (101), (102), (201), (202)
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; ALTER TABLE t1 ENGINE=S3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; ALTER TABLE t1 ADD PARTITION PARTITIONS 6
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; ALTER TABLE t1 ADD COLUMN c INT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; CREATE TABLE t1 (
+c1 int primary key,
+c2 int DEFAULT NULL
+) ENGINE=InnoDB
+PARTITION BY RANGE (c1)
+(PARTITION p1 VALUES LESS THAN (200),
+PARTITION p2 VALUES LESS THAN (300),
+PARTITION p3 VALUES LESS THAN (400))
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t1 select seq*100,seq*100 from seq_1_to_3
+slave-bin.000001 # Xid # # COMMIT /* XID */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=S3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; ALTER TABLE t1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (500))
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; CREATE TABLE t2 (
+c1 int primary key,
+c2 int DEFAULT NULL
+) ENGINE=InnoDB
+PARTITION BY RANGE (c1)
+(PARTITION p1 VALUES LESS THAN (200),
+PARTITION p2 VALUES LESS THAN (300),
+PARTITION p3 VALUES LESS THAN (400))
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t2 select seq*100,seq*100 from seq_1_to_3
+slave-bin.000001 # Xid # # COMMIT /* XID */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t2 engine=S3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; rename table t2 to t1
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table t1 drop partition p1
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Query # # use `database`; CREATE OR REPLACE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY RANGE (`c1`)
+(PARTITION `p2` VALUES LESS THAN (300) ENGINE = InnoDB,
+ PARTITION `p3` VALUES LESS THAN (400) ENGINE = InnoDB)
+slave-bin.000001 # Annotate_rows # # alter table t1 engine=innodb
+slave-bin.000001 # Table_map # # table_id: # (database.t1)
+slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+slave-bin.000001 # Xid # # COMMIT /* XID */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; CREATE TABLE t1 (
+c1 int primary key,
+c2 int DEFAULT NULL
+) ENGINE=InnoDB
+PARTITION BY RANGE (c1)
+(PARTITION p1 VALUES LESS THAN (200),
+PARTITION p2 VALUES LESS THAN (300),
+PARTITION p3 VALUES LESS THAN (400))
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t1 select seq*100,seq*100 from seq_1_to_3
+slave-bin.000001 # Xid # # COMMIT /* XID */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table t2 like t1
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t2 remove partitioning
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t2 values (450,450)
+slave-bin.000001 # Xid # # COMMIT /* XID */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t2 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; ALTER TABLE t1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (500))
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table t1 exchange partition p4 with table t2
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by server */
+connection master;
+#
+# clean up
+#
+connection slave;
+include/rpl_end.inc
diff --git a/mysql-test/suite/s3/replication_partition.test b/mysql-test/suite/s3/replication_partition.test
new file mode 100644
index 00000000..254924f9
--- /dev/null
+++ b/mysql-test/suite/s3/replication_partition.test
@@ -0,0 +1,170 @@
+--source include/have_s3.inc
+--source include/have_partition.inc
+--source include/have_binlog_format_mixed.inc
+--source include/have_innodb.inc
+--source include/have_sequence.inc
+--source include/master-slave.inc
+--source create_database.inc
+
+sync_slave_with_master;
+
+if (`select @@s3_slave_ignore_updates <> 1`)
+{
+ die "Slave is not configured with s3-slave-ignore-updates=1";
+}
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_result $database database
+--eval use $database
+connection master;
+
+--echo #
+--echo # Check replication of parititioned S3 tables
+--echo #
+
+CREATE TABLE t1 (
+ c1 INT DEFAULT NULL
+) ENGINE=Aria
+ PARTITION BY HASH (c1)
+ PARTITIONS 3;
+INSERT INTO t1 VALUE (1), (2), (101), (102), (201), (202);
+ALTER TABLE t1 ENGINE=S3;
+sync_slave_with_master;
+connection master;
+ALTER TABLE t1 ADD PARTITION PARTITIONS 6;
+select sum(c1) from t1;
+sync_slave_with_master;
+connection master;
+ALTER TABLE t1 ADD COLUMN c INT;
+select sum(c1) from t1;
+sync_slave_with_master;
+show create table t1;
+select sum(c1) from t1;
+connection master;
+drop table t1;
+
+--echo #
+--echo # Checking that the slave is keeping in sync with changed partitions
+--echo #
+
+CREATE TABLE t1 (
+ c1 int primary key,
+ c2 int DEFAULT NULL
+) ENGINE=InnoDB
+ PARTITION BY RANGE (c1)
+ (PARTITION p1 VALUES LESS THAN (200),
+ PARTITION p2 VALUES LESS THAN (300),
+ PARTITION p3 VALUES LESS THAN (400));
+insert into t1 select seq*100,seq*100 from seq_1_to_3;
+alter table t1 engine=S3;
+show create table t1;
+
+sync_slave_with_master;
+select sum(c1) from t1;
+--file_exists $MYSQLD_DATADIR/$database/t1.frm
+--file_exists $MYSQLD_DATADIR/$database/t1.par
+stop slave;
+connection master;
+ALTER TABLE t1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (500));
+connection slave;
+show create table t1;
+select sum(c1) from t1;
+start slave;
+connection master;
+sync_slave_with_master;
+select sum(c1)+0 from t1;
+stop slave;
+
+# Ensure the slave is using the new table
+show create table t1;
+
+connection master;
+drop table t1;
+connection slave;
+--file_exists $MYSQLD_DATADIR/$database/t1.par
+--replace_result $database database
+--error ER_NO_SUCH_TABLE
+select sum(c1) from t1;
+--error 1
+--file_exists $MYSQLD_DATADIR/$database/t1.par
+start slave;
+connection master;
+sync_slave_with_master;
+connection master;
+
+--echo #
+--echo # Check altering partitioned table to S3 and back
+--echo # Checks also rename partitoned table and drop partition
+--echo #
+
+CREATE TABLE t2 (
+ c1 int primary key,
+ c2 int DEFAULT NULL
+) ENGINE=InnoDB
+ PARTITION BY RANGE (c1)
+ (PARTITION p1 VALUES LESS THAN (200),
+ PARTITION p2 VALUES LESS THAN (300),
+ PARTITION p3 VALUES LESS THAN (400));
+insert into t2 select seq*100,seq*100 from seq_1_to_3;
+alter table t2 engine=S3;
+rename table t2 to t1;
+alter table t1 drop partition p1;
+sync_slave_with_master;
+select sum(c1) from t1;
+connection master;
+alter table t1 engine=innodb;
+sync_slave_with_master;
+select sum(c1) from t1;
+connection master;
+drop table t1;
+
+--echo #
+--echo # Check that slaves ignores changes to S3 tables.
+--echo #
+
+connection master;
+CREATE TABLE t1 (
+ c1 int primary key,
+ c2 int DEFAULT NULL
+) ENGINE=InnoDB
+ PARTITION BY RANGE (c1)
+ (PARTITION p1 VALUES LESS THAN (200),
+ PARTITION p2 VALUES LESS THAN (300),
+ PARTITION p3 VALUES LESS THAN (400));
+insert into t1 select seq*100,seq*100 from seq_1_to_3;
+create table t2 like t1;
+alter table t2 remove partitioning;
+insert into t2 values (450,450);
+sync_slave_with_master;
+stop slave;
+connection master;
+alter table t1 engine=s3;
+alter table t2 engine=s3;
+ALTER TABLE t1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (500));
+alter table t1 exchange partition p4 with table t2;
+select count(*) from t1;
+drop table t1,t2;
+connection slave;
+start slave;
+connection master;
+sync_slave_with_master;
+--replace_result $database database
+--error ER_NO_SUCH_TABLE
+select sum(c1) from t1;
+connection master;
+
+--echo #
+--echo # Check slave binary log
+--echo #
+
+sync_slave_with_master;
+--let $binlog_database=$database
+--source include/show_binlog_events.inc
+connection master;
+
+--echo #
+--echo # clean up
+--echo #
+--source drop_database.inc
+sync_slave_with_master;
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/s3/replication_stmt.cnf b/mysql-test/suite/s3/replication_stmt.cnf
new file mode 100644
index 00000000..9313546f
--- /dev/null
+++ b/mysql-test/suite/s3/replication_stmt.cnf
@@ -0,0 +1,3 @@
+!include ../rpl/my.cnf
+!include ./my.cnf
+!include ./slave.cnf
diff --git a/mysql-test/suite/s3/replication_stmt.result b/mysql-test/suite/s3/replication_stmt.result
new file mode 100644
index 00000000..4257823b
--- /dev/null
+++ b/mysql-test/suite/s3/replication_stmt.result
@@ -0,0 +1,300 @@
+include/master-slave.inc
+[connection master]
+set binlog_format=statement;
+RESET MASTER;
+connection slave;
+set binlog_format=statement;
+RESET MASTER;
+connection master;
+connection slave;
+connection master;
+#
+# Test ALTER TABLE ENGINE S3
+#
+create table t1 (a int, b int) engine=aria;
+insert into t1 select seq,seq+10 from seq_1_to_10;
+connection slave;
+connection master;
+alter table t1 engine=s3;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+connection slave;
+use database;
+select * from t1 limit 2;
+a b
+1 11
+2 12
+connection master;
+alter table t1 add column c int;
+connection slave;
+select * from t1,t1 as t1_tmp limit 2;
+a b c a b c
+1 11 NULL 1 11 NULL
+2 12 NULL 1 11 NULL
+# Now test when the .frm table is out of date on the slave
+stop slave;
+connection master;
+alter table t1 add column d int, engine=s3;
+connection slave;
+select * from t1 limit 2;
+a b c d
+1 11 NULL NULL
+2 12 NULL NULL
+start slave;
+connection master;
+connection slave;
+select * from t1 limit 2;
+a b c d
+1 11 NULL NULL
+2 12 NULL NULL
+# Same without tables in the table cache;
+stop slave;
+flush tables;
+connection master;
+alter table t1 add column e int, engine=s3;
+connection slave;
+select * from t1 limit 2;
+a b c d e
+1 11 NULL NULL NULL
+2 12 NULL NULL NULL
+start slave;
+connection master;
+connection slave;
+select * from t1 limit 2;
+a b c d e
+1 11 NULL NULL NULL
+2 12 NULL NULL NULL
+connection master;
+# Convert S3 table to Aria. Rows should be binary logged
+alter table t1 engine=aria;
+connection slave;
+select * from t1 limit 2;
+a b c d e
+1 11 NULL NULL NULL
+2 12 NULL NULL NULL
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+# Convert S3 table to Aria with rename. Rows should be binary logged
+connection master;
+alter table t1 engine=s3;
+alter table t1 rename t2, engine=aria;
+connection slave;
+select * from t2 limit 2;
+a b c d e
+1 11 NULL NULL NULL
+2 12 NULL NULL NULL
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+connection master;
+drop table t2;
+connection slave;
+connection master;
+#
+# Test RENAME
+#
+create table t1 (a int, b int) engine=aria;
+insert into t1 select seq,seq+10 from seq_1_to_10;
+alter table t1 engine=s3;
+rename table t1 to t2;
+connection slave;
+select * from t1 limit 2;
+ERROR 42S02: Table 'database.t1' doesn't exist
+select * from t2 limit 2;
+a b
+1 11
+2 12
+connection master;
+alter table t2 add column f int, rename t1;
+select * from t1 limit 2;
+a b f
+1 11 NULL
+2 12 NULL
+connection slave;
+select * from t1 limit 2;
+a b f
+1 11 NULL
+2 12 NULL
+select * from t2 limit 2;
+ERROR 42S02: Table 'database.t2' doesn't exist
+connection slave;
+stop slave;
+connection master;
+rename table t1 to t2;
+create table t1 (a int) engine=aria;
+drop table t1;
+create table if not exists t1 (a int, b int) engine=aria;
+drop table t1;
+create or replace table t1 (a int, b int, c int) engine=aria;
+alter table t1 engine=s3;
+connection slave;
+start slave;
+connection master;
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+select * from t1 limit 2;
+a b c
+select * from t2 limit 2;
+a b f
+1 11 NULL
+2 12 NULL
+connection master;
+#
+# Test DROP
+#
+drop table t1,t2;
+connection slave;
+select * from t1 limit 2;
+ERROR 42S02: Table 'database.t1' doesn't exist
+select * from t2 limit 2;
+ERROR 42S02: Table 'database.t2' doesn't exist
+connection master;
+#
+# Test LIKE
+#
+create table t1 (a int,b int);
+alter table t1 engine=s3;
+create table t2 like t1;
+ERROR HY000: Can't create table `database`.`t2` (errno: 131 "Command not supported by the engine")
+connection slave;
+show create table t2;
+ERROR 42S02: Table 'database.t2' doesn't exist
+connection master;
+drop table if exists t1,t2;
+Warnings:
+Note 1051 Unknown table 'database.t2'
+#
+# Check slave binary log
+#
+connection slave;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # create database database
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table t1 (a int, b int) engine=aria
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t1 select seq,seq+10 from seq_1_to_10
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table t1 add column c int
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table t1 add column d int, engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; flush tables
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table t1 add column e int, engine=s3
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Query # # use `database`; CREATE OR REPLACE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+slave-bin.000001 # Annotate_rows # # alter table t1 engine=aria
+slave-bin.000001 # Table_map # # table_id: # (database.t1)
+slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Query # # use `database`; CREATE OR REPLACE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
+slave-bin.000001 # Annotate_rows # # alter table t1 rename t2, engine=aria
+slave-bin.000001 # Table_map # # table_id: # (database.t2)
+slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t2` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table t1 (a int, b int) engine=aria
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t1 select seq,seq+10 from seq_1_to_10
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; rename table t1 to t2
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table t2 add column f int, rename t1
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; rename table t1 to t2
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table t1 (a int) engine=aria
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table if not exists t1 (a int, b int) engine=aria
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create or replace table t1 (a int, b int, c int) engine=aria
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table t1 (a int,b int)
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by server */
+connection master;
+#
+# MDEV-24351: S3, same-backend replication: Dropping a table on master
+# causes error on slave
+#
+show variables like 's3_replicate_alter_as_create_select';
+Variable_name Value
+s3_replicate_alter_as_create_select ON
+connection slave;
+create table t3 (a int, b int) engine=aria;
+insert into t3 values (1,1),(2,2),(3,3);
+alter table t3 engine=s3;
+connection master;
+drop table t3;
+# Must show "DROP TABLE IF EXISTS t3", not just "DROP TABLE t3"
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t3` /* generated by server */
+connection slave;
+connection master;
+#
+# clean up
+#
+connection slave;
+include/rpl_end.inc
diff --git a/mysql-test/suite/s3/replication_stmt.test b/mysql-test/suite/s3/replication_stmt.test
new file mode 100644
index 00000000..aba5d155
--- /dev/null
+++ b/mysql-test/suite/s3/replication_stmt.test
@@ -0,0 +1,11 @@
+--source include/have_binlog_format_statement.inc
+--source include/master-slave.inc
+
+set binlog_format=statement;
+RESET MASTER;
+connection slave;
+set binlog_format=statement;
+RESET MASTER;
+connection master;
+
+--source replication.inc
diff --git a/mysql-test/suite/s3/select.result b/mysql-test/suite/s3/select.result
new file mode 100644
index 00000000..94a6fdf1
--- /dev/null
+++ b/mysql-test/suite/s3/select.result
@@ -0,0 +1,8 @@
+create table t1 (pk int primary key, a int);
+insert into t1 values (1,1),(2,2),(3,3),(4,4);
+alter table t1 engine=S3;
+select a from t1 where pk in (2, 3);
+a
+2
+3
+drop table t1;
diff --git a/mysql-test/suite/s3/select.test b/mysql-test/suite/s3/select.test
new file mode 100644
index 00000000..223311cb
--- /dev/null
+++ b/mysql-test/suite/s3/select.test
@@ -0,0 +1,17 @@
+--source include/have_s3.inc
+--source create_database.inc
+
+#
+# MDEV-19465 Server crashes in s3_block_read upon IN quer
+#
+
+create table t1 (pk int primary key, a int);
+insert into t1 values (1,1),(2,2),(3,3),(4,4);
+alter table t1 engine=S3;
+select a from t1 where pk in (2, 3);
+drop table t1;
+
+#
+# clean up
+#
+--source drop_database.inc
diff --git a/mysql-test/suite/s3/slave.cnf b/mysql-test/suite/s3/slave.cnf
new file mode 100644
index 00000000..4f4d3d39
--- /dev/null
+++ b/mysql-test/suite/s3/slave.cnf
@@ -0,0 +1,34 @@
+[mysqld.2]
+plugin-load-add=@ENV.HA_S3_SO
+s3=ON
+s3-slave-ignore-updates=1
+s3-host-name=@ENV.S3_HOST_NAME
+s3-protocol-version=@ENV.S3_PROTOCOL_VERSION
+s3-bucket=@ENV.S3_BUCKET
+s3-access-key=@ENV.S3_ACCESS_KEY
+s3-secret-key=@ENV.S3_SECRET_KEY
+s3-region=@ENV.S3_REGION
+s3-port=@ENV.S3_PORT
+s3-use-http=@ENV.S3_USE_HTTP
+
+# You can change the following when running the tests against
+# your own S3 setup
+
+#s3-host-name=s3.amazonaws.com
+#s3-protocol-version=Amazon
+#s3-bucket=MariaDB
+#s3-access-key=...
+#s3-secret-key=...
+#s3-region=eu-north-1
+
+##
+## Configuration for local MinIO
+##
+#s3-host-name="127.0.0.1"
+## Note: s3-host-name="localhost" doesn't work. It causes
+## libmarias3 to use the wrong variant of the protocol.
+#s3-bucket=storage-engine
+#s3-access-key=minio
+#s3-secret-key=minioadmin
+#s3-port=9000
+#s3-use-http=ON
diff --git a/mysql-test/suite/s3/suite.pm b/mysql-test/suite/s3/suite.pm
new file mode 100644
index 00000000..cdefbc5e
--- /dev/null
+++ b/mysql-test/suite/s3/suite.pm
@@ -0,0 +1,67 @@
+package My::Suite::S3;
+
+use Socket;
+
+@ISA = qw(My::Suite);
+
+return "Need S3 engine" unless $::mysqld_variables{'s3'} eq "ON" or $ENV{HA_S3_SO};
+
+my $paddr = sockaddr_in(9000, INADDR_ANY);
+my $protocol = getprotobyname("tcp");
+socket(SOCK, PF_INET, SOCK_STREAM, $protocol);
+
+if(connect(SOCK, $paddr))
+{
+ $ENV{'S3_HOST_NAME'} = "127.0.0.1";
+ $ENV{'S3_PORT'} = 9000;
+ $ENV{'S3_BUCKET'} = "storage-engine";
+ $ENV{'S3_ACCESS_KEY'} = "minio";
+ $ENV{'S3_SECRET_KEY'} = "minioadmin";
+ $ENV{'S3_REGION'} = "";
+ $ENV{'S3_PROTOCOL_VERSION'} = "Auto";
+ $ENV{'S3_USE_HTTP'} = "ON";
+}
+else
+{
+ if (!$ENV{'S3_HOST_NAME'})
+ {
+ $ENV{'S3_HOST_NAME'} = "s3.amazonaws.com";
+ }
+
+ if (!$ENV{'S3_BUCKET'})
+ {
+ $ENV{'S3_BUCKET'} = "MariaDB";
+ }
+
+ if (!$ENV{'S3_REGION'})
+ {
+ $ENV{'S3_REGION'} = "";
+ }
+
+ if (!$ENV{'S3_ACCESS_KEY'})
+ {
+ return "Environment variable S3_ACCESS_KEY need to be set";
+ }
+
+ if (!$ENV{'S3_SECRET_KEY'})
+ {
+ return "Environment variable S3_SECRET_KEY need to be set";
+ }
+
+ if (!$ENV{'S3_PROTOCOL_VERSION'})
+ {
+ $ENV{'S3_PROTOCOL_VERSION'} = "Auto";
+ }
+
+ if (!$ENV{'S3_PORT'})
+ {
+ $ENV{'S3_PORT'} = 0;
+ }
+
+ if (!$ENV{'S3_USE_HTTP'})
+ {
+ $ENV{'S3_USE_HTTP'} = "OFF";
+ }
+}
+bless { };
+
diff --git a/mysql-test/suite/s3/unsupported.result b/mysql-test/suite/s3/unsupported.result
new file mode 100644
index 00000000..e12b57af
--- /dev/null
+++ b/mysql-test/suite/s3/unsupported.result
@@ -0,0 +1,15 @@
+create sequence s1;
+alter table s1 engine=s3;
+ERROR HY000: Can't create table `database`.`s1` (errno: 138 "Unsupported extension used for table")
+drop sequence s1;
+create temporary table t1 (a int);
+alter table t1 engine=S3;
+ERROR HY000: Can't create table `database`.`t1` (errno: 131 "Command not supported by the engine")
+drop temporary table t1;
+#
+# CREATE of S3 table
+#
+create or replace table t1 (a int, b int, key (a)) engine=S3;
+ERROR HY000: Can't create table `database`.`t1` (errno: 131 "Command not supported by the engine")
+select * from t1;
+ERROR 42S02: Table 'database.t1' doesn't exist
diff --git a/mysql-test/suite/s3/unsupported.test b/mysql-test/suite/s3/unsupported.test
new file mode 100644
index 00000000..dbc9584e
--- /dev/null
+++ b/mysql-test/suite/s3/unsupported.test
@@ -0,0 +1,43 @@
+--source include/have_s3.inc
+--source create_database.inc
+
+#
+# Test unsupported features in S3
+#
+#
+
+#
+# MDEV-19463 Altering sequence to S3 leaves unremovable garbage behind
+#
+
+create sequence s1;
+--replace_result $database database
+--error ER_CANT_CREATE_TABLE
+alter table s1 engine=s3;
+drop sequence s1;
+
+#
+# MDEV-19461 Assertion failure upon altering temporary S3 table
+#
+
+create temporary table t1 (a int);
+--replace_result $database database
+--error ER_CANT_CREATE_TABLE
+alter table t1 engine=S3;
+drop temporary table t1;
+
+--echo #
+--echo # CREATE of S3 table
+--echo #
+
+--replace_result $database database
+--error ER_CANT_CREATE_TABLE
+create or replace table t1 (a int, b int, key (a)) engine=S3;
+--replace_result $database database
+--error ER_NO_SUCH_TABLE
+select * from t1;
+
+#
+# clean up
+#
+--source drop_database.inc