mirror of https://gitee.com/bigwinds/arangodb
add defensive coding and logging in response to a divide by zero. ColumnFamilyData::RecalculateWriteStallConditions() called SetBytePerSecond() with some value less than four. Could have been a race condition due to our SetThrottle() called without db mutex. No proof, just likely. (#3950)
This commit is contained in:
parent
4104296fd3
commit
f6cdbcd4e8
|
@ -247,6 +247,10 @@ void RocksDBThrottle::SetThrottleWriteRate(std::chrono::microseconds Micros,
|
||||||
SetThrottle();
|
SetThrottle();
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
|
LOG_TOPIC(DEBUG, arangodb::Logger::ENGINES)
|
||||||
|
<< "SetThrottleWriteRate: Micros " << Micros.count()
|
||||||
|
<< ", Keys " << Keys << ", Bytes " << Bytes << ", IsLevel0 " << IsLevel0;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} // RocksDBThrottle::SetThrottleWriteRate
|
} // RocksDBThrottle::SetThrottleWriteRate
|
||||||
|
|
||||||
|
@ -263,6 +267,9 @@ void RocksDBThrottle::ThreadLoop() {
|
||||||
_threadCondvar.signal();
|
_threadCondvar.signal();
|
||||||
} // lock
|
} // lock
|
||||||
|
|
||||||
|
LOG_TOPIC(DEBUG, arangodb::Logger::ENGINES)
|
||||||
|
<< "ThreadLoop() started";
|
||||||
|
|
||||||
while(_threadRunning.load()) {
|
while(_threadRunning.load()) {
|
||||||
//
|
//
|
||||||
// start actual throttle work
|
// start actual throttle work
|
||||||
|
@ -288,6 +295,9 @@ void RocksDBThrottle::ThreadLoop() {
|
||||||
} // lock
|
} // lock
|
||||||
} // while
|
} // while
|
||||||
|
|
||||||
|
LOG_TOPIC(DEBUG, arangodb::Logger::ENGINES)
|
||||||
|
<< "ThreadLoop() ended";
|
||||||
|
|
||||||
} // RocksDBThrottle::ThreadLoop
|
} // RocksDBThrottle::ThreadLoop
|
||||||
|
|
||||||
|
|
||||||
|
@ -382,6 +392,10 @@ void RocksDBThrottle::RecalculateThrottle() {
|
||||||
if (temp_rate<1)
|
if (temp_rate<1)
|
||||||
temp_rate=1; // throttle must always have an effect
|
temp_rate=1; // throttle must always have an effect
|
||||||
|
|
||||||
|
LOG_TOPIC(DEBUG, arangodb::Logger::ENGINES)
|
||||||
|
<< "RecalculateThrottle(): old " << _throttleBps
|
||||||
|
<< ", new " << temp_rate;
|
||||||
|
|
||||||
_throttleBps=temp_rate;
|
_throttleBps=temp_rate;
|
||||||
|
|
||||||
// prepare for next interval
|
// prepare for next interval
|
||||||
|
@ -390,10 +404,17 @@ void RocksDBThrottle::RecalculateThrottle() {
|
||||||
// never had a valid throttle, and have first hint now
|
// never had a valid throttle, and have first hint now
|
||||||
_throttleBps=new_throttle;
|
_throttleBps=new_throttle;
|
||||||
|
|
||||||
|
LOG_TOPIC(DEBUG, arangodb::Logger::ENGINES)
|
||||||
|
<< "RecalculateThrottle(): first " << _throttleBps;
|
||||||
|
|
||||||
_firstThrottle=false;
|
_firstThrottle=false;
|
||||||
} // else if
|
} // else if
|
||||||
|
|
||||||
SetThrottle();
|
// This SetThrottle() call currently occurs without holding the
|
||||||
|
// rocksdb db mutex. Not safe, seen likely crash from it.
|
||||||
|
// Add back only if this becomes a pluggable WriteController with
|
||||||
|
// access to db mutex.
|
||||||
|
// SetThrottle();
|
||||||
|
|
||||||
} // !no_data && unlock _threadMutex
|
} // !no_data && unlock _threadMutex
|
||||||
|
|
||||||
|
@ -413,7 +434,9 @@ void RocksDBThrottle::SetThrottle() {
|
||||||
// this routine can get called before _internalRocksDB is set
|
// this routine can get called before _internalRocksDB is set
|
||||||
if (nullptr != _internalRocksDB) {
|
if (nullptr != _internalRocksDB) {
|
||||||
// inform write_controller_ of our new rate
|
// inform write_controller_ of our new rate
|
||||||
if (1<_throttleBps) {
|
// (column_family.cc RecalculateWriteStallConditions() makes assumptions
|
||||||
|
// that could force a divide by zero if _throttleBps is less than four ... using 100 for safety)
|
||||||
|
if (100<_throttleBps) {
|
||||||
// hard casting away of "const" ...
|
// hard casting away of "const" ...
|
||||||
if (((WriteController&)_internalRocksDB->write_controller()).max_delayed_write_rate() < _throttleBps) {
|
if (((WriteController&)_internalRocksDB->write_controller()).max_delayed_write_rate() < _throttleBps) {
|
||||||
((WriteController&)_internalRocksDB->write_controller()).set_max_delayed_write_rate(_throttleBps);
|
((WriteController&)_internalRocksDB->write_controller()).set_max_delayed_write_rate(_throttleBps);
|
||||||
|
|
Loading…
Reference in New Issue