|
I discussed this with Geert offline. In summary, it's risky to try to continue parsing BSON that we know is corrupt. This failure mode also requires us to have a document where the _id is not positionally first. It is not possible to insert a document like this since at least MongoDB 3.6, so there are increasingly fewer cases where this is a problem.
|
|
I was able to insert a document in an instrumented build where the _id was not first, and this was the result:
// With the server started normally
|
test> db.test.insert({ a: { b: { c: { d: { e: { f: { a: { b: { c: { d: { e: { f: { a: { b: { c: { d: { e: { f: {a: { b: { c: { d: { e: { f: {} } } } } }} } } } } } } } } } } } } } } } } }, _id: 1})
|
// After restarting with --setParamter maxBSONDepth=21
|
test> db.test.validate()
|
{
|
ns: 'test.test',
|
uuid: new UUID("ca26dd7a-c38c-4f17-a3e2-590ea5d8398d"),
|
nInvalidDocuments: 1,
|
nNonCompliantDocuments: 0,
|
nrecords: 2,
|
nIndexes: 1,
|
keysPerIndex: { _id_: 0 },
|
indexDetails: { _id_: { valid: true } },
|
valid: false,
|
repaired: false,
|
warnings: [],
|
errors: [ 'Detected one or more invalid documents. See logs.' ],
|
extraIndexEntries: [],
|
missingIndexEntries: [],
|
corruptRecords: [ Long("3") ],
|
advice: 'A corrupt namespace has been detected. See http://dochub.mongodb.org/core/data-recovery for recovery steps.',
|
ok: 1
|
}
|
Logs:
{"t":{"$date":"2023-04-26T17:01:20.440+00:00"},"s":"I", "c":"STORAGE", "id":4835001, "ctx":"conn2","msg":"Document corruption details - Document validation failed with error","attr":{"recordId":"3","error":{"code
|
":15,"codeName":"Overflow","errmsg":"BSONObj exceeds maximum nested object depth in element with field name 'a.b.c.d.e.f.a.b.c.d.e.f.a.b.c.d.e.f.a.b.c.d' in object with unknown _id"}}}
|
This was what I changed to insert the document:
diff --git a/src/mongo/db/ops/insert.cpp b/src/mongo/db/ops/insert.cpp
|
index 814ee91d196..04d3853c417 100644
|
--- a/src/mongo/db/ops/insert.cpp
|
+++ b/src/mongo/db/ops/insert.cpp
|
@@ -143,6 +143,7 @@ StatusWith<BSONObj> fixDocumentForInsert(OperationContext* opCtx,
|
}
|
}
|
|
+ validationDisabled = true;
|
if (validationDisabled || (firstElementIsId && !hasTimestampToFix))
|
return StatusWith<BSONObj>(BSONObj());
|
So BSON validation does not report the _id if it is not first.
|