mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge 10.1 into 10.2
This commit is contained in:
@@ -567,7 +567,8 @@ is_page_corrupted(
|
|||||||
page_size);
|
page_size);
|
||||||
if (is_corrupted && log_file) {
|
if (is_corrupted && log_file) {
|
||||||
fprintf(log_file,
|
fprintf(log_file,
|
||||||
"Page " ULINTPF ":%llu may be corrupted;"
|
"[page id: space=" ULINTPF
|
||||||
|
", page_number=%llu] may be corrupted;"
|
||||||
" key_version=%u\n",
|
" key_version=%u\n",
|
||||||
space_id, cur_page_num,
|
space_id, cur_page_num,
|
||||||
mach_read_from_4(
|
mach_read_from_4(
|
||||||
|
@@ -55,12 +55,19 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */
|
|||||||
#endif /* HAVE_VALGRIND_MEMCHECK_H */
|
#endif /* HAVE_VALGRIND_MEMCHECK_H */
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
|
/* NOTE: Do not invoke TRASH_FILL directly! Use TRASH_ALLOC or TRASH_FREE.
|
||||||
|
|
||||||
|
The MEM_UNDEFINED() call before memset() is for canceling the effect
|
||||||
|
of any previous MEM_NOACCESS(). We must invoke MEM_UNDEFINED() after
|
||||||
|
writing the dummy pattern, unless MEM_NOACCESS() is going to be invoked.
|
||||||
|
On AddressSanitizer, the MEM_UNDEFINED() in TRASH_ALLOC() has no effect. */
|
||||||
#define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); MEM_UNDEFINED(A, trash_tmp); memset(A, C, trash_tmp); } while (0)
|
#define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); MEM_UNDEFINED(A, trash_tmp); memset(A, C, trash_tmp); } while (0)
|
||||||
#else
|
#else
|
||||||
#define TRASH_FILL(A,B,C) do { MEM_UNDEFINED((A), (B)); } while (0)
|
#define TRASH_FILL(A,B,C) do { MEM_UNDEFINED((A), (B)); } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
/** Note that some memory became allocated or uninitialized. */
|
||||||
#define TRASH_ALLOC(A,B) do { TRASH_FILL(A,B,0xA5); MEM_UNDEFINED(A,B); } while(0)
|
#define TRASH_ALLOC(A,B) do { TRASH_FILL(A,B,0xA5); MEM_UNDEFINED(A,B); } while(0)
|
||||||
|
/** Note that some memory became freed. (Prohibit further access to it.) */
|
||||||
#define TRASH_FREE(A,B) do { TRASH_FILL(A,B,0x8F); MEM_NOACCESS(A,B); } while(0)
|
#define TRASH_FREE(A,B) do { TRASH_FILL(A,B,0x8F); MEM_NOACCESS(A,B); } while(0)
|
||||||
|
|
||||||
#endif /* MY_VALGRIND_INCLUDED */
|
#endif /* MY_VALGRIND_INCLUDED */
|
||||||
|
@@ -60,7 +60,7 @@ In the file, put a set of SQL statements that create some tables,
|
|||||||
load test data, and run some queries to manipulate it.
|
load test data, and run some queries to manipulate it.
|
||||||
|
|
||||||
Your test should begin by dropping the tables you are going to create and
|
Your test should begin by dropping the tables you are going to create and
|
||||||
end by dropping them again. This ensures that you can run the test over
|
end by dropping them again. This ensures that you can run the test over
|
||||||
and over again.
|
and over again.
|
||||||
|
|
||||||
If you are using mysqltest commands in your test case, you should create
|
If you are using mysqltest commands in your test case, you should create
|
||||||
@@ -81,7 +81,7 @@ comments, you can create the result file in one of the following ways:
|
|||||||
|
|
||||||
# mysqltest --record --database test --result-file=r/test_case_name.result < t/test_case_name.test
|
# mysqltest --record --database test --result-file=r/test_case_name.result < t/test_case_name.test
|
||||||
|
|
||||||
When this is done, take a look at r/test_case_name.result .
|
When this is done, take a look at r/test_case_name.result.
|
||||||
If the result is incorrect, you have found a bug. In this case, you should
|
If the result is incorrect, you have found a bug. In this case, you should
|
||||||
edit the test result to the correct results so that we can verify that
|
edit the test result to the correct results so that we can verify that
|
||||||
the bug is corrected in future releases.
|
the bug is corrected in future releases.
|
||||||
|
@@ -2710,6 +2710,8 @@ Warnings:
|
|||||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. CREATE... REPLACE SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. CREATE... REPLACE SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave
|
||||||
INSERT INTO insert_2_keys VALUES (1, 2)
|
INSERT INTO insert_2_keys VALUES (1, 2)
|
||||||
ON DUPLICATE KEY UPDATE a=VALUES(a)+10, b=VALUES(b)+10;
|
ON DUPLICATE KEY UPDATE a=VALUES(a)+10, b=VALUES(b)+10;
|
||||||
|
Warnings:
|
||||||
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||||
DROP TABLE filler_table;
|
DROP TABLE filler_table;
|
||||||
DROP TABLE insert_table;
|
DROP TABLE insert_table;
|
||||||
DROP TABLE update_table;
|
DROP TABLE update_table;
|
||||||
|
@@ -15,3 +15,4 @@ rpl_get_master_version_and_clock : Bug#11766137 Jan 05 2011 joro Valgrind warnin
|
|||||||
rpl_partition_archive : MDEV-5077 2013-09-27 svoj Cannot exchange partition with archive table
|
rpl_partition_archive : MDEV-5077 2013-09-27 svoj Cannot exchange partition with archive table
|
||||||
rpl_row_binlog_max_cache_size : MDEV-11092
|
rpl_row_binlog_max_cache_size : MDEV-11092
|
||||||
rpl_row_index_choice : MDEV-11666
|
rpl_row_index_choice : MDEV-11666
|
||||||
|
rpl_mdev_17614 : MDEV-17614/MDEV-17073 Unexpected lock conflict
|
||||||
|
20
mysql-test/suite/rpl/r/rpl_create_or_replace_fail.result
Normal file
20
mysql-test/suite/rpl/r/rpl_create_or_replace_fail.result
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
include/master-slave.inc
|
||||||
|
[connection master]
|
||||||
|
CREATE TEMPORARY TABLE t1 (a INT NOT NULL);
|
||||||
|
LOAD DATA INFILE 'x' INTO TABLE x;
|
||||||
|
ERROR 42S02: Table 'test.x' doesn't exist
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE t1 (x INT) PARTITION BY HASH(x);
|
||||||
|
ERROR HY000: Cannot create temporary table with partitions
|
||||||
|
"************** DROP TEMPORARY TABLE Should be present in Binary log **************"
|
||||||
|
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 `test`; CREATE TEMPORARY TABLE t1 (a INT NOT NULL)
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TEMPORARY TABLE t1 (x INT) PARTITION BY HASH(x)
|
||||||
|
CREATE TABLE t1 (b INT);
|
||||||
|
INSERT INTO t1 VALUES (NULL);
|
||||||
|
connection slave;
|
||||||
|
connection master;
|
||||||
|
DROP TABLE t1;
|
||||||
|
include/rpl_end.inc
|
@@ -1,31 +1,5 @@
|
|||||||
call mtr.add_suppression("Unsafe statement written to the binary log using statement format");
|
call mtr.add_suppression("Unsafe statement written to the binary log using statement format");
|
||||||
include/master-slave.inc
|
include/master-slave.inc
|
||||||
[connection master]
|
|
||||||
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
|
|
||||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT,
|
|
||||||
UNIQUE(b));
|
|
||||||
connection slave;
|
|
||||||
connection master;
|
|
||||||
INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
a b
|
|
||||||
1 10
|
|
||||||
2 2
|
|
||||||
connection slave;
|
|
||||||
call mtr.add_suppression("Slave SQL.*suffer.*http:..bugs.mysql.com.bug.php.id=24432");
|
|
||||||
include/wait_for_slave_sql_error.inc [errno=1105]
|
|
||||||
Last_SQL_Error = 'Error 'master may suffer from http://bugs.mysql.com/bug.php?id=24432 so slave stops; check error log on slave for more info' on query. Default database: 'test'. Query: 'INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10''
|
|
||||||
SELECT * FROM t1;
|
|
||||||
a b
|
|
||||||
stop slave;
|
|
||||||
include/wait_for_slave_to_stop.inc
|
|
||||||
reset slave;
|
|
||||||
connection master;
|
|
||||||
reset master;
|
|
||||||
drop table t1;
|
|
||||||
connection slave;
|
|
||||||
start slave;
|
|
||||||
include/wait_for_slave_to_start.inc
|
|
||||||
connection master;
|
connection master;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
id bigint(20) unsigned NOT NULL auto_increment,
|
id bigint(20) unsigned NOT NULL auto_increment,
|
||||||
|
98
mysql-test/suite/rpl/r/rpl_mdev_17614.result
Normal file
98
mysql-test/suite/rpl/r/rpl_mdev_17614.result
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
include/master-slave.inc
|
||||||
|
[connection master]
|
||||||
|
call mtr.add_suppression("Unsafe statement written to the binary log using statement format");
|
||||||
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY , b INT,
|
||||||
|
UNIQUE(b), c int) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES (1, 1, 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
Warnings:
|
||||||
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||||
|
INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
Warnings:
|
||||||
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
1 1 2
|
||||||
|
2 2 3
|
||||||
|
include/wait_for_slave_sql_error.inc [errno=1062]
|
||||||
|
Last_SQL_Error = 'Error 'Duplicate entry '1' for key 'b'' on query. Default database: 'test'. Query: 'INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c)''
|
||||||
|
#Different value from server
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
1 1 1
|
||||||
|
2 2 3
|
||||||
|
stop slave;
|
||||||
|
include/wait_for_slave_to_stop.inc
|
||||||
|
reset slave;
|
||||||
|
reset master;
|
||||||
|
drop table t1;
|
||||||
|
start slave;
|
||||||
|
include/wait_for_slave_to_start.inc
|
||||||
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||||
|
UNIQUE(b), c int) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES (default, 1, 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES (default, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
INSERT INTO t1 VALUES(default, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
1 1 2
|
||||||
|
3 2 3
|
||||||
|
#same data as master
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
1 1 2
|
||||||
|
3 2 3
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
||||||
|
UNIQUE(b), c int, d int ) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES (1, 1, 1, 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES (2, NULL, 2, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
Warnings:
|
||||||
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||||
|
INSERT INTO t1 VALUES(3, NULL, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
Warnings:
|
||||||
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c d
|
||||||
|
1 1 1 1
|
||||||
|
2 NULL 2 2
|
||||||
|
3 NULL 2 3
|
||||||
|
#same data as master
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c d
|
||||||
|
1 1 1 1
|
||||||
|
2 NULL 2 2
|
||||||
|
3 NULL 2 3
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||||
|
UNIQUE(b), c int) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES (1, 1, 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
1 1 2
|
||||||
|
2 2 3
|
||||||
|
include/wait_for_slave_sql_error.inc [errno=1062]
|
||||||
|
Last_SQL_Error = 'Error 'Duplicate entry '1' for key 'b'' on query. Default database: 'test'. Query: 'INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c)''
|
||||||
|
#Different value from server
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
1 1 1
|
||||||
|
2 2 3
|
||||||
|
stop slave;
|
||||||
|
include/wait_for_slave_to_stop.inc
|
||||||
|
reset slave;
|
||||||
|
reset master;
|
||||||
|
drop table t1;
|
||||||
|
start slave;
|
||||||
|
include/wait_for_slave_to_start.inc
|
||||||
|
include/rpl_end.inc
|
18
mysql-test/suite/rpl/r/rpl_sync_with_innodb_thd_conc.result
Normal file
18
mysql-test/suite/rpl/r/rpl_sync_with_innodb_thd_conc.result
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
include/master-slave.inc
|
||||||
|
[connection master]
|
||||||
|
connection slave;
|
||||||
|
SET @old_innodb_thread_concurrency := @@innodb_thread_concurrency;
|
||||||
|
SET @old_innodb_thread_sleep_delay := @@innodb_thread_sleep_delay;
|
||||||
|
SET GLOBAL innodb_thread_concurrency = 100;
|
||||||
|
connection master;
|
||||||
|
CREATE TABLE t(f INT) ENGINE=INNODB;
|
||||||
|
INSERT INTO t VALUES (10);
|
||||||
|
connection slave;
|
||||||
|
include/diff_tables.inc [master:t, slave:t]
|
||||||
|
"===== Clean up======="
|
||||||
|
connection master;
|
||||||
|
DROP TABLE t;
|
||||||
|
connection slave;
|
||||||
|
SET GLOBAL innodb_thread_concurrency = @old_innodb_thread_concurrency;
|
||||||
|
SET GLOBAL innodb_thread_sleep_delay = @old_innodb_thread_sleep_delay;
|
||||||
|
include/rpl_end.inc
|
@@ -1,5 +1,6 @@
|
|||||||
include/master-slave.inc
|
include/master-slave.inc
|
||||||
[connection master]
|
[connection master]
|
||||||
|
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
|
||||||
CREATE TABLE t1(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB;
|
CREATE TABLE t1(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB;
|
||||||
CREATE TABLE t2(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB;
|
CREATE TABLE t2(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB;
|
||||||
CREATE TRIGGER trig1 AFTER INSERT ON t1
|
CREATE TRIGGER trig1 AFTER INSERT ON t1
|
||||||
@@ -49,9 +50,13 @@ connection master;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1(i INT, j INT, UNIQUE KEY(i), UNIQUE KEY(j)) ENGINE=INNODB;
|
CREATE TABLE t1(i INT, j INT, UNIQUE KEY(i), UNIQUE KEY(j)) ENGINE=INNODB;
|
||||||
INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1;
|
INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1;
|
||||||
|
Warnings:
|
||||||
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||||
START TRANSACTION;
|
START TRANSACTION;
|
||||||
LOCK TABLES t1 WRITE;
|
LOCK TABLES t1 WRITE;
|
||||||
INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1;
|
INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1;
|
||||||
|
Warnings:
|
||||||
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
connection slave;
|
connection slave;
|
||||||
|
56
mysql-test/suite/rpl/t/rpl_create_or_replace_fail.test
Normal file
56
mysql-test/suite/rpl/t/rpl_create_or_replace_fail.test
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# ==== Purpose ====
|
||||||
|
#
|
||||||
|
# Test verifies that failed CREATE OR REPLACE TEMPORARY TABLE statement which
|
||||||
|
# dropped the table but failed at a later stage of creation of temporary table
|
||||||
|
# is written to binarylog in row based replication.
|
||||||
|
#
|
||||||
|
# ==== Implementation ====
|
||||||
|
#
|
||||||
|
# Steps:
|
||||||
|
# 0 - Have mixed based replication mode.
|
||||||
|
# 1 - Create a temporary table. It will be replicated as mixed replication
|
||||||
|
# mode is in use.
|
||||||
|
# 2 - Execute an unsafe statement which will switch current statement
|
||||||
|
# binlog format to 'ROW'. i.e If binlog_format=MIXED, there are open
|
||||||
|
# temporary tables, and an unsafe statement is executed, then subsequent
|
||||||
|
# statements are logged in row format.
|
||||||
|
# 3 - Execute a CREATE OR REPLACE TEMPORARY TABLE statement which tries to
|
||||||
|
# create partitions on temporary table. Since it is not supported it will
|
||||||
|
# fail.
|
||||||
|
# 4 - Check the binary log output to ensure that the failed statement is
|
||||||
|
# written to the binary log.
|
||||||
|
# 5 - Slave should be up and running and in sync with master.
|
||||||
|
#
|
||||||
|
# ==== References ====
|
||||||
|
#
|
||||||
|
# MDEV-18930: Failed CREATE OR REPLACE TEMPORARY not written into binary log
|
||||||
|
# makes data on master and slave diverge
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/have_partition.inc
|
||||||
|
--source include/have_binlog_format_mixed.inc
|
||||||
|
--source include/master-slave.inc
|
||||||
|
|
||||||
|
CREATE TEMPORARY TABLE t1 (a INT NOT NULL);
|
||||||
|
|
||||||
|
# Execute an unsafe statement which switches replication mode internally from
|
||||||
|
# "STATEMENT" to "ROW".
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
LOAD DATA INFILE 'x' INTO TABLE x;
|
||||||
|
|
||||||
|
--error ER_PARTITION_NO_TEMPORARY
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE t1 (x INT) PARTITION BY HASH(x);
|
||||||
|
|
||||||
|
--echo "************** DROP TEMPORARY TABLE Should be present in Binary log **************"
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
CREATE TABLE t1 (b INT);
|
||||||
|
INSERT INTO t1 VALUES (NULL);
|
||||||
|
--sync_slave_with_master
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
--connection master
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--source include/rpl_end.inc
|
||||||
|
|
@@ -14,45 +14,6 @@ source include/have_binlog_checksum_off.inc;
|
|||||||
|
|
||||||
source include/master-slave.inc;
|
source include/master-slave.inc;
|
||||||
|
|
||||||
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
|
|
||||||
|
|
||||||
#
|
|
||||||
# This is to test that slave properly detects if
|
|
||||||
# master may suffer from:
|
|
||||||
# BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values"
|
|
||||||
# (i.e. on master, INSERT ON DUPLICATE KEY UPDATE is used and manipulates
|
|
||||||
# an auto_increment column, and is binlogged statement-based).
|
|
||||||
#
|
|
||||||
|
|
||||||
# testcase with INSERT VALUES
|
|
||||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT,
|
|
||||||
UNIQUE(b));
|
|
||||||
sync_slave_with_master;
|
|
||||||
connection master;
|
|
||||||
INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
connection slave;
|
|
||||||
|
|
||||||
# show the error message
|
|
||||||
#1105 = ER_UNKNOWN_ERROR
|
|
||||||
--let $slave_sql_errno= 1105
|
|
||||||
--let $show_slave_sql_error= 1
|
|
||||||
call mtr.add_suppression("Slave SQL.*suffer.*http:..bugs.mysql.com.bug.php.id=24432");
|
|
||||||
--source include/wait_for_slave_sql_error.inc
|
|
||||||
# show that it was not replicated
|
|
||||||
SELECT * FROM t1;
|
|
||||||
|
|
||||||
# restart replication for the next testcase
|
|
||||||
stop slave;
|
|
||||||
--source include/wait_for_slave_to_stop.inc
|
|
||||||
reset slave;
|
|
||||||
connection master;
|
|
||||||
reset master;
|
|
||||||
drop table t1;
|
|
||||||
connection slave;
|
|
||||||
start slave;
|
|
||||||
--source include/wait_for_slave_to_start.inc
|
|
||||||
|
|
||||||
# testcase with INSERT SELECT
|
# testcase with INSERT SELECT
|
||||||
connection master;
|
connection master;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
|
121
mysql-test/suite/rpl/t/rpl_mdev_17614.test
Normal file
121
mysql-test/suite/rpl/t/rpl_mdev_17614.test
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
source include/have_debug.inc;
|
||||||
|
source include/have_innodb.inc;
|
||||||
|
-- source include/have_binlog_format_statement.inc
|
||||||
|
source include/master-slave.inc;
|
||||||
|
# MDEV-17614
|
||||||
|
# INSERT on dup key update is replication unsafe
|
||||||
|
# There can be three case
|
||||||
|
# 1. 2 unique key, Replication is unsafe.
|
||||||
|
# 2. 2 unique key , with one auto increment key, Safe to replicate because Innodb will acquire gap lock
|
||||||
|
# 3. n no of unique keys (n>1) but insert is only in 1 unique key
|
||||||
|
# 4. 2 unique key , with one auto increment key(but user gives auto inc value), unsafe to replicate
|
||||||
|
|
||||||
|
# Case 1
|
||||||
|
call mtr.add_suppression("Unsafe statement written to the binary log using statement format");
|
||||||
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY , b INT,
|
||||||
|
UNIQUE(b), c int) engine=innodb;
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection master;
|
||||||
|
INSERT INTO t1 VALUES (1, 1, 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
--connection master1
|
||||||
|
INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
--connection master
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--connection slave
|
||||||
|
# show the error message
|
||||||
|
--let $slave_sql_errno= 1062
|
||||||
|
--let $show_slave_sql_error= 1
|
||||||
|
--source include/wait_for_slave_sql_error.inc
|
||||||
|
--echo #Different value from server
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
# restart replication for the next testcase
|
||||||
|
stop slave;
|
||||||
|
--source include/wait_for_slave_to_stop.inc
|
||||||
|
reset slave;
|
||||||
|
connection master;
|
||||||
|
reset master;
|
||||||
|
drop table t1;
|
||||||
|
connection slave;
|
||||||
|
start slave;
|
||||||
|
--source include/wait_for_slave_to_start.inc
|
||||||
|
# Case 2
|
||||||
|
--connection master
|
||||||
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||||
|
UNIQUE(b), c int) engine=innodb;
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection master;
|
||||||
|
INSERT INTO t1 VALUES (default, 1, 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES (default, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
--connection master1
|
||||||
|
INSERT INTO t1 VALUES(default, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
--connection master
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--sync_slave_with_master
|
||||||
|
--echo #same data as master
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
drop table t1;
|
||||||
|
--sync_slave_with_master
|
||||||
|
|
||||||
|
# Case 3
|
||||||
|
--connection master
|
||||||
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
||||||
|
UNIQUE(b), c int, d int ) engine=innodb;
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection master;
|
||||||
|
INSERT INTO t1 VALUES (1, 1, 1, 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES (2, NULL, 2, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
--connection master1
|
||||||
|
INSERT INTO t1 VALUES(3, NULL, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
--connection master
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--sync_slave_with_master
|
||||||
|
--echo #same data as master
|
||||||
|
SELECT * FROM t1;
|
||||||
|
connection master;
|
||||||
|
drop table t1;
|
||||||
|
--sync_slave_with_master
|
||||||
|
|
||||||
|
# Case 4
|
||||||
|
--connection master
|
||||||
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||||
|
UNIQUE(b), c int) engine=innodb;
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection master;
|
||||||
|
INSERT INTO t1 VALUES (1, 1, 1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
--connection master1
|
||||||
|
INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||||
|
--connection master
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--connection slave
|
||||||
|
# show the error message
|
||||||
|
--let $slave_sql_errno= 1062
|
||||||
|
--let $show_slave_sql_error= 1
|
||||||
|
--source include/wait_for_slave_sql_error.inc
|
||||||
|
--echo #Different value from server
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
# restart replication for the next testcase
|
||||||
|
stop slave;
|
||||||
|
--source include/wait_for_slave_to_stop.inc
|
||||||
|
reset slave;
|
||||||
|
connection master;
|
||||||
|
reset master;
|
||||||
|
drop table t1;
|
||||||
|
connection slave;
|
||||||
|
start slave;
|
||||||
|
--source include/wait_for_slave_to_start.inc
|
||||||
|
|
||||||
|
--source include/rpl_end.inc
|
41
mysql-test/suite/rpl/t/rpl_sync_with_innodb_thd_conc.test
Normal file
41
mysql-test/suite/rpl/t/rpl_sync_with_innodb_thd_conc.test
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# ==== Purpose ====
|
||||||
|
#
|
||||||
|
# Test verifies that replication shouldn't hang when number of active threads
|
||||||
|
# on the slave server are less than the allowed innodb_thread_concurrency value.
|
||||||
|
#
|
||||||
|
# ==== Implementation ====
|
||||||
|
#
|
||||||
|
# Steps:
|
||||||
|
# 0 - Have master slave replication setup with engine being Innodb.
|
||||||
|
# 1 - Configure innodb_thread_concurrency = 100.
|
||||||
|
# 2 - Do some DML on master and sync the slave with master.
|
||||||
|
# 3 - Ensure replication doesn't hang.
|
||||||
|
#
|
||||||
|
# ==== References ====
|
||||||
|
#
|
||||||
|
# MDEV-20247: Replication hangs with "preparing" and never starts
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/master-slave.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
--connection slave
|
||||||
|
SET @old_innodb_thread_concurrency := @@innodb_thread_concurrency;
|
||||||
|
SET @old_innodb_thread_sleep_delay := @@innodb_thread_sleep_delay;
|
||||||
|
SET GLOBAL innodb_thread_concurrency = 100;
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
CREATE TABLE t(f INT) ENGINE=INNODB;
|
||||||
|
INSERT INTO t VALUES (10);
|
||||||
|
--sync_slave_with_master
|
||||||
|
|
||||||
|
--let $diff_tables=master:t, slave:t
|
||||||
|
--source include/diff_tables.inc
|
||||||
|
|
||||||
|
--echo "===== Clean up======="
|
||||||
|
--connection master
|
||||||
|
DROP TABLE t;
|
||||||
|
--sync_slave_with_master
|
||||||
|
SET GLOBAL innodb_thread_concurrency = @old_innodb_thread_concurrency;
|
||||||
|
SET GLOBAL innodb_thread_sleep_delay = @old_innodb_thread_sleep_delay;
|
||||||
|
--source include/rpl_end.inc
|
@@ -24,7 +24,7 @@
|
|||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
--source include/have_binlog_format_mixed.inc
|
--source include/have_binlog_format_mixed.inc
|
||||||
--source include/master-slave.inc
|
--source include/master-slave.inc
|
||||||
|
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
|
||||||
# Case-1: BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS
|
# Case-1: BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS
|
||||||
# Statement is unsafe because it invokes a trigger or a
|
# Statement is unsafe because it invokes a trigger or a
|
||||||
# stored function that inserts into an AUTO_INCREMENT column.
|
# stored function that inserts into an AUTO_INCREMENT column.
|
||||||
|
@@ -6120,6 +6120,48 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int THD::decide_logging_format_low(TABLE *table)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys
|
||||||
|
can be unsafe.
|
||||||
|
*/
|
||||||
|
if(wsrep_binlog_format() <= BINLOG_FORMAT_STMT &&
|
||||||
|
!is_current_stmt_binlog_format_row() &&
|
||||||
|
!lex->is_stmt_unsafe() &&
|
||||||
|
lex->sql_command == SQLCOM_INSERT &&
|
||||||
|
lex->duplicates == DUP_UPDATE)
|
||||||
|
{
|
||||||
|
uint unique_keys= 0;
|
||||||
|
uint keys= table->s->keys, i= 0;
|
||||||
|
Field *field;
|
||||||
|
for (KEY* keyinfo= table->s->key_info;
|
||||||
|
i < keys && unique_keys <= 1; i++, keyinfo++)
|
||||||
|
if (keyinfo->flags & HA_NOSAME &&
|
||||||
|
!(keyinfo->key_part->field->flags & AUTO_INCREMENT_FLAG &&
|
||||||
|
//User given auto inc can be unsafe
|
||||||
|
!keyinfo->key_part->field->val_int()))
|
||||||
|
{
|
||||||
|
for (uint j= 0; j < keyinfo->user_defined_key_parts; j++)
|
||||||
|
{
|
||||||
|
field= keyinfo->key_part[j].field;
|
||||||
|
if(!bitmap_is_set(table->write_set,field->field_index))
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
unique_keys++;
|
||||||
|
exit:;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unique_keys > 1)
|
||||||
|
{
|
||||||
|
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS);
|
||||||
|
binlog_unsafe_warning_flags|= lex->get_stmt_unsafe_flags();
|
||||||
|
set_current_stmt_binlog_format_row_if_mixed();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Implementation of interface to write rows to the binary log through the
|
Implementation of interface to write rows to the binary log through the
|
||||||
|
@@ -2399,6 +2399,20 @@ public:
|
|||||||
/* container for handler's private per-connection data */
|
/* container for handler's private per-connection data */
|
||||||
Ha_data ha_data[MAX_HA];
|
Ha_data ha_data[MAX_HA];
|
||||||
|
|
||||||
|
/**
|
||||||
|
Bit field for the state of binlog warnings.
|
||||||
|
|
||||||
|
The first Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types of
|
||||||
|
unsafeness that the current statement has.
|
||||||
|
|
||||||
|
This must be a member of THD and not of LEX, because warnings are
|
||||||
|
detected and issued in different places (@c
|
||||||
|
decide_logging_format() and @c binlog_query(), respectively).
|
||||||
|
Between these calls, the THD->lex object may change; e.g., if a
|
||||||
|
stored routine is invoked. Only THD persists between the calls.
|
||||||
|
*/
|
||||||
|
uint32 binlog_unsafe_warning_flags;
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
binlog_cache_mngr * binlog_setup_trx_data();
|
binlog_cache_mngr * binlog_setup_trx_data();
|
||||||
|
|
||||||
@@ -2508,20 +2522,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
enum_binlog_format current_stmt_binlog_format;
|
enum_binlog_format current_stmt_binlog_format;
|
||||||
|
|
||||||
/**
|
|
||||||
Bit field for the state of binlog warnings.
|
|
||||||
|
|
||||||
The first Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types of
|
|
||||||
unsafeness that the current statement has.
|
|
||||||
|
|
||||||
This must be a member of THD and not of LEX, because warnings are
|
|
||||||
detected and issued in different places (@c
|
|
||||||
decide_logging_format() and @c binlog_query(), respectively).
|
|
||||||
Between these calls, the THD->lex object may change; e.g., if a
|
|
||||||
stored routine is invoked. Only THD persists between the calls.
|
|
||||||
*/
|
|
||||||
uint32 binlog_unsafe_warning_flags;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Number of outstanding table maps, i.e., table maps in the
|
Number of outstanding table maps, i.e., table maps in the
|
||||||
transaction cache.
|
transaction cache.
|
||||||
@@ -4165,6 +4165,18 @@ public:
|
|||||||
}
|
}
|
||||||
void leave_locked_tables_mode();
|
void leave_locked_tables_mode();
|
||||||
int decide_logging_format(TABLE_LIST *tables);
|
int decide_logging_format(TABLE_LIST *tables);
|
||||||
|
/*
|
||||||
|
In Some cases when decide_logging_format is called it does not have all
|
||||||
|
information to decide the logging format. So that cases we call decide_logging_format_2
|
||||||
|
at later stages in execution.
|
||||||
|
One example would be binlog format for IODKU but column with unique key is not inserted.
|
||||||
|
We dont have inserted columns info when we call decide_logging_format so on later stage we call
|
||||||
|
decide_logging_format_low
|
||||||
|
|
||||||
|
@returns 0 if no format is changed
|
||||||
|
1 if there is change in binlog format
|
||||||
|
*/
|
||||||
|
int decide_logging_format_low(TABLE *table);
|
||||||
|
|
||||||
enum need_invoker { INVOKER_NONE=0, INVOKER_USER, INVOKER_ROLE};
|
enum need_invoker { INVOKER_NONE=0, INVOKER_USER, INVOKER_ROLE};
|
||||||
void binlog_invoker(bool role) { m_binlog_invoker= role ? INVOKER_ROLE : INVOKER_USER; }
|
void binlog_invoker(bool role) { m_binlog_invoker= role ? INVOKER_ROLE : INVOKER_USER; }
|
||||||
|
@@ -1051,6 +1051,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thd->decide_logging_format_low(table);
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
if (lock_type == TL_WRITE_DELAYED)
|
if (lock_type == TL_WRITE_DELAYED)
|
||||||
{
|
{
|
||||||
|
@@ -5115,7 +5115,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
/* In RBR we don't need to log CREATE TEMPORARY TABLE */
|
/* In RBR we don't need to log CREATE TEMPORARY TABLE */
|
||||||
if (thd->is_current_stmt_binlog_format_row() && create_info->tmp_table())
|
if (!result && thd->is_current_stmt_binlog_format_row() && create_info->tmp_table())
|
||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
|
|
||||||
if (create_info->tmp_table())
|
if (create_info->tmp_table())
|
||||||
|
@@ -1753,9 +1753,9 @@ innobase_srv_conc_enter_innodb(
|
|||||||
&& thd_is_replication_slave_thread(trx->mysql_thd)) {
|
&& thd_is_replication_slave_thread(trx->mysql_thd)) {
|
||||||
const ulonglong end = my_interval_timer()
|
const ulonglong end = my_interval_timer()
|
||||||
+ ulonglong(srv_replication_delay) * 1000000;
|
+ ulonglong(srv_replication_delay) * 1000000;
|
||||||
while (srv_conc_get_active_threads()
|
while ((srv_conc_get_active_threads()
|
||||||
>= srv_thread_concurrency
|
>= srv_thread_concurrency)
|
||||||
|| my_interval_timer() >= end) {
|
&& my_interval_timer() < end) {
|
||||||
os_thread_sleep(2000 /* 2 ms */);
|
os_thread_sleep(2000 /* 2 ms */);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, 2018, MariaDB Corporation.
|
Copyright (c) 2017, 2019, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@@ -1954,9 +1954,9 @@ innobase_srv_conc_enter_innodb(
|
|||||||
&& thd_is_replication_slave_thread(trx->mysql_thd)) {
|
&& thd_is_replication_slave_thread(trx->mysql_thd)) {
|
||||||
const ulonglong end = my_interval_timer()
|
const ulonglong end = my_interval_timer()
|
||||||
+ ulonglong(srv_replication_delay) * 1000000;
|
+ ulonglong(srv_replication_delay) * 1000000;
|
||||||
while (srv_conc_get_active_threads()
|
while ((srv_conc_get_active_threads()
|
||||||
>= srv_thread_concurrency
|
>= srv_thread_concurrency)
|
||||||
|| my_interval_timer() >= end) {
|
&& my_interval_timer() < end) {
|
||||||
os_thread_sleep(2000 /* 2 ms */);
|
os_thread_sleep(2000 /* 2 ms */);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user