fix: split metrics could fail an assert in a very rare scenario
This commit is contained in:
parent
0e7d538c94
commit
370e8a9903
|
@ -269,7 +269,7 @@ struct StorageServerMetrics {
|
||||||
|
|
||||||
// This function can run on untrusted user data. We must validate all divisions carefully.
|
// This function can run on untrusted user data. We must validate all divisions carefully.
|
||||||
KeyRef getSplitKey( int64_t remaining, int64_t estimated, int64_t limits, int64_t used, int64_t infinity,
|
KeyRef getSplitKey( int64_t remaining, int64_t estimated, int64_t limits, int64_t used, int64_t infinity,
|
||||||
bool isLastShard, StorageMetricSample& sample, double divisor, KeyRef const& lastKey, KeyRef const& key )
|
bool isLastShard, StorageMetricSample& sample, double divisor, KeyRef const& lastKey, KeyRef const& key, bool hasUsed )
|
||||||
{
|
{
|
||||||
ASSERT(remaining >= 0);
|
ASSERT(remaining >= 0);
|
||||||
ASSERT(limits > 0);
|
ASSERT(limits > 0);
|
||||||
|
@ -290,7 +290,7 @@ struct StorageServerMetrics {
|
||||||
// This does the conversion from native units to bytes using the divisor.
|
// This does the conversion from native units to bytes using the divisor.
|
||||||
double offset = (expectedSize - used) / divisor;
|
double offset = (expectedSize - used) / divisor;
|
||||||
if( offset <= 0 )
|
if( offset <= 0 )
|
||||||
return lastKey;
|
return hasUsed ? lastKey : key;
|
||||||
return sample.splitEstimate( KeyRangeRef(lastKey, key), offset * ( ( 1.0 - SERVER_KNOBS->SPLIT_JITTER_AMOUNT ) + 2 * g_random->random01() * SERVER_KNOBS->SPLIT_JITTER_AMOUNT ) );
|
return sample.splitEstimate( KeyRangeRef(lastKey, key), offset * ( ( 1.0 - SERVER_KNOBS->SPLIT_JITTER_AMOUNT ) + 2 * g_random->random01() * SERVER_KNOBS->SPLIT_JITTER_AMOUNT ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -312,16 +312,16 @@ struct StorageServerMetrics {
|
||||||
if( remaining.bytes < 2*SERVER_KNOBS->MIN_SHARD_BYTES )
|
if( remaining.bytes < 2*SERVER_KNOBS->MIN_SHARD_BYTES )
|
||||||
break;
|
break;
|
||||||
KeyRef key = req.keys.end;
|
KeyRef key = req.keys.end;
|
||||||
|
bool hasUsed = used.bytes != 0 || used.bytesPerKSecond != 0 || used.iosPerKSecond != 0;
|
||||||
key = getSplitKey( remaining.bytes, estimated.bytes, req.limits.bytes, used.bytes,
|
key = getSplitKey( remaining.bytes, estimated.bytes, req.limits.bytes, used.bytes,
|
||||||
req.limits.infinity, req.isLastShard, byteSample, 1, lastKey, key );
|
req.limits.infinity, req.isLastShard, byteSample, 1, lastKey, key, hasUsed );
|
||||||
if( used.bytes < SERVER_KNOBS->MIN_SHARD_BYTES )
|
if( used.bytes < SERVER_KNOBS->MIN_SHARD_BYTES )
|
||||||
key = std::max( key, byteSample.splitEstimate( KeyRangeRef(lastKey, req.keys.end), SERVER_KNOBS->MIN_SHARD_BYTES - used.bytes ) );
|
key = std::max( key, byteSample.splitEstimate( KeyRangeRef(lastKey, req.keys.end), SERVER_KNOBS->MIN_SHARD_BYTES - used.bytes ) );
|
||||||
key = getSplitKey( remaining.iosPerKSecond, estimated.iosPerKSecond, req.limits.iosPerKSecond, used.iosPerKSecond,
|
key = getSplitKey( remaining.iosPerKSecond, estimated.iosPerKSecond, req.limits.iosPerKSecond, used.iosPerKSecond,
|
||||||
req.limits.infinity, req.isLastShard, iopsSample, SERVER_KNOBS->STORAGE_METRICS_AVERAGE_INTERVAL_PER_KSECONDS, lastKey, key );
|
req.limits.infinity, req.isLastShard, iopsSample, SERVER_KNOBS->STORAGE_METRICS_AVERAGE_INTERVAL_PER_KSECONDS, lastKey, key, hasUsed );
|
||||||
key = getSplitKey( remaining.bytesPerKSecond, estimated.bytesPerKSecond, req.limits.bytesPerKSecond, used.bytesPerKSecond,
|
key = getSplitKey( remaining.bytesPerKSecond, estimated.bytesPerKSecond, req.limits.bytesPerKSecond, used.bytesPerKSecond,
|
||||||
req.limits.infinity, req.isLastShard, bandwidthSample, SERVER_KNOBS->STORAGE_METRICS_AVERAGE_INTERVAL_PER_KSECONDS, lastKey, key );
|
req.limits.infinity, req.isLastShard, bandwidthSample, SERVER_KNOBS->STORAGE_METRICS_AVERAGE_INTERVAL_PER_KSECONDS, lastKey, key, hasUsed );
|
||||||
ASSERT( key != lastKey || used.bytes != 0 || used.bytesPerKSecond != 0 || used.iosPerKSecond != 0);
|
ASSERT( key != lastKey || hasUsed);
|
||||||
if( key == req.keys.end )
|
if( key == req.keys.end )
|
||||||
break;
|
break;
|
||||||
reply.splits.push_back_deep( reply.splits.arena(), key );
|
reply.splits.push_back_deep( reply.splits.arena(), key );
|
||||||
|
|
Loading…
Reference in New Issue