diff --git a/db/pdfile.h b/db/pdfile.h index 19d75c8a41b..7ef25a3e0a1 100644 --- a/db/pdfile.h +++ b/db/pdfile.h @@ -114,6 +114,17 @@ public: DiskLoc firstRecord, lastRecord; char extentData[4]; + bool validates() { + return !(firstRecord.isNull() ^ lastRecord.isNull()) && + length >= 0 && !myLoc.isNull(); + } + + void dump(iostream& s) { + s << " loc:" << myLoc.toString() << " xnext:" << xnext.toString() << " xprev:" << xprev.toString() << '\n'; + s << " ns:" << ns.buf << '\n'; + s << " size:" << length << " firstRecord:" << firstRecord.toString() << " lastRecord:" << lastRecord.toString() << '\n'; + } + /* assumes already zeroed -- insufficient for block 'reuse' perhaps Returns a DeletedRecord location which is the data in the extent ready for us. Caller will need to add that to the freelist structure in namespacedetail. diff --git a/db/query.cpp b/db/query.cpp index 109257408f6..80f4bbf316c 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -332,14 +332,23 @@ void clean(const char *ns, NamespaceDetails *d) { } string validateNS(const char *ns, NamespaceDetails *d) { + bool valid = true; stringstream ss; - ss << "\nvalidate "; + ss << "\nvalidate\n"; if( d->capped ) - cout << " capped:" << d->capped << " max:" << d->max; - ss << "\n"; + ss << " capped:" << d->capped << " max:" << d->max << '\n'; + + ss << " firstExtent:" << d->firstExtent.toString() << " lastExtent:" << d->lastExtent.toString() << '\n'; + ss << " datasize?:" << d->datasize << " nrecords?:" << d->nrecords << " lastExtentSize:" << d->lastExtentSize << '\n'; try { + { + ss << " first extent:\n"; + d->firstExtent.ext()->dump(ss); + valid = valid && d->firstExtent.ext()->validates(); + } + auto_ptr c = theDataFileMgr.findAll(ns); int n = 0; long long len = 0; @@ -390,6 +399,9 @@ string validateNS(const char *ns, NamespaceDetails *d) { ss << "\n exception during validate\n" << endl; } + if( !valid ) + ss << " ns corrupt, requires dbchk\n"; + return ss.str(); }