Linux

שאלת ראיון למומחה שרתי Linux: הדיסק מלא לפי df ו־du מוצא רק חצי. איפה המקום?

10 דק׳ קריאה•מכללת נטמי
שווה להעביר הלאה
שאלת ראיון למומחה שרתי Linux: הדיסק מלא לפי df ו־du מוצא רק חצי. איפה המקום?

אתם בראיון לתפקיד מומחה שרתי Linux. עברתם את השאלות על הרשאות, על systemd ועל SSH, ואז מגיע תרחיש: ״קיבלת התראה בשלוש בלילה. המחיצה של ‎/var בשרת Production מלאה ב־100%. הרצת df והוא מראה שהדיסק מלא, אבל du על כל התיקיות מסתכם בפחות מחצי. איפה המקום, ואיך אתה משחרר אותו בלי להפיל את השרת?״

מראיינים בתפקידי Linux ו־DevOps אוהבים את השאלה הזו, כי אי אפשר לענות עליה מרשימת פקודות שזוכרים בעל פה. היא בודקת אם אתם מבינים מה קורה במערכת הקבצים מתחת לפקודות, ואם אתם יודעים לעבוד על שרת חי בלי לגרום נזק.

למה df ו־du לא מסכימים?

בלינוקס, השם של קובץ בתיקייה הוא רק קישור ל־inode. הנתונים עצמם שייכים ל־inode. כשמריצים rm, מוחקים את הקישור ומורידים את ה־link count. מערכת הקבצים משחררת את הבלוקים רק כששני תנאים מתקיימים: אף שם כבר לא מצביע על ה־inode, ואף תהליך לא מחזיק אותו פתוח.

  • ▸df שואל את מערכת הקבצים ישירות כמה בלוקים תפוסים וכמה פנויים. הוא רואה הכול, כולל נתונים של קבצים שכבר אין להם שם.
  • ▸du עובר על עץ התיקיות קובץ אחרי קובץ וסוכם את הבלוקים. מה שאין לו נתיב בתיקייה, du פשוט לא יכול לספור.
  • ▸לכן פער גדול בין השניים אומר כמעט תמיד שיש על הדיסק נתונים שאין דרך להגיע אליהם דרך נתיב רגיל.

החשוד המרכזי: לוג שנמחק אבל עדיין פתוח

התרחיש הקלאסי: אפליקציה כותבת ל־‎/var/log/app/app.log, הקובץ מגיע ל־40GB, ומישהו בצוות ״פותר״ את הבעיה עם rm. הקובץ נעלם מ־ls, אבל תהליך ה־Java או ה־nginx עדיין מחזיק אליו File Descriptor פתוח וממשיך לכתוב. המקום לא חוזר, ו־df ממשיך להראות 100%. מי שמחק בטוח שפינה 40GB, ובפועל לא שוחרר אפילו בייט אחד.

איתור: מה תפוס, מה גלוי, ומי מחזיק קבצים מחוקים
# כמה תפוס לפי מערכת הקבצים
df -hT /var

# כמה תפוס לפי הקבצים הגלויים, בלי לחצות למחיצות אחרות
du -xh --max-depth=1 /var | sort -h

# קבצים פתוחים שה־link count שלהם 0, כלומר נמחקו
lsof -nP +L1

# בלי lsof: חיפוש ישיר ב־/proc
find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null
הדגל ‎-x ב־du חשוב: בלעדיו du ייכנס גם למחיצות אחרות שמחוברות מתחת ל־‎/var, והמספרים לא יהיו ברי השוואה ל־df.
פלט לדוגמה של lsof +L1
COMMAND  PID USER FD   TYPE DEVICE    SIZE/OFF NLINK NODE NAME
java    2481 app   7w  REG  253,2 42949672960     0 1311 /var/log/app/app.log (deleted)
NLINK 0 ו־(deleted) בסוף השורה: הקובץ נמחק, אבל PID 2481 מחזיק אותו פתוח בכתיבה דרך File Descriptor מספר 7, ו־40GB עדיין תפוסים.

איך משחררים את המקום בלי להפיל את השרת

  • ▸הדרך הנקייה: לגרום לתהליך לסגור את הקובץ. בהרבה שירותים reload מספיק כדי שיפתחו מחדש את קבצי הלוג, למשל systemctl reload nginx. אם השירות לא תומך בזה, restart בחלון זמן מתוכנן.
  • ▸כשאי אפשר לאתחל עכשיו: לקצץ את הקובץ דרך ה־File Descriptor של התהליך. המקום משתחרר מיד, והתהליך ממשיך לכתוב כרגיל.
  • ▸מה לא לעשות: לא להרוג תהליכים באקראי עם kill -9, ולא להמשיך למחוק קבצים אחרים ״כדי לפנות מקום״. זה לא יעזור, כי המקום תפוס על ידי הקובץ שכבר נמחק.
