Check return value of TableBuilder::Add() in compaction routine.
This is a prospective fix for the crash described in crbug.com/326566884. Inspection of the crash dump suggests that `Add()` is failing, but the compaction routine is continuing to run. While it's not entirely clear how precisely this leads to the observed failure mode, it seems safer to check the status of the TableBuilder and abort early as needed.
This commit is contained in:
parent
068d5ee1a3
commit
80d6c09fa4
@ -998,7 +998,12 @@ Status DBImpl::DoCompactionWork(CompactionState* compact) {
|
|||||||
compact->current_output()->smallest.DecodeFrom(key);
|
compact->current_output()->smallest.DecodeFrom(key);
|
||||||
}
|
}
|
||||||
compact->current_output()->largest.DecodeFrom(key);
|
compact->current_output()->largest.DecodeFrom(key);
|
||||||
compact->builder->Add(key, input->value());
|
|
||||||
|
status = compact->builder->Add(key, input->value());
|
||||||
|
if (!status.ok()) {
|
||||||
|
FinishCompactionOutputFile(compact, input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Close output file if it is big enough
|
// Close output file if it is big enough
|
||||||
if (compact->builder->FileSize() >=
|
if (compact->builder->FileSize() >=
|
||||||
|
@ -49,7 +49,7 @@ class LEVELDB_EXPORT TableBuilder {
|
|||||||
// Add key,value to the table being constructed.
|
// Add key,value to the table being constructed.
|
||||||
// REQUIRES: key is after any previously added key according to comparator.
|
// REQUIRES: key is after any previously added key according to comparator.
|
||||||
// REQUIRES: Finish(), Abandon() have not been called
|
// REQUIRES: Finish(), Abandon() have not been called
|
||||||
void Add(const Slice& key, const Slice& value);
|
Status Add(const Slice& key, const Slice& value);
|
||||||
|
|
||||||
// Advanced operation: flush any buffered key/value pairs to file.
|
// Advanced operation: flush any buffered key/value pairs to file.
|
||||||
// Can be used to ensure that two adjacent entries never live in
|
// Can be used to ensure that two adjacent entries never live in
|
||||||
|
@ -91,10 +91,12 @@ Status TableBuilder::ChangeOptions(const Options& options) {
|
|||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableBuilder::Add(const Slice& key, const Slice& value) {
|
Status TableBuilder::Add(const Slice& key, const Slice& value) {
|
||||||
Rep* r = rep_;
|
Rep* r = rep_;
|
||||||
assert(!r->closed);
|
assert(!r->closed);
|
||||||
if (!ok()) return;
|
if (!ok()) {
|
||||||
|
return status();
|
||||||
|
}
|
||||||
if (r->num_entries > 0) {
|
if (r->num_entries > 0) {
|
||||||
assert(r->options.comparator->Compare(key, Slice(r->last_key)) > 0);
|
assert(r->options.comparator->Compare(key, Slice(r->last_key)) > 0);
|
||||||
}
|
}
|
||||||
@ -120,6 +122,7 @@ void TableBuilder::Add(const Slice& key, const Slice& value) {
|
|||||||
if (estimated_block_size >= r->options.block_size) {
|
if (estimated_block_size >= r->options.block_size) {
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
|
return status();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableBuilder::Flush() {
|
void TableBuilder::Flush() {
|
||||||
|
Loading…
Reference in New Issue
Block a user