@@ -826,6 +826,9 @@ Status DBImpl::Recover(
826
826
}
827
827
828
828
Status s = versions_->Recover (column_families);
829
+ if (options_.paranoid_checks && s.ok ()) {
830
+ s = CheckConsistency ();
831
+ }
829
832
if (s.ok ()) {
830
833
SequenceNumber max_sequence (0 );
831
834
default_cf_handle_ = new ColumnFamilyHandleImpl (
@@ -1211,14 +1214,14 @@ Status DBImpl::FlushMemTableToOutputFile(ColumnFamilyData* cfd,
1211
1214
1212
1215
if (!s.ok ()) {
1213
1216
cfd->imm ()->RollbackMemtableFlush (mems, file_number, &pending_outputs_);
1214
- return s;
1217
+ } else {
1218
+ // Replace immutable memtable with the generated Table
1219
+ s = cfd->imm ()->InstallMemtableFlushResults (
1220
+ cfd, mems, versions_.get (), &mutex_, options_.info_log .get (),
1221
+ file_number, pending_outputs_, &deletion_state.memtables_to_free ,
1222
+ db_directory_.get ());
1215
1223
}
1216
1224
1217
- // Replace immutable memtable with the generated Table
1218
- s = cfd->imm ()->InstallMemtableFlushResults (
1219
- cfd, mems, versions_.get (), &mutex_, options_.info_log .get (), file_number,
1220
- pending_outputs_, &deletion_state.memtables_to_free , db_directory_.get ());
1221
-
1222
1225
if (s.ok ()) {
1223
1226
InstallSuperVersion (cfd, deletion_state);
1224
1227
if (madeProgress) {
@@ -1236,6 +1239,13 @@ Status DBImpl::FlushMemTableToOutputFile(ColumnFamilyData* cfd,
1236
1239
}
1237
1240
}
1238
1241
}
1242
+
1243
+ if (!s.ok () && !s.IsShutdownInProgress () && options_.paranoid_checks &&
1244
+ bg_error_.ok ()) {
1245
+ // if a bad error happened (not ShutdownInProgress) and paranoid_checks is
1246
+ // true, mark DB read-only
1247
+ bg_error_ = s;
1248
+ }
1239
1249
return s;
1240
1250
}
1241
1251
@@ -3955,6 +3965,33 @@ void DBImpl::GetLiveFilesMetaData(std::vector<LiveFileMetaData>* metadata) {
3955
3965
versions_->GetLiveFilesMetaData (metadata);
3956
3966
}
3957
3967
3968
+ Status DBImpl::CheckConsistency () {
3969
+ mutex_.AssertHeld ();
3970
+ std::vector<LiveFileMetaData> metadata;
3971
+ versions_->GetLiveFilesMetaData (&metadata);
3972
+
3973
+ std::string corruption_messages;
3974
+ for (const auto & md : metadata) {
3975
+ std::string file_path = dbname_ + md.name ;
3976
+ uint64_t fsize = 0 ;
3977
+ Status s = env_->GetFileSize (file_path, &fsize);
3978
+ if (!s.ok ()) {
3979
+ corruption_messages +=
3980
+ " Can't access " + md.name + " : " + s.ToString () + " \n " ;
3981
+ } else if (fsize != md.size ) {
3982
+ corruption_messages += " Sst file size mismatch: " + md.name +
3983
+ " . Size recorded in manifest " +
3984
+ std::to_string (md.size ) + " , actual size " +
3985
+ std::to_string (fsize) + " \n " ;
3986
+ }
3987
+ }
3988
+ if (corruption_messages.size () == 0 ) {
3989
+ return Status::OK ();
3990
+ } else {
3991
+ return Status::Corruption (corruption_messages);
3992
+ }
3993
+ }
3994
+
3958
3995
void DBImpl::TEST_GetFilesMetaData (
3959
3996
ColumnFamilyHandle* column_family,
3960
3997
std::vector<std::vector<FileMetaData>>* metadata) {
0 commit comments