307 字 | 1 分钟

_mutex之间

多个class的_mutex存在调用关系链,必须避免死锁问题。

例如,SessionCtx::commitAll存在多个锁的嵌套调用。

  1. SessionCtx::commitAll
  2. std::lock_guard<std::mutex> lk(SessionCtx::_mutex);
  3. RocksTxn::commit
  4. RocksKVStore::markCommitted
  5. std::lock_guard<std::mutex> lk(RocksKVStore::_mutex);

也就是说,不能存在上锁顺序为RocksKVStore::_mutex->SessionCtx::_mutex的调用关系,否则就可能死锁。

其他情况包括:

  1. SessionCtx::rollbackAll
  2. std::lock_guard<std::mutex> lk(SessionCtx::_mutex);
  3. RocksTxn::rollback
  4. RocksKVStore::markCommitted
  5. std::lock_guard<std::mutex> lk(RocksKVStore::_mutex);
  6. ReplManager::recycleBinlog
  7. std::lock_guard<std::mutex> lk(*ReplManager::_logRecycleMutex[storeId].get());
  8. ReplManager::getCurBinlogFs
  9. std::unique_lock<std::mutex> lk(ReplManager::_mutex);
  10. ReplManager::updateCurBinlogFs
  11. std::unique_lock<std::mutex> lk(ReplManager::_mutex);
  12. ReplManager::flushCurBinlogFs
  13. ReplManager::updateCurBinlogFs
  14. std::unique_lock<std::mutex> lk(ReplManager::_mutex);
  15. ServerEntry::resetServerStat
  16. std::lock_guard<std::mutex> lk(ServerEntry::_mutex);
  17. ServerStat::reset()
  18. std::lock_guard<std::mutex> lk(ServerStat::_mutex);
  19. ServerEntry::addSession
  20. std::lock_guard<std::mutex> lk(ServerEntry::_mutex);
  21. NetSession::start
  22. std::lock_guard<std::mutex> lk(NetSession::_mutex);
  23. ServerEntry::replyMonitors
  24. std::lock_guard<std::mutex> lk(ServerEntry::_mutex);
  25. NetSession::setResponse()
  26. std::lock_guard<std::mutex> lk(NetSession::_mutex);

目前,允许的嵌套调用关系为

  1. SessionCtx::_mutex -> RocksKVStore::_mutex
  2. ReplManager::_logRecycleMutex[storeId] -> ReplManager::_mutex
  3. ServerEntry::_mutex -> ServerStat::_mutex
  4. ServerEntry::_mutex -> NetSession::_mutex

LOCK_* 和 _mutex

约定,必须先锁逻辑锁(LOCK_*)之后才能对_mutex上锁。

例如

  1. ReplManager::changeReplSource
  2. auto expdb = _svr->getSegmentMgr()->getDb(sess, storeId,mgl::LockMode::LOCK_X, true);
  3. changeReplSourceInLock
  4. std::unique_lock<std::mutex> lk(ReplManager::_mutex);

不允许先lock(_mutex),再getDB