אוספי לוג גדלים בלי גבול — TTL קיים אך לא הוחל עליהם
קובץ/מודול מרכזי: database/manager.py (שם כבר יש _create_profiler_indexes עם TTL), ומקום כתיבת שני האוספים. לא תלוי ב: תיקון גבולות הפתק, ולא באף PR פתוח אחר.
חשוב: המנגנון כבר קיים בקוד. הבאג הוא שהוא לא הוחל על שני האוספים הגדולים — לא שהוא חסר. זה תיקון תוספת, לא בנייה מאפס.
מקור הבדיקה: צילומי /db-health ותוכן שני האוספים (ודאי), וחיפוש TTL index בקוד שהחזיר שלושה מקומות שבהם TTL כן קיים (ודאי). הקשר ל-latency של bookmarks — השערה לא מאומתת.
הממצא (ודאי, מהצילומים)
שני אוספים גדולים בסדר גודל של מאות אלפי מסמכים, פי מאה מכל אוסף תוכן אמיתי:
| אוסף |
מסמכים |
גודל |
מה זה |
service_metrics |
435,229 |
90MB |
צבירת מדדי observability. כל רשומה request_agg עם bucket_seconds: 60 — דלי לדקה, פר endpoint |
job_runs |
305,436 |
106MB |
רשומת כל הרצת cron. הדוגמאות: predictive_sampler, sentry_poll, drive_reschedule — total_items: 0, ריצות סרק שנרשמות |
לשם השוואה: code_snippets — 1,121 מסמכים. התוכן האמיתי זעיר מול הלוגים.
הקצב מסביר את הגודל: service_metrics נכתב כל דקה × כל endpoint; job_runs נכתב בכל טיק של כל job. אלה נתונים שנוצרים אוטומטית 24/7 בלי שאף אחד קורא אותם לאחור — הם לתצוגה חיה בדשבורד בלבד.
מה שכבר קיים בקוד (ודאי, מהחיפוש)
TTL כן מיושם — על אוספים אחרים:
_create_profiler_indexes ב-database/manager.py: TTL של 7 ימים על slow_queries_log (expireAfterSeconds=604800, name: ttl_cleanup, על שדה timestamp).
attention_dismissals: TTL על expires_at (expireAfterSeconds=0 + שדה תאריך במסמך).
ensure_lock_indexes ב-main.py: TTL על expires_at/expiresAt של ה-lock collection, עם fallback רך אם היצירה נכשלת.
כלומר יש בפרויקט דפוס TTL מוכן, מוכח, ועם טיפול בכשל. הוא פשוט לא הוחל על job_runs ו-service_metrics.
מה לבדוק לפני כל תיקון (חובה — לא להניח)
- האם משהו קורא מ-
service_metrics או מ-job_runs לאחור, מעבר לתצוגת הדשבורד. אם ה-observability מחשב מגמות על חלון של שבועות, TTL אגרסיבי ימחק נתונים שהוא צריך. לאתר את כל הקוראים לפני קביעת retention.
- האם באמת אין עליהם TTL, או שיש ופג/שגוי. הצילומים מראים TTL על אוספים אחרים; צריך לוודא במפורש ששני אלה חסרים אותו, ולא להסיק מהיעדרם בצילום.
- מה ה-retention הנכון לכל אחד.
slow_queries_log נקבע ל-7 ימים (604800ש'). ל-service_metrics (תצוגה חיה) אולי מספיק פחות; ל-job_runs אולי יותר, אם יש ערך היסטורי לאבחון. החלטה של אמיר, אחרי שסעיף 1 עונה מי קורא.
הצעת התיקון (אחרי שהבדיקות עונות)
להרחיב את _create_profiler_indexes (או המקום המקביל) ולהוסיף TTL לשני האוספים, באותו דפוס שכבר קיים — כולל ה-fallback הרך של ensure_lock_indexes (אם היצירה נכשלת, לוג ו-emit_event, בלי להפיל).
# אותו דפוס כמו slow_queries_log, על שדה הזמן של כל אוסף
await self.db.service_metrics.create_index("ts", expireAfterSeconds=<retention_1>, name="ttl_cleanup")
await self.db.job_runs.create_index("started_at", expireAfterSeconds=<retention_2>, name="ttl_cleanup")
שם שדה הזמן שונה בין אוספים — וזו מלכודת: slow_queries_log משתמש ב-timestamp (אומת בתיעוד), service_metrics נראה עם ts, ו-job_runs עם started_at/ended_at. שלושה אוספים, שלושה שמות. לא לנחש — לפתוח מסמך מכל אוסף ולראות את שם השדה בפועל.
ההשערה שצריך לבדוק בנפרד (לא מאומתת)
היום אירעה תקלת latency: bookmarks.get_file_bookmarks לקח 152 שניות, ובאותו חלון גם collections.get_tags_metadata ו-api_ui_prefs. ה-JSON של ההתראה הראה שכל הבקשות האיטיות היו על אותו ObjectId (6a9054dd...), ו-db_pool_utilization: 13% — כלומר המסד לא היה רווי. זה מצביע על עיבוד נקודתי של פריט אחד, לא בהכרח על האוספים הגדולים.
מה לבדוק: האם שאילתה כלשהי — של bookmarks, collections, או אחרת — סורקת את service_metrics/job_runs בלי אינדקס מתאים. אם כן, ה-TTL גם ישפר latency (פחות מסמכים לסרוק). אם לא — ה-TTL עדיין נכון מטעמי אחסון, אבל לא יפתור את ה-latency, וזה באג נפרד.
לא להניח שהשניים קשורים. לאמת עם explain() על השאילתות האיטיות.
בדיקות
- אחרי הוספת ה-TTL, כתיבת מסמך חדש לכל אוסף → האינדקס קיים (
getIndexes() מראה expireAfterSeconds).
- מסמך עם שדה זמן ישן מה-retention → נמחק בסבב ה-TTL של מונגו (עד 60ש' לאחר התפוגה).
- מסמך טרי → לא נמחק.
- יצירת האינדקס נכשלת (הרשאה, קונפליקט) → המערכת ממשיכה, לוג +
emit_event, לא קורסת — כמו ensure_lock_indexes.
- אם סעיף 1 בבדיקות מצא קורא לאחור: לוודא שהחלון שהוא צריך קצר מה-retention.
מה לא נסגר
- מי קורא מהאוספים לאחור — סעיף 1 למעלה, חייב להיענות לפני קביעת retention.
- הקשר ל-latency — השערה, טעונה
explain().
- retention לכל אוסף — החלטת אמיר אחרי שהקוראים ידועים.
לא בסשן
- שינוי מבנה הרשומות של שני האוספים.
- שינוי בתדירות הכתיבה (הדלי לדקה, טיק ה-job) — זה מקור הנתונים, לא הבעיה.
- תיקון ה-latency עצמו אם יתברר שאינו קשור — באג נפרד.
מעדכן:
job_runs 318,797 מסמכים
service_metrics 470,040 מסמכים
אוספי לוג גדלים בלי גבול — TTL קיים אך לא הוחל עליהם
הממצא (ודאי, מהצילומים)
שני אוספים גדולים בסדר גודל של מאות אלפי מסמכים, פי מאה מכל אוסף תוכן אמיתי:
service_metricsrequest_aggעםbucket_seconds: 60— דלי לדקה, פר endpointjob_runspredictive_sampler,sentry_poll,drive_reschedule—total_items: 0, ריצות סרק שנרשמותלשם השוואה:
code_snippets— 1,121 מסמכים. התוכן האמיתי זעיר מול הלוגים.הקצב מסביר את הגודל:
service_metricsנכתב כל דקה × כל endpoint;job_runsנכתב בכל טיק של כל job. אלה נתונים שנוצרים אוטומטית 24/7 בלי שאף אחד קורא אותם לאחור — הם לתצוגה חיה בדשבורד בלבד.מה שכבר קיים בקוד (ודאי, מהחיפוש)
TTL כן מיושם — על אוספים אחרים:
_create_profiler_indexesב-database/manager.py: TTL של 7 ימים עלslow_queries_log(expireAfterSeconds=604800,name: ttl_cleanup, על שדהtimestamp).attention_dismissals: TTL עלexpires_at(expireAfterSeconds=0+ שדה תאריך במסמך).ensure_lock_indexesב-main.py: TTL עלexpires_at/expiresAtשל ה-lock collection, עם fallback רך אם היצירה נכשלת.כלומר יש בפרויקט דפוס TTL מוכן, מוכח, ועם טיפול בכשל. הוא פשוט לא הוחל על
job_runsו-service_metrics.מה לבדוק לפני כל תיקון (חובה — לא להניח)
service_metricsאו מ-job_runsלאחור, מעבר לתצוגת הדשבורד. אם ה-observability מחשב מגמות על חלון של שבועות, TTL אגרסיבי ימחק נתונים שהוא צריך. לאתר את כל הקוראים לפני קביעת retention.slow_queries_logנקבע ל-7 ימים (604800ש'). ל-service_metrics(תצוגה חיה) אולי מספיק פחות; ל-job_runsאולי יותר, אם יש ערך היסטורי לאבחון. החלטה של אמיר, אחרי שסעיף 1 עונה מי קורא.הצעת התיקון (אחרי שהבדיקות עונות)
להרחיב את
_create_profiler_indexes(או המקום המקביל) ולהוסיף TTL לשני האוספים, באותו דפוס שכבר קיים — כולל ה-fallback הרך שלensure_lock_indexes(אם היצירה נכשלת, לוג ו-emit_event, בלי להפיל).שם שדה הזמן שונה בין אוספים — וזו מלכודת:
slow_queries_logמשתמש ב-timestamp(אומת בתיעוד),service_metricsנראה עםts, ו-job_runsעםstarted_at/ended_at. שלושה אוספים, שלושה שמות. לא לנחש — לפתוח מסמך מכל אוסף ולראות את שם השדה בפועל.ההשערה שצריך לבדוק בנפרד (לא מאומתת)
היום אירעה תקלת latency:
bookmarks.get_file_bookmarksלקח 152 שניות, ובאותו חלון גםcollections.get_tags_metadataו-api_ui_prefs. ה-JSON של ההתראה הראה שכל הבקשות האיטיות היו על אותו ObjectId (6a9054dd...), ו-db_pool_utilization: 13%— כלומר המסד לא היה רווי. זה מצביע על עיבוד נקודתי של פריט אחד, לא בהכרח על האוספים הגדולים.מה לבדוק: האם שאילתה כלשהי — של bookmarks, collections, או אחרת — סורקת את
service_metrics/job_runsבלי אינדקס מתאים. אם כן, ה-TTL גם ישפר latency (פחות מסמכים לסרוק). אם לא — ה-TTL עדיין נכון מטעמי אחסון, אבל לא יפתור את ה-latency, וזה באג נפרד.לא להניח שהשניים קשורים. לאמת עם
explain()על השאילתות האיטיות.בדיקות
getIndexes()מראהexpireAfterSeconds).emit_event, לא קורסת — כמוensure_lock_indexes.מה לא נסגר
explain().לא בסשן
מעדכן:
job_runs 318,797 מסמכים
service_metrics 470,040 מסמכים