From dbd19cb48e4641157668c91f4f9d2e0869aba6be Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Mon, 29 Aug 2016 12:42:32 +0200 Subject: [PATCH] hexify corrupted markers --- arangod/VocBase/datafile.cpp | 64 ++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/arangod/VocBase/datafile.cpp b/arangod/VocBase/datafile.cpp index 40e3ad6464..c72d501652 100644 --- a/arangod/VocBase/datafile.cpp +++ b/arangod/VocBase/datafile.cpp @@ -34,6 +34,7 @@ #include "VocBase/server.h" #include +#include // #define DEBUG_DATAFILE 1 @@ -756,7 +757,7 @@ static bool CheckDatafile(TRI_datafile_t* datafile, bool ignoreFailures) { bool nextMarkerOk = false; if (size > 0) { - auto next = reinterpret_cast(marker) + size; + auto next = reinterpret_cast(marker) + DatafileHelper::AlignedSize(size); auto p = next; if (p < end) { @@ -783,7 +784,7 @@ static bool CheckDatafile(TRI_datafile_t* datafile, bool ignoreFailures) { // there is a next marker auto nextMarker = reinterpret_cast(next); - + if (nextMarker->getType() != 0 && nextMarker->getSize() >= sizeof(TRI_df_marker_t) && next + nextMarker->getSize() <= end && @@ -810,10 +811,67 @@ static bool CheckDatafile(TRI_datafile_t* datafile, bool ignoreFailures) { datafile->_next = datafile->_data + datafile->_currentSize; datafile->_state = TRI_DF_STATE_OPEN_ERROR; - LOG(WARN) << "crc mismatch found in datafile '" << datafile->getName(datafile) << "' at position " << currentSize << ". expected crc: " << CalculateCrcValue(marker) << ", actual crc: " << marker->getCrc(); + LOG(WARN) << "crc mismatch found in datafile '" << datafile->getName(datafile) << "' of size " + << datafile->_maximalSize << ", at position " << currentSize; + + LOG(WARN) << "crc mismatch found inside marker of type '" << TRI_NameMarkerDatafile(marker) + << "' and size " << size + << ". expected crc: " << CalculateCrcValue(marker) << ", actual crc: " << marker->getCrc(); + + { + LOG(INFO) << "raw marker data following:"; + char const* p = reinterpret_cast(marker); + char const* e = reinterpret_cast(marker) + DatafileHelper::AlignedSize(size); + std::string line; + std::string raw; + size_t printed = 0; + while (p < e) { + // print offset + line.append("0x"); + uintptr_t offset = static_cast(p - datafile->_data); + for (size_t i = 0; i < 8; ++i) { + uint8_t c = static_cast((offset & (0xFFULL << 8 * (7 - i))) >> 8 * (7 - i)); + uint8_t n1 = c >> 4; + uint8_t n2 = c & 0x0F; + + line.push_back((n1 < 10) ? ('0' + n1) : 'A' + n1 - 10); + line.push_back((n2 < 10) ? ('0' + n2) : 'A' + n2 - 10); + } + + // print data + line.append(": "); + for (size_t i = 0; i < 16; ++i) { + if (p >= e) { + line.append(" "); + } else { + uint8_t c = static_cast(*p++); + uint8_t n1 = c >> 4; + uint8_t n2 = c & 0x0F; + + line.push_back((n1 < 10) ? ('0' + n1) : 'A' + n1 - 10); + line.push_back((n2 < 10) ? ('0' + n2) : 'A' + n2 - 10); + line.push_back(' '); + + raw.push_back((c < 32 || c >= 127) ? '.' : static_cast(c)); + + ++printed; + } + } + + LOG(INFO) << line << " " << raw; + line.clear(); + raw.clear(); + + if (printed >= 2048) { + LOG(INFO) << "(output truncated due to excessive length)"; + break; + } + } + } if (nextMarkerOk) { LOG(INFO) << "data directly following this marker looks ok so repairing the marker may recover it"; + LOG(INFO) << "please restart the server with the parameter '--wal.ignore-logfile-errors true' to repair the marker"; } else { LOG(WARN) << "data directly following this marker cannot be analyzed"; }