bugfix: MemTableList::RemoveOldMemTables invalid iterator after remov… (#6013)

Summary:
Fix issue https://github.com/facebook/rocksdb/issues/6012.

I found that it may be caused by the following codes in function _RemoveOldMemTables()_ in **db/memtable_list.cc**  :
```
  for (auto it = memlist.rbegin(); it != memlist.rend(); ++it) {
    MemTable* mem = *it;
    if (mem->GetNextLogNumber() > log_number) {
      break;
    }
    current_->Remove(mem, to_delete);
```

The iterator **it** turns invalid after `current_->Remove(mem, to_delete);`
Pull Request resolved: https://github.com/facebook/rocksdb/pull/6013

Test Plan:
```
make check
```

Differential Revision: D18401107

Pulled By: riversand963

fbshipit-source-id: bf0da3b868ed70f7aff24cf7b3e2049c0c5c7a4e
This commit is contained in:
蔡渠棠 2019-11-11 15:56:07 -08:00 committed by Facebook Github Bot
parent c17384fea4
commit f29e6b3be2
1 changed files with 7 additions and 0 deletions

View File

@ -736,17 +736,24 @@ void MemTableList::RemoveOldMemTables(uint64_t log_number,
assert(to_delete != nullptr); assert(to_delete != nullptr);
InstallNewVersion(); InstallNewVersion();
auto& memlist = current_->memlist_; auto& memlist = current_->memlist_;
autovector<MemTable*> old_memtables;
for (auto it = memlist.rbegin(); it != memlist.rend(); ++it) { for (auto it = memlist.rbegin(); it != memlist.rend(); ++it) {
MemTable* mem = *it; MemTable* mem = *it;
if (mem->GetNextLogNumber() > log_number) { if (mem->GetNextLogNumber() > log_number) {
break; break;
} }
old_memtables.push_back(mem);
}
for (auto it = old_memtables.begin(); it != old_memtables.end(); ++it) {
MemTable* mem = *it;
current_->Remove(mem, to_delete); current_->Remove(mem, to_delete);
--num_flush_not_started_; --num_flush_not_started_;
if (0 == num_flush_not_started_) { if (0 == num_flush_not_started_) {
imm_flush_needed.store(false, std::memory_order_release); imm_flush_needed.store(false, std::memory_order_release);
} }
} }
UpdateMemoryUsageExcludingLast(); UpdateMemoryUsageExcludingLast();
ResetTrimHistoryNeeded(); ResetTrimHistoryNeeded();
} }