קיצוץ קובץ מחוק דרך ‎/proc
# לפי ה־PID וה־FD מהפלט של lsof
: > /proc/2481/fd/7

# בדיקה שהמקום חזר
df -h /var
הקיצוץ מוחק את תוכן הלוג. אם צריך אותו לחקירה, מעתיקים אותו קודם ליעד במחיצה אחרת שיש בה מקום: cp /proc/2481/fd/7 /backup/app.log

lsof לא מצא כלום? עוד שתי סיבות

מראיין טוב לא יעצור בתשובה הראשונה: ״בדקת, ואין קבצים מחוקים פתוחים. מה עכשיו?״ כאן מגיעות שתי סיבות שפחות אנשים מכירים.

  • ▸קבצים מוסתרים מתחת ל־mount point: נניח ש־‎/var/log היא מחיצה נפרדת. אם בזמן שהיא לא הייתה מחוברת, למשל אחרי Boot שבו ה־mount נכשל, שירות כתב לוגים לתיקייה, הקבצים נכתבו בפועל למחיצה של ‎/var. אחרי שהמחיצה חוברה היא מסתירה אותם, ו־du לא רואה אותם. bind mount של ‎/var למקום אחר מראה את התיקייה בלי מה שמחובר מעליה.
  • ▸בלוקים שמורים ב־ext4: כברירת מחדל ext4 שומר כ־5% מהבלוקים ל־root, כדי שהמערכת תמשיך לתפקד גם כשמשתמשים רגילים מילאו את הדיסק. זו הסיבה ש־Used ועוד Avail ב־df לא מסתכמים ל־Size. בדיסק של 2TB מדובר בכ־100GB. במחיצות נתונים אפשר להקטין את האחוז עם tune2fs -m, במחיצת השורש עדיף להשאיר אותו.
בדיקת קבצים מוסתרים ובלוקים שמורים
# מה מסתתר בתיקייה מתחת למחיצה שמחוברת עליה
mkdir -p /mnt/var-under
mount --bind /var /mnt/var-under
du -sh /mnt/var-under/log
umount /mnt/var-under

# כמה בלוקים שמורים ל־root במחיצת ext4
tune2fs -l "$(findmnt -no SOURCE /var)" | grep -i 'reserved block count'
bind mount רגיל לא מעביר את המחיצות שמחוברות מתחת, ולכן ב־‎/mnt/var-under/log רואים את מה שנכתב לתיקייה עצמה, לא את המחיצה של ‎/var/log.

השאלה שכמעט תמיד מגיעה אחרי: אין מקום, אבל יש מקום

התרחיש ההפוך: df -h מראה 60% פנוי, אבל האפליקציה נופלת עם No space left on device. הפעם הבעיה היא לא בלוקים אלא inodes. לכל קובץ יש inode אחד, ובמערכות כמו ext4 מספר ה־inodes נקבע כשיוצרים את מערכת הקבצים. מיליוני קבצים קטנים, כמו קבצי session של PHP או תור מיילים שנתקע, יכולים לגמור את ה־inodes הרבה לפני שנגמר המקום.

בדיקת inodes
df -i /var

# איפה יש הכי הרבה קבצים (GNU du)
du -x --inodes --max-depth=2 /var | sort -n | tail
IUse% של 100% עם הרבה מקום פנוי הוא סימן מובהק למיליוני קבצים קטנים.

איך מונעים את זה מראש

  • ▸logrotate מוגדר נכון: אחרי סיבוב הלוג שולחים לשירות reload בבלוק postrotate, או משתמשים ב־copytruncate לאפליקציות שלא יודעות לפתוח מחדש את הלוג. ל־copytruncate יש מחיר: שורות שנכתבות בין ההעתקה לקיצוץ עלולות ללכת לאיבוד.
  • ▸הגבלת נפח ל־journald: הגדרת SystemMaxUse בקובץ ‎/etc/systemd/journald.conf, או ניקוי חד פעמי עם journalctl --vacuum-size=500M.
  • ▸ניטור והתראה גם על אחוז דיסק, גם על אחוז inodes וגם על קצב הגדילה. 85% שהצטברו במשך חודש הם לא אותו סיפור כמו 85% שהגיעו בשעה.
  • ▸מחיצות נפרדות ל־‎/var/log ולתיקיות של מסדי נתונים, כדי שלוג שיצא משליטה לא ימלא את מחיצת השורש ויפיל את כל השרת.

