1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00
Files
mariadb/mysql-test/suite/galera/r/galera_FK_duplicate_client_insert.result
Vlad Lesin 8ff1096999 MDEV-29081 trx_t::lock.was_chosen_as_deadlock_victim race in lock_wait_end()
The issue is that trx_t::lock.was_chosen_as_deadlock_victim can be reset
before the transaction check it and set trx_t::error_state.

The fix is to reset trx_t::lock.was_chosen_as_deadlock_victim only in
trx_t::commit_in_memory(), which is invoked on full rollback. There is
also no need to have separate bit in
trx_t::lock.was_chosen_as_deadlock_victim to flag transaction it was
chosen as a victim of Galera conflict resolution, the same variable can be
used for both cases except debug build. For debug build we need to
distinguish deadlock and Galera's abort victims for debug checks. Also
there is no need to check for deadlock in lock_table_enqueue_waiting() for
Galera as the coresponding check presents in lock_wait().

Local variable "error_state" in lock_wait() was replaced with
trx->error_state, because before the replace
lock_sys_t::cancel<false>(trx, lock) and lock_sys.deadlock_check() could
change trx->error_state, which then could be overwritten with the local
"error_state" variable value.

The lock_wait_suspend_thread_enter DEBUG_SYNC point name is misleading,
because lock_wait_suspend_thread was eliminated in e71e613. It was renamed
to lock_wait_start.

Reviewed by: Marko Mäkelä, Jan Lindström.
2022-08-24 17:06:57 +03:00

383 lines
10 KiB
Plaintext

connection node_2;
connection node_1;
CREATE TABLE user(id int primary key, j int) ENGINE=InnoDB;
CREATE TABLE user_session(id int primary key, fk1 int, fk2 int) ENGINE=InnoDB;
alter table user_session add foreign key (fk1) references user(id);
INSERT INTO user values (1,0), (2,0), (3,0), (4,0);
INSERT INTO user_session values (1,1,1);
connect node_1_u, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connect node_1_i, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connect node_2_i, 127.0.0.1, root, , test, $NODE_MYPORT_2;
"Phase 1: plain SQL statements"
connection node_1;
connection node_1_u;
begin;
update user set j = j + 1 WHERE id > 0;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
insert into user_session(id,fk1,fk2) values (2, 2, 2);
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
insert into user_session(id,fk1,fk2) values (2, 2, 3);
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
update user set j = j + 1 WHERE id > 0;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
insert into user_session(id,fk1,fk2) values (2, 2, 2);
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
insert into user_session(id,fk1,fk2) values (2, 2, 3);
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
update user set j = j + 1 WHERE id > 0;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
insert into user_session(id,fk1,fk2) values (2, 2, 2);
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
insert into user_session(id,fk1,fk2) values (2, 2, 3);
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
update user set j = j + 1 WHERE id > 0;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
insert into user_session(id,fk1,fk2) values (2, 2, 2);
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
insert into user_session(id,fk1,fk2) values (2, 2, 3);
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
update user set j = j + 1 WHERE id > 0;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
insert into user_session(id,fk1,fk2) values (2, 2, 2);
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
insert into user_session(id,fk1,fk2) values (2, 2, 3);
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
update user set j = j + 1 WHERE id > 0;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
insert into user_session(id,fk1,fk2) values (2, 2, 2);
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
insert into user_session(id,fk1,fk2) values (2, 2, 3);
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
update user set j = j + 1 WHERE id > 0;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
insert into user_session(id,fk1,fk2) values (2, 2, 2);
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
insert into user_session(id,fk1,fk2) values (2, 2, 3);
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
update user set j = j + 1 WHERE id > 0;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
insert into user_session(id,fk1,fk2) values (2, 2, 2);
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
insert into user_session(id,fk1,fk2) values (2, 2, 3);
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
update user set j = j + 1 WHERE id > 0;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
insert into user_session(id,fk1,fk2) values (2, 2, 2);
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
insert into user_session(id,fk1,fk2) values (2, 2, 3);
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
update user set j = j + 1 WHERE id > 0;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
insert into user_session(id,fk1,fk2) values (2, 2, 2);
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
insert into user_session(id,fk1,fk2) values (2, 2, 3);
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
"Phase 2: prepared statements"
connection node_1_u;
prepare upd from 'update user set j = j + 1 WHERE id > 0';
connection node_1_i;
prepare ins1 from 'insert into user_session(id,fk1,fk2) values (2, 2, 2)';
connection node_2_i;
prepare ins2 from 'insert into user_session(id,fk1,fk2) values (2, 2, 3)';
connection node_1;
connection node_1_u;
begin;
execute upd;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
execute ins1;
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
execute ins2;
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
execute upd;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
execute ins1;
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
execute ins2;
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
execute upd;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
execute ins1;
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
execute ins2;
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
execute upd;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
execute ins1;
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
execute ins2;
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
execute upd;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
execute ins1;
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
execute ins2;
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
execute upd;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
execute ins1;
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
execute ins2;
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
execute upd;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
execute ins1;
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
execute ins2;
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
execute upd;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
execute ins1;
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
execute ins2;
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
execute upd;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
execute ins1;
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
execute ins2;
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1_u;
begin;
execute upd;
connection node_1_i;
set debug_sync='lock_wait_start SIGNAL ins_waiting WAIT_FOR cont_ins';
execute ins1;
connection node_1;
set debug_sync='now WAIT_FOR ins_waiting';
connection node_2_i;
execute ins2;
connection node_1;
set debug_sync='now SIGNAL cont_ins';
connection node_1_i;
connection node_1_u;
commit;
connection node_1;
truncate user_session;
set debug_sync = reset;
connection node_1;
drop table user_session,user;