代码实现
MySQL无锁优化特性新增类如表1所示。
trx_lists_init_at_db_start的变化:在数据库启动期间,用生命周期为trx_lists_init_at_db_start的TrxIdSet,实现原本的全局TrxIdSet的功能,主要是trx_resurrect中“Ressurrect transactions that were doing updates”时根据trxid避免重复创建trx实例。
trx_reference的变化:使用原子操作,替代原本的mutex保护。
trx_erase_lists的变化:将trx_sys->mutex临界区里的rw_trx_set.erase操作从临界区移除。
trx_release_impl_and_expl_locks的变化:
- 在trx_sys->mutex临界区外,增加trx_sys->rw_trx_hash.erase,替代原本trx_erase_lists中的rw_trx_set.erase。
- 同时为保证 rw_trx_hash 仅包含PREPARED或ACTIVE状态的事务,将trx_release_impl_and_expl_locks中的trx->state = TRX_STATE_COMMITTED_IN_MEMORY移出trx_sys->mutex临界区。
- 原始代码包含如下注释说明:
由于已将trx->state = TRX_STATE_COMMITTED_IN_MEMORY移出trx_sys->mutex临界区,方法(1)不再成立。因此,方法(1)的使用者lock_rec_convert_impl_to_expl可能会看到trx已被移出rw_trx_hash,但状态还未设成TRX_STATE_COMMITTED_IN_MEMORY。此时lock_rec_convert_impl_to_expl的正确性由如下保证:
- 在lock_rec_convert_impl_to_expl的上下文中,trx不存在于rw_trx_hash,等同于原逻辑的!trx_rw_is_active()。
- lock_rec_convert_impl_to_expl最终会通过lock_rec_convert_impl_to_expl_for_trx再次确认事务状态,即注释中的“deciding for the final time if we really want to create explicit lock on behalf of implicit lock holder”。
trx_rw_is_active和trx_rw_is_active_low的变化:删除接口,使用rw_trx_hash.find替代。
trx_get_rw_trx_by_id的变化:删除接口,使用rw_trx_hash.find替代。
trx_assert_recovered的变化:未被使用的接口,删除。
trx_sys_rw_trx_add的变化:语义有误的接口,删除。使用rw_trx_hash.insert替代。
rec_queue_validate_latched的变化:由于trx_release_impl_and_expl_locks的变化,采用类似lock_rec_convert_impl_to_expl_for_trx的方式确认事务状态。