שאלות המשך שכדאי להיות מוכנים אליהן

  • ▸מה ההבדל בין hard link ל־soft link? hard link הוא עוד שם לאותו inode, ולכן הנתונים נמחקים רק כשכל השמות נמחקו. soft link הוא קובץ נפרד שמכיל נתיב, והוא נשבר אם המקור נמחק.
  • ▸מה ההבדל בין truncate -s 0 ל־rm? truncate מאפס את התוכן ומשאיר את הקובץ ואת ה־inode, ולכן תהליך שכותב אליו ממשיך כרגיל והמקום חוזר. rm מוחק רק את השם.
  • ▸למה ls -l ו־du מראים גדלים שונים לאותו קובץ? ls מציג את הגודל הלוגי, ו־du את הבלוקים שהוקצו בפועל. בקובץ Sparse, כמו דיסק של מכונה וירטואלית, ls יכול להראות 100GB ו־du רק 3GB.
  • ▸איך מגדילים מחיצת LVM בלי השבתה? lvextend עם הדגל ‎-r מגדיל את ה־Logical Volume ואת מערכת הקבצים יחד. ext4 ו־XFS תומכים בהגדלה בזמן שהמחיצה מחוברת. הקטנה היא כבר סיפור אחר, ו־XFS לא תומכת בה בכלל.
  • ▸מה ההבדל בין reload ל־restart ב־systemd? reload מבקש מהשירות לטעון מחדש את ההגדרות בלי לעצור, אם השירות תומך בזה. restart עוצר ומפעיל מחדש, כולל ניתוק החיבורים הפעילים.

שאלות כאלה לא בודקות זיכרון של פקודות, הן בודקות אם אתם מרגישים בבית בטרמינל: קוראים פלט, מבינים הרשאות, יודעים מתי צריך root ולא מתבלבלים כשמשהו לא מסתדר. את הבסיס הזה בונים בקורס ניהול שרתי לינוקס של נטמי, ומי שמכוון לתפקיד תשתיות מלא מקבל את התמונה הרחבה בחבילת Sys Admin המלא.

רוצים להגיע לראיון Linux עם ביטחון בטרמינל?

קורס ניהול שרתי לינוקס של נטמי כולל 28 שיעורים מוקלטים בעברית: עבודה ב־Shell, ניהול קבצים ותיקיות, שרשור פקודות והפניית פלט, חיפוש עם grep, משתמשים, קבוצות והרשאות, sudo ו־ACL, ומעבדה על מכונת Ubuntu שאתם מקימים בעצמכם ב־VirtualBox ומתחברים אליה ב־SSH. ומי שמכוון לתפקיד System Administrator, חבילת Sys Admin המלא משלבת ארבעה קורסים: Windows Server ו־Active Directory, Linux, VMware ו־CCNA, כדי שתבינו גם את השרת, גם את הווירטואליזציה שהוא רץ עליה וגם את הרשת שמחברת הכול.

מקורות מקצועיים להעמקה

ההסבר מבוסס על דפי ה־man הרשמיים של Linux. התנהגות של פקודות כמו du ו־lsof עשויה להשתנות מעט בין הפצות וגרסאות, ולכן כדאי לבדוק את דף ה־man בשרת שלכם.

תגיות ומילות מפתח
  • #ראיונות_עבודה
  • #שאלת_ראיון
  • #Linux
  • #לינוקס
  • #מומחה_שרתי_לינוקס
  • #Linux_Administrator
  • #System_Administrator
  • #DevOps
  • #SRE
  • #df
  • #du
  • #lsof
  • #inode
  • #No_space_left_on_device
  • #logrotate
  • #journald
  • #systemd
  • #ext4
  • #XFS
  • #LVM
  • #Troubleshooting
  • #פתרון_תקלות
  • #ניהול_שרתים
  • #קורס_לינוקס
  • #קורס_לינוקס_בעברית
  • #קורס_ניהול_שרתי_לינוקס
  • #חבילת_סיסטם
  • #SysAdmin
  • #מכללת_נטמי
  • #NetMe_College

רוצים להתמקצע?

הפוסט הזה הוא רק טעימה. הקורס המלא של קורס ניהול שרתי לינוקס ילמד אתכם הכל מא׳ עד ת׳.