1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-21117: refine the server binlog-based recovery for semisync

Problem:
=======
When the semisync master is crashed and restarted as slave it could
recover transactions that former slaves may never have seen.
A known method existed to clear out all prepared transactions
with --tc-heuristic-recover=rollback does not care to adjust
binlog accordingly.

Fix:
===
The binlog-based recovery is made to concern of the slave semisync role of
post-crash restarted server.
No changes in behavior is done to the "normal" binloggging server
and the semisync master.

When the restarted server is configured with
  --rpl-semi-sync-slave-enabled=1
the refined recovery attempts to roll back prepared transactions
and truncate binlog accordingly.
In case of a partially committed (that is committed at least
in one of the engine participants) such transaction gets committed.
It's guaranteed no (partially as well) committed transactions
exist beyond the truncate position.
In case there exists a non-transactional replication event
(being in a way a committed transaction) past the
computed truncate position the recovery ends with an error.

As after master crash and failover to slave, the demoted-to-slave
ex-master must be ready to face and accept its own (generated by)
events, without generally necessary --replicate-same-server-id.
So the acceptance conditions are relaxed for the semisync slave
to accept own events without that option.
While gtid_strict_mode ON ensures no duplicate transaction can be
(re-)executed the master_use_gtid=none slave has to be
configured with --replicate-same-server-id.

*NOTE* for reviewers.

This patch does not handle the user XA which is done
in next git commit.
This commit is contained in:
Sujatha
2020-04-09 20:45:45 +05:30
committed by Andrei Elkin
parent 82c07b178a
commit 6c39eaeb12
25 changed files with 2619 additions and 127 deletions

View File

@@ -0,0 +1,77 @@
# ==== Purpose ====
#
# Test verifies truncation of multiple binary logs.
#
# ==== References ====
# MDEV-21117: recovery for --rpl-semi-sync-slave-enabled server
--source include/have_innodb.inc
--source include/have_debug_sync.inc
--source include/have_binlog_format_row.inc
call mtr.add_suppression("Can.t init tc log");
call mtr.add_suppression("Aborting");
SET @@global.max_binlog_size= 4096;
RESET MASTER;
FLUSH LOGS;
CREATE TABLE ti (a INT PRIMARY KEY, b MEDIUMTEXT) ENGINE=Innodb;
CREATE TABLE tm (a INT PRIMARY KEY, b MEDIUMTEXT) ENGINE=MyISAM;
connect(master1,localhost,root,,);
--echo "List of binary logs before rotation"
--source include/show_binary_logs.inc
# Some load to either non- and transactional egines
# that should not affect the following recovery:
INSERT INTO ti VALUES(1,"I am gonna survive");
INSERT INTO tm VALUES(1,"me too!");
# hold on near engine commit
SET DEBUG_SYNC= "commit_after_release_LOCK_after_binlog_sync SIGNAL master1_ready WAIT_FOR con1_go";
--send INSERT INTO ti VALUES (2, REPEAT("x", 4100))
connect(master2,localhost,root,,);
# The 2nd trx for recovery, it does not rotate binlog
SET DEBUG_SYNC= "now WAIT_FOR master1_ready";
SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL master2_ready WAIT_FOR master2_go";
--send INSERT INTO ti VALUES (3, "not gonna survive")
--connection default
SET DEBUG_SYNC= "now WAIT_FOR master2_ready";
--echo "List of binary logs before crash"
--source include/show_binary_logs.inc
--echo # The gtid binlog state prior the crash will be truncated at the end of the test
SELECT @@global.gtid_binlog_state;
--connection default
--source include/kill_mysqld.inc
--disconnect master1
--disconnect master2
#
# Server restart
#
--let $restart_parameters= --rpl-semi-sync-slave-enabled=1
--source include/start_mysqld.inc
# Check error log for a successful truncate message.
let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err;
--let SEARCH_FILE=$log_error_
--let SEARCH_PATTERN=truncated binlog file:.*master.*000002
--source include/search_pattern_in_file.inc
--echo "One record should be present in table"
SELECT * FROM ti;
--echo # The truncated gtid binlog state
SELECT @@global.gtid_binlog_state;
SELECT @@global.gtid_binlog_pos;
--echo # Cleanup
DROP TABLE ti;
--echo # End of the tests