andrei.elkin@pp.inet.fi writes:
Now consider the second case, where T_1 only sets rgi->killed_for_retry _after_ T_2 has passed the above code point:
1. T_2 acquires some lock inside InnoDB
2. T_2 passes the above code point with the check for rgi->killed_for_retry, it calls mark_start_commit() and starts the commit process.
3. T_1 only now gets a lock conflict with T_2, it calls thd_rpl_deadlock_check(), sets rgi->killed_for_retry, schedules a task for the manager thread to kill T_2
4. T_1 goes to wait on the lock.
In this situation, the lock in InnoDB was still held by T_2 when it ran mark_start_commit().
Hmm, this is unclear. I thought you had a case in which T_2 releases an innodb stats lock at the end of its current statement. And T_1 would try to acquire the lock within that timeframe.
I was describing two different cases, "first case" and "second case". The "first case" is the case where the bug occurred, and the one my patch fixes. It is just as you describe, T_2 releases an innodb stats lock at the end of its current statement. The above "second case" describes a different scenario, trying to explain why this scenario does not cause a bug. This case differs from the "first case" in that the lock taken by T_2 is _not_ released at the end of its current statement, it is only released at commit/rollback. Sorry if this was not clear.
Am I confused in the above? It'd be great to have a T_2 worker stack at time of the lock is granted to it, but it's not provided..
I have included below a stack trace from my notes, where an insert goes to take a dict stats lock.
Obvisoulsy under this perception T_2 would execute mark_start_commit() after the lock is released.
For the scenario where T_2 executes mark_start_commit() after the lock is released, and the bug occurred, you should look at the "first case", described in points 1-8. The "second case" that you found unclear you can just ignore. The point of that was to explain what happens in a different scenario, where T_2 does not release its lock until the transaction is rolled back. In this case we avoid starting D_3 too early, because T_2 does unmark_start_commit() before rolling back and releasing its lock, so there is no bug (with or without the patch).
Please clear it out.
I hope this helps. - Kristian. #13 0x000055af4d51a81e in lock_table_for_trx (table=0x7f30ac0018d8, trx=0x7f30ec7efe80, mode=LOCK_X, no_wait=false) at /kvm/src/my/mariadb/storage/innobase/lock/lock0lock.cc:3831 #14 0x000055af4d7baad8 in dict_stats_save (table_orig=0x7f308897a368, only_for_index=0x0) at /kvm/src/my/mariadb/storage/innobase/dict/dict0stats.cc:3298 #15 0x000055af4d7bcc3b in dict_stats_update (table=0x7f308897a368, stats_upd_option=DICT_STATS_RECALC_PERSISTENT) at /kvm/src/my/mariadb/storage/innobase/dict/dict0stats.cc:4096 #16 0x000055af4d7bd01a in dict_stats_update (table=0x7f308897a368, stats_upd_option=DICT_STATS_FETCH_ONLY_IF_NOT_IN_MEMORY) at /kvm/src/my/mariadb/storage/innobase/dict/dict0stats.cc:4216 #17 0x000055af4d455462 in dict_stats_init (table=0x7f308897a368) at /kvm/src/my/mariadb/storage/innobase/include/dict0stats.inl:165 #18 0x000055af4d474eee in ha_innobase::info_low (this=0x7f3088981450, flag=282, is_analyze=false) at /kvm/src/my/mariadb/storage/innobase/handler/ha_innodb.cc:14754 #19 0x000055af4d4758dd in ha_innobase::info (this=0x7f3088981450, flag=282) at /kvm/src/my/mariadb/storage/innobase/handler/ha_innodb.cc:15018 #20 0x000055af4d461690 in ha_innobase::open (this=0x7f3088981450, name=0x7f3088991e90 "./test/t6") at /kvm/src/my/mariadb/storage/innobase/handler/ha_innodb.cc:6131 #21 0x000055af4d0c42b0 in handler::ha_open (this=0x7f3088981450, table_arg=0x7f307c013188, name=0x7f3088991e90 "./test/t6", mode=2, test_if_locked=18, mem_root=0x0, partitions_to_open=0x0) at /kvm/src/my/mariadb/sql/handler.cc:3375 #22 0x000055af4ce7999a in open_table_from_share (thd=0x7f3088000f88, share=0x7f30889918d0, alias=0x7f308800a9f0, db_stat=33, prgflag=8, ha_open_flags=18, outparam=0x7f307c013188, is_create_table=false, partitions_to_open=0x0) at /kvm/src/my/mariadb/sql/table.cc:4459 #23 0x000055af4cc541b7 in open_table (thd=0x7f3088000f88, table_list=0x7f308800a9a8, ot_ctx=0x7f30e4288d00) at /kvm/src/my/mariadb/sql/sql_base.cc:2196 #24 0x000055af4cc58768 in open_and_process_table (thd=0x7f3088000f88, tables=0x7f308800a9a8, counter=0x7f30e4288d94, flags=0, prelocking_strategy=0x7f30e4288e18, has_prelocking_list=false, ot_ctx=0x7f30e4288d00) at /kvm/src/my/mariadb/sql/sql_base.cc:4126 #25 0x000055af4cc59a69 in open_tables (thd=0x7f3088000f88, options=..., start=0x7f30e4288d78, counter=0x7f30e4288d94, flags=0, prelocking_strategy=0x7f30e4288e18) at /kvm/src/my/mariadb/sql/sql_base.cc:4613 #26 0x000055af4cc5b850 in open_and_lock_tables (thd=0x7f3088000f88, options=..., tables=0x7f308800a9a8, derived=true, flags=0, prelocking_strategy=0x7f30e4288e18) at /kvm/src/my/mariadb/sql/sql_base.cc:5587 #27 0x000055af4cc11466 in open_and_lock_tables (thd=0x7f3088000f88, tables=0x7f308800a9a8, derived=true, flags=0) at /kvm/src/my/mariadb/sql/sql_base.h:510 #28 0x000055af4ccb46d0 in mysql_insert (thd=0x7f3088000f88, table_list=0x7f308800a9a8, fields=..., values_list=..., update_fields=..., update_values=..., duplic=DUP_ERROR, ignore=false, result=0x0) at /kvm/src/my/mariadb/sql/sql_insert.cc:768 #29 0x000055af4cd05d06 in mysql_execute_command (thd=0x7f3088000f88, is_called_from_prepared_stmt=false) at /kvm/src/my/mariadb/sql/sql_parse.cc:4579