mirror of
https://github.com/MariaDB/server.git
synced 2025-02-02 03:51:50 +01:00
8823b832bb
Bug#23831 deadlock not noticed RBR bug in that when replicated msta (multi-statement-trans-action) deadlocks with a local at write row event or gets timed-out, the event handler did not return the correct error code. Wrong error code stops slave sql thread instead of to proceed with rollback and replay. The correct code is typed in error log and stored for error handling rotine to conduct rollback and replay of the transaction. The handling for the rbr remains the same as for the sbr events. Particularly, timed-out transaction still is rolled back - look at the related bugs.
130 lines
3.7 KiB
Text
130 lines
3.7 KiB
Text
# See if slave restarts the transaction after failing on an InnoDB deadlock error.
|
|
|
|
# Note: testing what happens when too many retries is possible, but
|
|
# needs large waits when running with --debug, so we don't do it.
|
|
# The same way, this test may not test what is expected when run
|
|
# under Valgrind, timings are too short then (with --valgrind I
|
|
# (Guilhem) have seen the test manage to provoke lock wait timeout
|
|
# error but not deadlock error; that is ok as code deals with the two
|
|
# errors in exactly the same way.
|
|
# We don't 'show status like 'slave_retried_transactions'' because this
|
|
# is not repeatable (depends on sleeps).
|
|
|
|
-- source include/master-slave.inc
|
|
|
|
connection master;
|
|
eval CREATE TABLE t1 (a INT NOT NULL, KEY(a)) ENGINE=$engine_type;
|
|
eval CREATE TABLE t2 (a INT NOT NULL, KEY(a)) ENGINE=$engine_type;
|
|
# requiring 'unique' for the timeout part of the test
|
|
eval CREATE TABLE t3 (a INT UNIQUE) ENGINE=$engine_type;
|
|
eval CREATE TABLE t4 (a INT) ENGINE=$engine_type;
|
|
show variables like 'slave_transaction_retries';
|
|
sync_slave_with_master;
|
|
|
|
show create table t1;
|
|
show create table t2;
|
|
show variables like 'slave_transaction_retries';
|
|
stop slave;
|
|
|
|
# 1) Test deadlock
|
|
|
|
connection master;
|
|
begin;
|
|
# Let's keep BEGIN and the locked statement in two different relay logs.
|
|
insert into t2 values (0); # t2,t1 actors of deadlock in repl-ed ta
|
|
#insert into t3 select * from t2 for update;
|
|
let $1=10;
|
|
disable_query_log;
|
|
while ($1)
|
|
{
|
|
eval insert into t3 values( $1 );
|
|
dec $1;
|
|
}
|
|
enable_query_log;
|
|
insert into t1 values(1);
|
|
commit;
|
|
save_master_pos;
|
|
|
|
connection slave;
|
|
begin;
|
|
# Let's make our transaction large so that it's repl-ed msta that's victim
|
|
let $1=100;
|
|
disable_query_log;
|
|
while ($1)
|
|
{
|
|
eval insert into t4 values( $1 );
|
|
dec $1;
|
|
}
|
|
enable_query_log;
|
|
select * from t1 for update; # t1,t2 on local slave's
|
|
start slave;
|
|
|
|
# bad option, todo: replicate a non-transactional t_sync with the transaction
|
|
# and use wait_until_rows_count macro below
|
|
--real_sleep 3 # hope that slave is blocked now
|
|
#let $count=11;
|
|
#let $table=t_sync;
|
|
#--include wait_until_rows_count.inc
|
|
|
|
select * from t2 for update /* dl */; # provoke deadlock, repl-ed should be victim
|
|
commit;
|
|
sync_with_master;
|
|
select * from t1; # check that repl-ed succeeded finally
|
|
select * from t2 /* must be 1 */;
|
|
# check that no error is reported
|
|
--replace_column 1 # 7 # 8 # 9 # 16 # 22 # 23 # 33 #
|
|
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
|
--vertical_results
|
|
show slave status;
|
|
--horizontal_results
|
|
|
|
# 2) Test lock wait timeout
|
|
|
|
stop slave;
|
|
delete from t3;
|
|
change master to master_log_pos=544; # the BEGIN log event
|
|
begin;
|
|
select * from t2 for update; # hold lock
|
|
start slave;
|
|
--real_sleep 10 # repl-ed should have blocked, and be retrying
|
|
select count(*) from t3 /* must be zero */; # replaying begins after rollback
|
|
commit;
|
|
sync_with_master;
|
|
select * from t1; # check that repl-ed succeeded finally
|
|
select * from t2;
|
|
# check that no error is reported
|
|
--replace_column 1 # 7 # 8 # 9 # 11 # 16 # 22 # 23 # 33 #
|
|
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
|
--vertical_results
|
|
show slave status;
|
|
--horizontal_results
|
|
|
|
# Now we repeat 2), but with BEGIN in the same relay log as
|
|
# COMMIT (to see if seeking into hot log is ok).
|
|
|
|
set global max_relay_log_size=0;
|
|
|
|
# This is really copy-paste of 2) of above
|
|
stop slave;
|
|
delete from t3;
|
|
change master to master_log_pos=544;
|
|
begin;
|
|
select * from t2 for update;
|
|
start slave;
|
|
--real_sleep 10
|
|
select count(*) from t3 /* must be zero */; # replaying begins after rollback
|
|
commit;
|
|
sync_with_master;
|
|
select * from t1;
|
|
select * from t2;
|
|
--replace_column 1 # 7 # 8 # 9 # 11 # 16 # 22 # 23 # 33 #
|
|
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
|
--vertical_results
|
|
show slave status;
|
|
--horizontal_results
|
|
|
|
connection master;
|
|
drop table t1,t2,t3,t4;
|
|
sync_slave_with_master;
|
|
|
|
--echo End of 5.1 tests
|