December 13, 2012

[MySQL 学习]show engine innodb status中的history list length

Percona bug#1058100提到trx_purge_add_update_undo_to_history函数,不甚了解,用gdb跟踪了下 trx_commit_off_kernel->trx_write_serialisation_history->trx_undo_update_cleanup->trx_purge_add_update_undo_to_history lsn = trx_write_serialisation_history(trx); a.首先对当前事务的undo段进行标记,以表明事务提交。 对于update undo日志,为事务分配id(trx_serialisation_number_get->trx_sys_get_new_trx_id),标记undo状态为TRX_UNDO_TO_PURGE(trx_undo_set_state_at_finish), 对于insert undo标记undo回滚段状态为TRX_UNDO_TO_FREE 如果update undo段只占用一个Page,并且使用的字节数小于TRX_UNDO_PAGE_REUSE_LIMIT(3/4的page size)时,则将undo段标记为TRX_UNDO_CACHED,表示下次可以重用该回滚段。 b.对于update undo,还需要将undo加到history list上,并做一些清理工作 trx_undo_update_cleanup(trx, undo_hdr_page, &mtr); (1)trx_purge_add_update_undo_to_history(trx, undo_page, mgr); 当undo 段的state不为TRX_UNDO_CACHED时,需要更新undo段的history list length,然后将undo加入到改回滚段的TRX_RSEG_HISTORY的链表上(不太了解undo这部分相关的逻辑),将事务号写入undo_header + TRX_UNDO_TRX_NO中,并在TRX_UNDO_DEL_MARKS标注是否存在标记删除记录(需要purge) 在kernel_mutex的保护下trx_sys->rseg_history_len++; 我们在show engine innodb status里看到的History list length实际上就是trx_sys->rseg_history_len值。 由于该函数总是在事务提交时才被调用到,因此我们也可以把history list lengh理解为尚未被清理update undo的事务数.在update/delete为主的工作负载中,可能会看到length明显的增大。 这里有一段被注释的代码,也是Percona bug#1058100提出的质疑 //  if (!(trx_sys->rseg_history_len % srv_purge_batch_size)) { /*should wake up always*/         /* Inform the […]