Hi Sergei, After QA runs done by Ramesh, we now know the latest fix candidate i.e. what is in bb-10.2-MDEV-25114-galera-v2 is incorrect. Problem is in wsrep_close_connections() as it holds LOCK_thread_count while it does abort_replicated that will call wsrep_abort_transaction and there we use find_thread_by_id that would also take LOCK_thread_count. As there is another code path here, the problem is not easily fixed. We can't just release LOCK_thread_count at wsrep_close_connections as we iterate the thread list.
I must say I'm not sure what to do now. (gdb) bt #0 __pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ../sysdeps/unix/sysv/linux/pthread_kill.c:56 #1 0x000056333963a2e8 in my_write_core (sig=sig@entry=6) at /test/mtest/10.2_dbg/mysys/stacktrace.c:382 #2 0x0000563338f2993d in handle_fatal_signal (sig=6) at /test/mtest/10.2_dbg/sql/signal_handler.cc:355 #3 <signal handler called> #4 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 #5 0x000014b799572859 in __GI_abort () at abort.c:79 #6 0x000056333963edc4 in safe_mutex_lock (mp=0x563339e47220 <LOCK_thread_count>, my_flags=my_flags@entry=0, file=file@entry=0x5633396d9050 "/test/mtest/10.2_dbg/sql/sql_parse.cc", line=line@entry=8902) at /test/mtest/10.2_dbg/mysys/thr_mutex.c:264 #7 0x0000563338d1aea7 in inline_mysql_mutex_lock (src_line=8902, src_file=0x5633396d9050 "/test/mtest/10.2_dbg/sql/sql_parse.cc", that=<optimized out>) at /test/mtest/10.2_dbg/include/mysql/psi/mysql_thread.h:688 #8 find_thread_by_id (id=id@entry=48, query_id=query_id@entry=false) at /test/mtest/10.2_dbg/sql/sql_parse.cc:8902 #9 0x0000563339134c39 in wsrep_abort_transaction (hton=<optimized out>, bf_thd=0x14b680000d90, victim_thd=<optimized out>, signal=<optimized out>) at /test/mtest/10.2_dbg/storage/innobase/handler/ha_innodb.cc:19821 #10 0x0000563338f38cbf in ha_abort_transaction (bf_thd=bf_thd@entry=0x14b680000d90, victim_thd=victim_thd@entry=0x14b680000d90, signal=signal@entry=1 '\001') at /test/mtest/10.2_dbg/sql/handler.cc:6327 #11 0x0000563338ebed6d in wsrep_abort_thd (bf_thd_ptr=bf_thd_ptr@entry=0x14b680000d90, victim_thd_ptr=victim_thd_ptr@entry=0x14b680000d90, signal=signal@entry=1 '\001') at /test/mtest/10.2_dbg/sql/wsrep_thd.cc:832 #12 0x0000563338eaa2bd in abort_replicated (thd=thd@entry=0x14b680000d90) at /test/mtest/10.2_dbg/sql/wsrep_mysqld.cc:2269 #13 0x0000563338eae097 in wsrep_close_client_connections (wait_to_end=wait_to_end@entry=1 '\001', except_caller_thd=except_caller_thd@entry=0x0) at /test/mtest/10.2_dbg/sql/wsrep_mysqld.cc:2437 #14 0x0000563338eaedf6 in wsrep_stop_replication (thd=thd@entry=0x0) at /test/mtest/10.2_dbg/sql/wsrep_mysqld.cc:962 #15 0x0000563338c543d8 in kill_server (sig_ptr=sig_ptr@entry=0x0) at /test/mtest/10.2_dbg/sql/mysqld.cc:2009 #16 0x0000563338c558d5 in kill_server_thread (arg=<optimized out>) at /test/mtest/10.2_dbg/sql/mysqld.cc:2047 #17 0x000014b799a7a609 in start_thread (arg=<optimized out>) at pthread_create.c:477 #18 0x000014b79966f293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95 R: Jan On Wed, Oct 6, 2021 at 5:03 PM Sergei Golubchik <s...@mariadb.org> wrote: > Hi, Jan! > > On Oct 06, Jan Lindström wrote: > > > > > > > > > +/* This is wrapper for wsrep_break_lock in thr_lock.c */ > > > > > > +static int wsrep_thr_abort_thd(void *bf_thd_ptr, void > *victim_thd_ptr, my_bool signal) > > > > > > +{ > > > > > > + THD* victim_thd= (THD *) victim_thd_ptr; > > > > > > + /* We need to lock THD::LOCK_thd_data to protect victim > > > > > > + from concurrent usage or disconnect or delete. */ > > > > > > > > > > How do you know victim_thd wasn't deleted before you locked > > > > > LOCK_thd_data below? > > > > > > > > I must say the thr_lock code is not familiar to me but there are > > > > mysql_mutex_lock() calls to lock->mutex. After code review it is not > > > > clear to me what that mutex is. > > > > > > where are mysql_mutex_lock() calls to lock->mutex? > > > > mysys/thr_lock.c there is function thr_lock() there is call to > > mysql_mutex_lock(&lock->mutex); this is before wsrep_break_lock where we > > call wsrep_thd_abort > > this is for table locks. `lock` is `data->lock` where `data` is THR_LOCK > structure somewhere in the table share. It locks tables and handlers, > not threads. And InnoDB isn't using it at all anyway. > > > > > > > > > if (victim_trx) { > > > > > > + wsrep_thd_UNLOCK(victim_thd); > > > > > > > > > > what keeps victim_trx from disappearing here? > > > > > > > > Nothing. Do you have suggestions ? > > > > > > A couple of thoughts: > > > > > > * Why do you unlock LOCK_thd_data here at all? I believed the whole > > > point of using TOI was to make sure that even if you lock mutexes in > > > a different order, it will not cause a deadlock. > > > > This is DDL-case when we have a MDL-conflict not user KILL, we need to > > release it in my opinion because we need to take mutexes in > > lock_sys -> trx -> THD::LOCK_thd_data order, > > if I do not release I can see easily safe_mutex warnings > > I don't understand. First, lock_sys and trx mutexes are not covered by > safe_mutex, so it cannot possibly warn about them. > > Second, the reason for taking mutexes always in the same order is to > avoid deadlocks. And yor TOI trick should archieve that. > > > > * You cannot pass a THD safely over a gap where no locks keep it in > > > existence. You can pass an integer, thread id, and use > > > find_thread_by_id later. > > > > I have a suggestion for this: > > > > if (victim_trx) { > > + > > + const trx_id_t victim_trx_id= victim_trx->id; > > + const longlong victim_thread= > thd_get_thread_id(victim_thd); > > lock_mutex_enter(); > > - trx_mutex_enter(victim_trx); > > - wsrep_innobase_kill_one_trx(bf_thd, bf_trx, victim_trx, > signal); > > + if (trx_t* victim= trx_rw_is_active(victim_trx_id, NULL, > true)) // If this succeeds, trx can not go away > > + { > > + trx_mutex_enter(victim); > > + ut_ad(victim->mysql_thd ? > > + thd_get_thread_id(victim->mysql_thd) == > victim_thread : > > + 1); > > + wsrep_innobase_kill_one_trx(bf_thd, bf_trx, > victim, signal); > > + trx_mutex_exit(victim); > > + victim->release_reference(); // Now trx can go > away after we have released lock_sys > > + wsrep_srv_conc_cancel_wait(victim); > > + } > > lock_mutex_exit(); > > - trx_mutex_exit(victim_trx); > > - wsrep_srv_conc_cancel_wait(victim_trx); > > DBUG_VOID_RETURN; > > I don't understand, sorry. It's not quite clear what this patch should > apply to. May be you can paste what the new code should look like, not a > patch? > > In particular, where are wsrep_thd_UNLOCK and wsrep_thd_LOCK. Are they > present in this new variant at all? > > > > > > By the way, how long can WSREP_TO_ISOLATION_BEGIN() take? > > > Does it need to wait for everything else being replicated? > > > > As long as it takes to start it on all nodes in the cluster. > > So, KILL basically won't work when a cluster is starting. > Can bf aborts happen during a cluster startup? > > Regards, > Sergei > VP of MariaDB Server Engineering > and secur...@mariadb.org >
_______________________________________________ Mailing list: https://launchpad.net/~maria-developers Post to : maria-developers@lists.launchpad.net Unsubscribe : https://launchpad.net/~maria-developers More help : https://help.launchpad.net/ListHelp