mirror of
https://github.com/MariaDB/server.git
synced 2025-02-16 02:15:33 +01:00
![Kristian Nielsen](/assets/img/avatar_default.png)
In Log_event::read_log_event(), don't use IO_CACHE::error of the relay log's
IO_CACHE to signal an error back to the caller. When reading the active
relay log, this flag is also being used by the IO thread, and setting it can
randomly cause the IO thread to wrongly detect IO error on writing and
permanently disable the relay log.
This was seen sporadically in test case rpl.rpl_from_mysql80. The read
error set by the SQL thread in the IO_CACHE would be interpreted as a
write error by the IO thread, which would cause it to throw a fatal
error and close the relay log. And this would later cause CHANGE
MASTER to try to purge a closed relay log, resulting in nullptr crash.
SQL thread is not able to parse an event read from the relay log. This
can happen like here when replicating unknown events from a MySQL master,
potentially also for other reasons.
Also fix a mistake in my_b_flush_io_cache() introduced back in 2001
(fa09f2cd7e
) where my_b_flush_io_cache() could wrongly return an error set
in IO_CACHE::error, even if the flush operation itself succeeded.
Also fix another sporadic failure in rpl.rpl_from_mysql80 where the outout
of MASTER_POS_WAIT() depended on timing of SQL and IO thread.
Reviewed-by: Monty <monty@mariadb.org>
Reviewed-by: Andrei Elkin <andrei.elkin@mariadb.com>
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
123 lines
4.2 KiB
Text
123 lines
4.2 KiB
Text
--source include/have_innodb.inc
|
|
--source include/have_binlog_format_row.inc
|
|
--source include/master-slave.inc
|
|
|
|
# Test some replication events from MySQL 8.0 to MariaDB.
|
|
# Works by copying in a binlog generated by MySQL 8.0.
|
|
# The binlog was generated by the following test case. Note that after
|
|
# re-generating this, values for Master_log_pos below may need updating, check
|
|
# mysqlbinlog for the correct new values.
|
|
#
|
|
# The latin1 character set is needed since MariaDB currently does not support
|
|
# the default MySQL character set. The binlog_format=statement is needed due to
|
|
# missing support for the JSON type in row events. These can be removed once
|
|
# support is added in MariaDB.
|
|
#
|
|
# --source include/not_group_replication_plugin.inc
|
|
# --source include/have_binlog_format_row.inc
|
|
# --source include/master-slave.inc
|
|
#
|
|
# --connection master
|
|
# SET NAMES 'latin1';
|
|
# SET SESSION collation_server= 'latin1_swedish_ci';
|
|
# CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c VARCHAR(1024)) ENGINE=InnoDB CHARACTER SET latin1;
|
|
# INSERT INTO t1 VALUES (1, 0, '');
|
|
# BEGIN;
|
|
# INSERT INTO t1 VALUES (2, 0, 'hulu');
|
|
# INSERT INTO t1 VALUES (3, 0, 'bulu');
|
|
# COMMIT;
|
|
# INSERT INTO t1 VALUES (4, 0, 'skip');
|
|
#
|
|
# SET SESSION binlog_transaction_compression= 1;
|
|
# BEGIN;
|
|
# --disable_query_log
|
|
# --let $i= 0
|
|
# while ($i < 100) {
|
|
# eval INSERT INTO t1 VALUES ($i+1000, $i, CONCAT("--", $i, "--", REPEAT("\\/", 100), "--"));
|
|
# inc $i;
|
|
# }
|
|
# --enable_query_log
|
|
# COMMIT;
|
|
# SET SESSION binlog_transaction_compression= default;
|
|
#
|
|
# INSERT INTO t1 VALUES (5, 0, 'after compressed');
|
|
# SET SESSION binlog_row_value_options= PARTIAL_JSON;
|
|
# CREATE TABLE t2 (a INT PRIMARY KEY, b JSON) ENGINE=InnoDB;
|
|
# SET SESSION binlog_format=statement;
|
|
# INSERT INTO t2 VALUES (1, CONCAT('{"a": "hulu", "b": "', REPEAT("[zyzzy]", 100), '", "c": "bulu"}'));
|
|
# SET SESSION binlog_format=row;
|
|
# UPDATE t2 SET b=JSON_REPLACE(b, '$.b', REPEAT("oOo", 50));
|
|
# SET SESSION binlog_row_value_options= DEFAULT;
|
|
# --sync_slave_with_master
|
|
#
|
|
# --connection master
|
|
# SET sql_log_bin= 0;
|
|
# FLUSH BINARY LOGS;
|
|
# SET sql_log_bin= 1;
|
|
# DROP TABLE t1, t2;
|
|
# --source include/rpl_end.inc
|
|
|
|
|
|
--connection slave
|
|
--source include/stop_slave.inc
|
|
|
|
--connection master
|
|
--let $datadir= `SELECT @@datadir`
|
|
--let $rpl_server_number= 1
|
|
--source include/rpl_stop_server.inc
|
|
|
|
# Copy in the MySQL 8.0 generated binlog.
|
|
--remove_file $datadir/master-bin.000001
|
|
--copy_file $MYSQL_TEST_DIR/std_data/mdev35643_mysql_80_binlog.000001 $datadir/master-bin.000001
|
|
|
|
--source include/rpl_start_server.inc
|
|
|
|
--save_master_pos
|
|
|
|
--connection slave
|
|
CHANGE MASTER TO Master_log_file='master-bin.000001', Master_log_pos=4, Master_use_gtid=No;
|
|
START SLAVE IO_THREAD;
|
|
--source include/wait_for_slave_io_to_start.inc
|
|
# The position 1178 is the start of: INSERT INTO t1 VALUES (4, 0, 'skip');
|
|
# After that comes unknown MySQL 8.0 events, which we test error for below.
|
|
START SLAVE UNTIL Master_log_file='master-bin.000001', Master_log_pos= 1178;
|
|
--disable_result_log
|
|
SELECT MASTER_POS_WAIT('master-bin.000001', 1178, 60);
|
|
--enable_result_log
|
|
SELECT * FROM t1 ORDER BY a;
|
|
|
|
--source include/wait_for_slave_sql_to_stop.inc
|
|
|
|
START SLAVE;
|
|
--let $slave_sql_errno= 1594
|
|
--source include/wait_for_slave_sql_error.inc
|
|
|
|
STOP SLAVE IO_THREAD;
|
|
--source include/wait_for_slave_io_to_stop.inc
|
|
# The position 2298 is the start of: INSERT INTO t1 VALUES (5, 0, 'after compressed');
|
|
CHANGE MASTER TO Master_log_file='master-bin.000001', Master_log_pos=2297;
|
|
START SLAVE IO_THREAD;
|
|
START SLAVE SQL_THREAD;
|
|
--source include/wait_for_slave_io_to_start.inc
|
|
--let $slave_sql_errno= 1594
|
|
--source include/wait_for_slave_sql_error.inc
|
|
|
|
SELECT * FROM t1 ORDER BY a;
|
|
SELECT * FROM t2 ORDER BY a;
|
|
|
|
STOP SLAVE IO_THREAD;
|
|
--source include/wait_for_slave_io_to_stop.inc
|
|
# Restart replication after the MySQL 8.0 file.
|
|
CHANGE MASTER TO Master_log_file='master-bin.000002', Master_log_pos=4;
|
|
START SLAVE IO_THREAD;
|
|
START SLAVE SQL_THREAD;
|
|
--source include/wait_for_slave_io_to_start.inc
|
|
--source include/wait_for_slave_sql_to_start.inc
|
|
--sync_with_master
|
|
|
|
DROP TABLE t1, t2;
|
|
CALL mtr.add_suppression('TRANSACTION_PAYLOAD_EVENT event. You can avoid this event by specifying');
|
|
CALL mtr.add_suppression('PARTIAL_UPDATE_ROWS_EVENT event. You can avoid this event by specifying');
|
|
|
|
--connection master
|
|
--source include/rpl_end.inc
|