| 288 | } |
| 289 | |
| 290 | Status DBImpl::Recover(VersionEdit* edit, bool* save_manifest) { |
| 291 | mutex_.AssertHeld(); |
| 292 | |
| 293 | // Ignore error from CreateDir since the creation of the DB is |
| 294 | // committed only when the descriptor is created, and this directory |
| 295 | // may already exist from a previous failed creation attempt. |
| 296 | env_->CreateDir(dbname_); |
| 297 | assert(db_lock_ == nullptr); |
| 298 | Status s = env_->LockFile(LockFileName(dbname_), &db_lock_); |
| 299 | if (!s.ok()) { |
| 300 | return s; |
| 301 | } |
| 302 | |
| 303 | if (!env_->FileExists(CurrentFileName(dbname_))) { |
| 304 | if (options_.create_if_missing) { |
| 305 | s = NewDB(); |
| 306 | if (!s.ok()) { |
| 307 | return s; |
| 308 | } |
| 309 | } else { |
| 310 | return Status::InvalidArgument( |
| 311 | dbname_, "does not exist (create_if_missing is false)"); |
| 312 | } |
| 313 | } else { |
| 314 | if (options_.error_if_exists) { |
| 315 | return Status::InvalidArgument(dbname_, |
| 316 | "exists (error_if_exists is true)"); |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | s = versions_->Recover(save_manifest); |
| 321 | if (!s.ok()) { |
| 322 | return s; |
| 323 | } |
| 324 | SequenceNumber max_sequence(0); |
| 325 | |
| 326 | // Recover from all newer log files than the ones named in the |
| 327 | // descriptor (new log files may have been added by the previous |
| 328 | // incarnation without registering them in the descriptor). |
| 329 | // |
| 330 | // Note that PrevLogNumber() is no longer used, but we pay |
| 331 | // attention to it in case we are recovering a database |
| 332 | // produced by an older version of leveldb. |
| 333 | const uint64_t min_log = versions_->LogNumber(); |
| 334 | const uint64_t prev_log = versions_->PrevLogNumber(); |
| 335 | std::vector<std::string> filenames; |
| 336 | s = env_->GetChildren(dbname_, &filenames); |
| 337 | if (!s.ok()) { |
| 338 | return s; |
| 339 | } |
| 340 | std::set<uint64_t> expected; |
| 341 | versions_->AddLiveFiles(&expected); |
| 342 | uint64_t number; |
| 343 | FileType type; |
| 344 | std::vector<uint64_t> logs; |
| 345 | for (size_t i = 0; i < filenames.size(); i++) { |
| 346 | if (ParseFileName(filenames[i], &number, &type)) { |
| 347 | expected.erase(number); |