كيفية العثور على الاستعلامات التي انتهت مهلتها في MongoDB؟
-
28-09-2020 - |
سؤال
هل من الممكن العثور على استفسارات في system.profile
- مجموعة من قاعدة بيانات MongoDB التي لم تنته بسبب انتهاء المهلة؟
لقد وجدت بعض الاستعلامات التي استمرت لفترة أطول من الوقت المحدد في $maxTimeMS
.
db.coll.find(
{ millis: {$gt: 1300}, "command.maxTimeMS": NumberLong(1300) },
{millis: 1}
).sort(
{millis: -1}
)
لكنهم لم يركضوا سوى بضعة ميلي ثانية فقط، ولم يكن لديهم مجال error
أو timeout
. هل هناك حقول تشير إلى انتهاء المهلة؟
المحلول
في مجموعة بيانات كبيرة جدًا، قمت باختبار استعلام تنتهي مهلته بعد 10 ثوانٍ:
db.collection.find({"foo": "bar"}).maxTimeMS(10000)
(في حالتي المجموعة لديها > 100 GB
من البيانات وليس هناك فهرس في هذا المجال foo
).لقد بحثت عن الاستعلام باستخدام:
db.system.profile.find({"query.query" : { "foo" : "bar" }}).limit(5).sort({ts: -1}).pretty()
ووجدت أن الحقول exception
و exceptionCode
ممتلئة ب:
"exception" : "operation exceeded time limit",
"exceptionCode" : 50,
لذلك البحث عن المجال exception
يجب أن يعطيك النتيجة المرجوة:
db.system.profile.find({ "exception" : { "$exists" : 1 } }).limit(5).sort({ts: -1}).pretty()
وإذا كنت تبحث بشكل صريح عن الاستعلامات التي انتهت مهلتها، فحاول:
db.system.profile.find( {"exceptionCode": 50} ).sort( {ts: -1} ).pretty()
نصائح أخرى
يستهدف MongoDB عمليات الإنهاء إذا تجاوز المؤشر المرتبط الحد الزمني المخصص له (maxTimeMS).أعتقد أن الملليات القليلة الإضافية تأتي من شيئين.
1) يجب أن تكون هناك عملية داخلية يتم فحصها بشكل دوري حتى تحصل على الفاصل الزمني للتحقق (على سبيل المثال كل 1 مللي ثانية)
2) ينهي MongoDB العمليات التي تتجاوز الحد الزمني المخصص لها، باستخدام نفس آلية db.killOp().يقوم MongoDB بإنهاء العملية فقط في إحدى نقاط المقاطعة المحددة لها.للوصول إلى نقطة المقاطعة قد يستغرق الأمر بضعة ملي.