307 字 | 1 分钟
_mutex之间
多个class的_mutex存在调用关系链,必须避免死锁问题。
例如,SessionCtx::commitAll存在多个锁的嵌套调用。
SessionCtx::commitAll
std::lock_guard<std::mutex> lk(SessionCtx::_mutex);
RocksTxn::commit
RocksKVStore::markCommitted
std::lock_guard<std::mutex> lk(RocksKVStore::_mutex);
也就是说,不能存在上锁顺序为RocksKVStore::_mutex
->SessionCtx::_mutex
的调用关系,否则就可能死锁。
其他情况包括:
SessionCtx::rollbackAll
std::lock_guard<std::mutex> lk(SessionCtx::_mutex);
RocksTxn::rollback
RocksKVStore::markCommitted
std::lock_guard<std::mutex> lk(RocksKVStore::_mutex);
ReplManager::recycleBinlog
std::lock_guard<std::mutex> lk(*ReplManager::_logRecycleMutex[storeId].get());
ReplManager::getCurBinlogFs
std::unique_lock<std::mutex> lk(ReplManager::_mutex);
ReplManager::updateCurBinlogFs
std::unique_lock<std::mutex> lk(ReplManager::_mutex);
ReplManager::flushCurBinlogFs
ReplManager::updateCurBinlogFs
std::unique_lock<std::mutex> lk(ReplManager::_mutex);
ServerEntry::resetServerStat
std::lock_guard<std::mutex> lk(ServerEntry::_mutex);
ServerStat::reset()
std::lock_guard<std::mutex> lk(ServerStat::_mutex);
ServerEntry::addSession
std::lock_guard<std::mutex> lk(ServerEntry::_mutex);
NetSession::start
std::lock_guard<std::mutex> lk(NetSession::_mutex);
ServerEntry::replyMonitors
std::lock_guard<std::mutex> lk(ServerEntry::_mutex);
NetSession::setResponse()
std::lock_guard<std::mutex> lk(NetSession::_mutex);
目前,允许的嵌套调用关系为
SessionCtx::_mutex -> RocksKVStore::_mutex
ReplManager::_logRecycleMutex[storeId] -> ReplManager::_mutex
ServerEntry::_mutex -> ServerStat::_mutex
ServerEntry::_mutex -> NetSession::_mutex
LOCK_* 和 _mutex
约定,必须先锁逻辑锁(LOCK_*)之后才能对_mutex上锁。
例如
ReplManager::changeReplSource
auto expdb = _svr->getSegmentMgr()->getDb(sess, storeId,mgl::LockMode::LOCK_X, true);
changeReplSourceInLock
std::unique_lock<std::mutex> lk(ReplManager::_mutex);
不允许先lock(_mutex)
,再getDB