1
0
mirror of https://github.com/MariaDB/server.git synced 2025-05-05 16:59:35 +03:00
mariadb/mysql-test/t/rpl_crash_binlog_ib_1a.test
unknown 3220a94519 Robustness feature.
Won't be pushed as is - separate email sent for internal review.
WL#1717 "binlog-innodb consistency".
Now when mysqld starts, if InnoDB does a crash recovery, we use the binlog name
and position retrieved from InnoDB (corresponding to the last transaction
successfully committed by InnoDB) to cut any rolled back transaction from
the binary log. This is triggered by the --innodb-safe-binlog option.
Provided you configure mysqld to fsync() InnoDB at every commit (using
flush_log_at_trx_commit) and to fsync() the binlog at every write
(using --sync-binlog=1), this behaviour guarantees that a master always has
consistency between binlog and InnoDB, whenever the crash happens.
6 tests to verify that it works.


client/mysqltest.c:
  New command require_os (only "unix" accepted for now).
innobase/include/trx0sys.h:
  when InnoDB does crash recovery, we now save the binlog coords it prints, into variables for later use.
innobase/trx/trx0sys.c:
  when InnoDB does crash recovery, we now save the binlog coords it prints, into variables for later use.
mysql-test/mysql-test-run.sh:
  The tests which check that the binlog is cut at restart, need to not delete those binlogs, of course.
  And not delete replication info, so that we can test that the slave does not receive anything
  wrong from the cut binlog.
sql/ha_innodb.cc:
  methods to read from InnoDB the binlog coords stored into it
sql/ha_innodb.h:
  ethods to read from InnoDB the binlog coords stored into it
sql/log.cc:
  Added my_sync() when we create a binlog (my_sync of the binlog and of the index file);
  this is always done, whether --sync-binlog or not (binlog creation is rare, so no speed
  problem, and I like to have the existence of the binlog always reliably recorded, even if
  later content is not).
  If --crash-binlog-innodb, crash between the binlog write and the InnoDB commit.
  New methods:
  - report_pos_in_innodb() to store the binlog name and position into InnoDB (used only when
  we create a new binlog: at startup and at FLUSH LOGS)
  - cut_spurious_tail() to possibly cut the tail of a binlog based on the info we read
  from InnoDB (does something only if InnoDB has just done a crash recovery).
sql/mysql_priv.h:
  new option, to crash (use for testing only)
sql/mysqld.cc:
  New option --innodb-safe-binlog and --crash-binlog-innodb (the latter is for testing, it makes mysqld crash).
  Just after opening the logs and opening the storage engines, cut any wrong statement from the binlog, based
  on info read from InnoDB.
sql/sql_class.h:
  new methods for MYSQL_LOG.
2004-06-20 19:11:02 +02:00

72 lines
2.6 KiB
Plaintext

# Test if master cuts binlog at InnoDB crash's recovery,
# if the transaction had been written to binlog but not committed into InnoDB
# We need InnoDB in the master, and a debug build in the master.
# There are 6 tests, in fact 3 pairs:
# 1st pair:
# rpl_crash_binlog_innodb_1a: crash when InnoDB in autocommit mode
# rpl_crash_binlog_innodb_1b: test of recovery after the crash of test 1a
# 2nd pair:
# rpl_crash_binlog_innodb_2a: crash when InnoDB in non autocommit mode
# rpl_crash_binlog_innodb_2b: test of recovery after the crash of test 1a
# 3rd pair:
# rpl_crash_binlog_innodb_3a: crash when InnoDB in autocommit mode, at
# very first transactional statement since master's startup (a purely
# academic case but which will be tested a lot)
# rpl_crash_binlog_innodb_3b: test of recovery after the crash of test 3a
# The *b tests should always be run just after their 1a; don't run *b
# alone it won't work properly.
# This test is only for autocommit mode.
source include/master-slave.inc ;
source include/have_debug.inc ;
source include/have_innodb.inc ;
require_os unix ;
flush logs; # this will help us be sure it's the same log in the next test
# One problem: we need InnoDB to know of the last good position, so it
# must have committed at least one transaction and in the binlog before the crash.
# NOTE: the above should become false quite soon
set autocommit=1;
set sql_log_bin=0;
create table t1 (n int) engine=innodb;
set sql_log_bin=1;
sync_slave_with_master;
# We use MyISAM on slave so that any spurious statement received from the
# master has a visible effect.
create table t1 (n int) engine=myisam;
connection master;
insert into t1 values (3);
# The reported size here should be exactly the same as the one we measure
# at the end of rpl_crash_binlog_innodb_1b.test
show master status;
# Master will crash in this (it crashes on 3rd binlog write, counting
# the DROP IF EXISTS in master-slave.inc):
error 2013;
send insert into t1 values (4);
sleep 4; # enough time to die
# No 'reap' as it may hang as master died hard.
# This kill speeds up:
system sh misc/kill_master.sh ;
# Check that slave did not receive the spurious INSERT statement
connection slave;
select * from t1;
# Check that the spurious statement is in the master's binlog
# LOAD_FILE() needs a file readable by all
system chmod ugo+r $MYSQL_TEST_DIR/var/log/master-bin.000002 ;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
eval set @a=load_file("$MYSQL_TEST_DIR/var/log/master-bin.000002");
select length(@a);
select @a like "%values (4)%";
# Now we will run rpl_crash_binlog_innodb_1b.test to test
# if the spurious statement gets truncated at master's restart.