Allow mutex to be released in GetAggregatedIntProperty (#7412)

Summary:
Current implementation holds db mutex while calling
`GetAggregatedIntProperty()`. For property kEstimateTableReadersMem,
this can be expensive, especially if the number of table readers is
high.
We can release and re-acquire db mutex if
property_info.need_out_of_mutex is true.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/7412

Test Plan:
make check
COMPILE_WITH_ASAN=1 make check
COMPILE_WITH_TSAN=1 make check
Also test internally on a shadow host. Used bpf to verify the
excessively long db mutex holding no longer exists when applications
call GetApproximateMemoryUsageByType().

Reviewed By: jay-zhuang

Differential Revision: D23794824

Pulled By: riversand963

fbshipit-source-id: 6bc02a59fd25613d343a62cf817467c7122c9721
main
Yanqin Jin 4 years ago committed by Facebook GitHub Bot
parent 29f7bbef99
commit cd72f8974b
  1. 25
      db/db_impl/db_impl.cc

@ -3135,17 +3135,17 @@ bool DBImpl::GetIntPropertyInternal(ColumnFamilyData* cfd,
} }
} else { } else {
SuperVersion* sv = nullptr; SuperVersion* sv = nullptr;
if (!is_locked) { if (is_locked) {
sv = GetAndRefSuperVersion(cfd); mutex_.Unlock();
} else {
sv = cfd->GetSuperVersion();
} }
sv = GetAndRefSuperVersion(cfd);
bool ret = cfd->internal_stats()->GetIntPropertyOutOfMutex( bool ret = cfd->internal_stats()->GetIntPropertyOutOfMutex(
property_info, sv->current, value); property_info, sv->current, value);
if (!is_locked) { ReturnAndCleanupSuperVersion(cfd, sv);
ReturnAndCleanupSuperVersion(cfd, sv); if (is_locked) {
mutex_.Lock();
} }
return ret; return ret;
@ -3182,6 +3182,7 @@ bool DBImpl::GetAggregatedIntProperty(const Slice& property,
} }
uint64_t sum = 0; uint64_t sum = 0;
bool ret = true;
{ {
// Needs mutex to protect the list of column families. // Needs mutex to protect the list of column families.
InstrumentedMutexLock l(&mutex_); InstrumentedMutexLock l(&mutex_);
@ -3190,15 +3191,21 @@ bool DBImpl::GetAggregatedIntProperty(const Slice& property,
if (!cfd->initialized()) { if (!cfd->initialized()) {
continue; continue;
} }
if (GetIntPropertyInternal(cfd, *property_info, true, &value)) { cfd->Ref();
ret = GetIntPropertyInternal(cfd, *property_info, true, &value);
// GetIntPropertyInternal may release db mutex and re-acquire it.
mutex_.AssertHeld();
cfd->UnrefAndTryDelete();
if (ret) {
sum += value; sum += value;
} else { } else {
return false; ret = false;
break;
} }
} }
} }
*aggregated_value = sum; *aggregated_value = sum;
return true; return ret;
} }
SuperVersion* DBImpl::GetAndRefSuperVersion(ColumnFamilyData* cfd) { SuperVersion* DBImpl::GetAndRefSuperVersion(ColumnFamilyData* cfd) {

Loading…
Cancel
Save