binlog文件作为一次写入,会在sync阶段消耗大量的IO,会导致全库hang主,状态大多为query end。 大事务会造成导致主从延迟。 大事务可能导致某些需要备份挂起,原因在于flush table with read lock,拿不到MDL GLOBAL 级别的锁,等待状态为 Waiting for global read lock。 大事务可能导致更大Innodb row锁加锁范围,导致row锁等待问题。 回滚困难。 基于如上一些不完全的列举,我们应该在线上尽可能的避免大事务。好了我们下面来进行问题讨论。
PrintNotStarted print_not_started(file);//建立一个结构体,目的是做not start 事务的打印 ut_list_map(trx_sys->mysql_trx_list, print_not_started); //这个地方打印出那些事务状态是no start的事务。mysql_trx_list是全事务。 const trx_t* trx; TrxListIterator trx_iter; //这个迭代器是trx_sys->rw_trx_list 这个链表的迭代器 const trx_t* prev_trx = 0; /* Control whether a block should be fetched from the buffer pool. */ bool load_block = true; bool monitor = srv_print_innodb_lock_monitor && (srv_show_locks_held != 0); while ((trx = trx_iter.current()) != 0) { //通过迭代器进行迭代 ,显然这里不会有只读事务的信息,全部是读写事务。 ... /* If we need to print the locked record contents then we need to fetch the containing block from the buffer pool. */ if (monitor) { /* Print the locks owned by the current transaction. */ TrxLockIterator& lock_iter = trx_iter.lock_iter(); if (!lock_trx_print_locks( //打印出锁的详细信息 file, trx, lock_iter, load_block)) 简单的说就是先打印哪些处于not start的事务,然后打印那些读写事务的信息,当然我们的回滚事务肯定也包含在其中了,需要注意的是只读事务show engine不会打印。 对于处于回滚状态的事务我们可以在show engine中观察到如下信息: