@@ -317,6 +317,12 @@ BerkeleyBatch::SafeDbt::operator Dbt*()
317
317
return &m_dbt;
318
318
}
319
319
320
+ /* End of headers, beginning of key/value data */
321
+ static const char *HEADER_END = " HEADER=END" ;
322
+ /* End of key/value data */
323
+ static const char *DATA_END = " DATA=END" ;
324
+ typedef std::pair<std::vector<unsigned char >, std::vector<unsigned char > > KeyValPair;
325
+
320
326
bool BerkeleyBatch::Recover (const fs::path& file_path, void *callbackDataIn, bool (*recoverKVcallback)(void * callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename)
321
327
{
322
328
std::string filename;
@@ -342,8 +348,61 @@ bool BerkeleyBatch::Recover(const fs::path& file_path, void *callbackDataIn, boo
342
348
return false ;
343
349
}
344
350
345
- std::vector<BerkeleyEnvironment::KeyValPair> salvagedData;
346
- bool fSuccess = env->Salvage (newFilename, salvagedData);
351
+ /* *
352
+ * Salvage data from a file. The DB_AGGRESSIVE flag is being used (see berkeley DB->verify() method documentation).
353
+ * key/value pairs are appended to salvagedData which are then written out to a new wallet file.
354
+ * NOTE: reads the entire database into memory, so cannot be used
355
+ * for huge databases.
356
+ */
357
+ std::vector<KeyValPair> salvagedData;
358
+
359
+ std::stringstream strDump;
360
+
361
+ Db db (env->dbenv .get (), 0 );
362
+ result = db.verify (newFilename.c_str (), nullptr , &strDump, DB_SALVAGE | DB_AGGRESSIVE);
363
+ if (result == DB_VERIFY_BAD) {
364
+ LogPrintf (" Salvage: Database salvage found errors, all data may not be recoverable.\n " );
365
+ }
366
+ if (result != 0 && result != DB_VERIFY_BAD) {
367
+ LogPrintf (" Salvage: Database salvage failed with result %d.\n " , result);
368
+ return false ;
369
+ }
370
+
371
+ // Format of bdb dump is ascii lines:
372
+ // header lines...
373
+ // HEADER=END
374
+ // hexadecimal key
375
+ // hexadecimal value
376
+ // ... repeated
377
+ // DATA=END
378
+
379
+ std::string strLine;
380
+ while (!strDump.eof () && strLine != HEADER_END)
381
+ getline (strDump, strLine); // Skip past header
382
+
383
+ std::string keyHex, valueHex;
384
+ while (!strDump.eof () && keyHex != DATA_END) {
385
+ getline (strDump, keyHex);
386
+ if (keyHex != DATA_END) {
387
+ if (strDump.eof ())
388
+ break ;
389
+ getline (strDump, valueHex);
390
+ if (valueHex == DATA_END) {
391
+ LogPrintf (" Salvage: WARNING: Number of keys in data does not match number of values.\n " );
392
+ break ;
393
+ }
394
+ salvagedData.push_back (make_pair (ParseHex (keyHex), ParseHex (valueHex)));
395
+ }
396
+ }
397
+
398
+ bool fSuccess ;
399
+ if (keyHex != DATA_END) {
400
+ LogPrintf (" Salvage: WARNING: Unexpected end of file while reading salvage output.\n " );
401
+ fSuccess = false ;
402
+ } else {
403
+ fSuccess = (result == 0 );
404
+ }
405
+
347
406
if (salvagedData.empty ())
348
407
{
349
408
LogPrintf (" Salvage(aggressive) found no records in %s.\n " , newFilename);
@@ -365,7 +424,7 @@ bool BerkeleyBatch::Recover(const fs::path& file_path, void *callbackDataIn, boo
365
424
}
366
425
367
426
DbTxn* ptxn = env->TxnBegin ();
368
- for (BerkeleyEnvironment:: KeyValPair& row : salvagedData)
427
+ for (KeyValPair& row : salvagedData)
369
428
{
370
429
if (recoverKVcallback)
371
430
{
@@ -420,64 +479,6 @@ bool BerkeleyBatch::VerifyDatabaseFile(const fs::path& file_path, bilingual_str&
420
479
return true ;
421
480
}
422
481
423
- /* End of headers, beginning of key/value data */
424
- static const char *HEADER_END = " HEADER=END" ;
425
- /* End of key/value data */
426
- static const char *DATA_END = " DATA=END" ;
427
-
428
- bool BerkeleyEnvironment::Salvage (const std::string& strFile, std::vector<BerkeleyEnvironment::KeyValPair>& vResult)
429
- {
430
- LOCK (cs_db);
431
- assert (mapFileUseCount.count (strFile) == 0 );
432
-
433
- std::stringstream strDump;
434
-
435
- Db db (dbenv.get (), 0 );
436
- int result = db.verify (strFile.c_str (), nullptr , &strDump, DB_SALVAGE | DB_AGGRESSIVE);
437
- if (result == DB_VERIFY_BAD) {
438
- LogPrintf (" BerkeleyEnvironment::Salvage: Database salvage found errors, all data may not be recoverable.\n " );
439
- }
440
- if (result != 0 && result != DB_VERIFY_BAD) {
441
- LogPrintf (" BerkeleyEnvironment::Salvage: Database salvage failed with result %d.\n " , result);
442
- return false ;
443
- }
444
-
445
- // Format of bdb dump is ascii lines:
446
- // header lines...
447
- // HEADER=END
448
- // hexadecimal key
449
- // hexadecimal value
450
- // ... repeated
451
- // DATA=END
452
-
453
- std::string strLine;
454
- while (!strDump.eof () && strLine != HEADER_END)
455
- getline (strDump, strLine); // Skip past header
456
-
457
- std::string keyHex, valueHex;
458
- while (!strDump.eof () && keyHex != DATA_END) {
459
- getline (strDump, keyHex);
460
- if (keyHex != DATA_END) {
461
- if (strDump.eof ())
462
- break ;
463
- getline (strDump, valueHex);
464
- if (valueHex == DATA_END) {
465
- LogPrintf (" BerkeleyEnvironment::Salvage: WARNING: Number of keys in data does not match number of values.\n " );
466
- break ;
467
- }
468
- vResult.push_back (make_pair (ParseHex (keyHex), ParseHex (valueHex)));
469
- }
470
- }
471
-
472
- if (keyHex != DATA_END) {
473
- LogPrintf (" BerkeleyEnvironment::Salvage: WARNING: Unexpected end of file while reading salvage output.\n " );
474
- return false ;
475
- }
476
-
477
- return (result == 0 );
478
- }
479
-
480
-
481
482
void BerkeleyEnvironment::CheckpointLSN (const std::string& strFile)
482
483
{
483
484
dbenv->txn_checkpoint (0 , 0 , 0 );
0 commit comments