ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

Home ดิสก์เต็ม: ตรวจสอบพื้นที่และหาไฟล์ขนาดใหญ่บน Linux

ดิสก์เต็ม: ตรวจสอบพื้นที่และหาไฟล์ขนาดใหญ่บน Linux

เมื่อดิสก์เต็ม อาการที่เห็นมักไม่ได้บอกตรง ๆ ว่าดิสก์เต็ม เช่น เว็บไซต์ขึ้น Error 500, MySQL/MariaDB หยุดทำงาน, อัปโหลดไฟล์ไม่ได้, ส่งอีเมลไม่ออก หรือพิมพ์คำสั่งแล้วขึ้น No space left on device คู่มือนี้พาไล่ตรวจจากภาพรวมลงไปถึงไฟล์ที่กินพื้นที่ และวิธีคืนพื้นที่อย่างปลอดภัยโดยไม่ลบไฟล์ที่ระบบยังต้องใช้

คำสั่งทั้งหมดใช้ได้บน Ubuntu 22.04/24.04 และ AlmaLinux/Rocky Linux 8-9 ถ้าตรวจแล้วพบว่าข้อมูลจำเป็นทั้งหมด ทางออกคือเพิ่มพื้นที่ดิสก์ ดู การขยายพื้นที่ Partition หลังเพิ่มพื้นที่ Disk Space (Linux) หรือ เพิ่ม Data Disk บน Linux

สิ่งที่ต้องเตรียม

  • สิทธิ์ root หรือผู้ใช้ที่ใช้ sudo ได้
  • ถ้าดิสก์เต็ม 100% จน SSH เข้าไม่ได้ ให้ใช้ Console Server ผ่าน Web UI
  • ก่อนลบไฟล์ใดที่ไม่แน่ใจ ให้สำรองไปไว้ที่อื่นก่อน หรือย้ายไปดิสก์อื่นแทนการลบ

ขั้นตอนที่ 1: ดูว่าพาร์ติชันไหนเต็ม

df -hT

ดูคอลัมน์ Use% และ Mounted on ตัวอย่าง

Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/vda1      ext4   40G   39G  0.9G  98% /
tmpfs          tmpfs 2.0G     0  2.0G   0% /dev/shm

บรรทัดที่ Use% ใกล้ 100% คือพาร์ติชันที่ต้องจัดการ ส่วน tmpfs และ devtmpfs อยู่ในหน่วยความจำ ไม่เกี่ยวกับดิสก์

ตรวจ Inode ด้วย

df -i

ถ้า df -h ยังเหลือพื้นที่แต่ระบบแจ้งว่าดิสก์เต็ม ให้ดูคอลัมน์ IUse% ถ้าใกล้ 100% แปลว่ามีไฟล์เล็ก ๆ จำนวนมหาศาล (เช่น Session ของ PHP หรือไฟล์ Cache) จนหมดจำนวนไฟล์ที่ระบบไฟล์รองรับ แม้พื้นที่ยังเหลือก็ตาม ดูวิธีหาในหัวข้อปัญหาที่พบบ่อย

ขั้นตอนที่ 2: ไล่หาโฟลเดอร์ที่ใหญ่ที่สุด

เริ่มจาก / แล้วไล่ลงไปทีละชั้น ตัวเลือก -x ทำให้ไม่ข้ามไปนับดิสก์อื่นที่ Mount อยู่

sudo du -xh --max-depth=1 / 2>/dev/null | sort -h | tail -n 15

ผลลัพธ์เรียงจากเล็กไปใหญ่ บรรทัดล่างสุดคือผลรวมของ / บรรทัดเหนือขึ้นไปคือโฟลเดอร์ที่ใหญ่ที่สุด ตัวอย่าง

1.2G    /usr
3.5G    /home
28G     /var
34G     /

จากนั้นไล่ลงไปในโฟลเดอร์ที่ใหญ่ที่สุด เช่น

sudo du -xh --max-depth=1 /var 2>/dev/null | sort -h | tail -n 15
sudo du -xh --max-depth=1 /var/log 2>/dev/null | sort -h | tail -n 15

ทำซ้ำจนพบต้นเหตุ ตำแหน่งที่มักกินพื้นที่คือ /var/log (Log), /var/lib/mysql (ฐานข้อมูลและ Binary Log), /var/lib/docker (Image และ Container), /var/www หรือ /home (ไฟล์เว็บและไฟล์ Backup ที่ลืมลบ)

ถ้าต้องการเครื่องมือแบบเลือกดูได้ ติดตั้ง ncdu (sudo apt install ncdu บน Ubuntu หรือ sudo dnf install ncdu บน AlmaLinux/Rocky ซึ่งต้องเปิด EPEL ก่อน) แล้วรัน sudo ncdu -x /

ขั้นตอนที่ 3: หาไฟล์ขนาดใหญ่โดยตรง

ค้นหาไฟล์ที่ใหญ่กว่า 500 MB บนพาร์ติชัน /

sudo find / -xdev -type f -size +500M -exec ls -lh {} + 2>/dev/null | sort -k5 -h

ไฟล์ที่พบบ่อย ได้แก่ ไฟล์ Backup ขนาดใหญ่ (.tar.gz, .sql, .zip), Log ที่ไม่เคยถูก Rotate และไฟล์ Dump ที่ทำไว้ชั่วคราว

ขั้นตอนที่ 4: คืนพื้นที่อย่างปลอดภัย

ลดขนาด systemd journal

sudo journalctl --disk-usage
sudo journalctl --vacuum-size=200M

คำสั่งแรกบอกว่า Journal ใช้พื้นที่เท่าไร คำสั่งที่สองลบ Journal เก่าจนเหลือไม่เกิน 200 MB ถ้าต้องการจำกัดถาวร ให้ตั้ง SystemMaxUse=200M ในไฟล์ /etc/systemd/journald.conf แล้วรัน sudo systemctl restart systemd-journald

ล้าง Cache ของตัวจัดการแพ็กเกจ

# Ubuntu
sudo apt clean
sudo apt autoremove --purge

# AlmaLinux / Rocky Linux
sudo dnf clean all
sudo dnf autoremove

autoremove จะแสดงรายการแพ็กเกจที่จะลบ (รวมถึง Kernel รุ่นเก่า) และถามยืนยันก่อน อ่านรายการให้แน่ใจก่อนตอบ Y

ล้างไฟล์ Log ขนาดใหญ่ที่กำลังถูกเขียน

อย่าใช้ rm กับไฟล์ Log ที่โปรแกรมกำลังเปิดอยู่ เพราะพื้นที่จะไม่ถูกคืนจนกว่าโปรแกรมนั้นจะรีสตาร์ต ให้ล้างเนื้อหาในไฟล์แทน (สำรองไว้ก่อนถ้ายังต้องใช้ข้อมูลใน Log)

sudo truncate -s 0 /var/log/nginx/access.log

ไฟล์ Log เก่าที่ถูก Rotate แล้ว เช่น *.log.1 หรือ *.gz ลบได้ตามปกติ และควรตรวจการตั้งค่า logrotate ใน /etc/logrotate.d/ เพื่อไม่ให้เกิดซ้ำ

Docker

sudo docker system df
sudo docker system prune

docker system prune ลบ Container ที่หยุดแล้ว Network ที่ไม่ได้ใช้ และ Image ที่ไม่มี Tag ถ้าเพิ่ม -a จะลบ Image ที่ไม่มี Container ใช้งานทั้งหมด และถ้าเพิ่ม --volumes จะลบ Volume ที่ไม่ได้ใช้ ซึ่งอาจมีข้อมูลฐานข้อมูลอยู่ ใช้เฉพาะเมื่อแน่ใจแล้ว

MySQL/MariaDB Binary Log

ถ้า /var/lib/mysql มีไฟล์ binlog.* หรือ mysql-bin.* จำนวนมาก อย่าลบไฟล์ด้วย rm ให้สั่งผ่านฐานข้อมูล และถ้าใช้ Replication ต้องตรวจก่อนว่า Replica อ่านไปถึงไฟล์ใดแล้ว

sudo mysql -e "PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;"

ตรวจสอบผลลัพธ์

df -h /

ค่า Use% ควรลดลง ควรเหลือพื้นที่ว่างอย่างน้อย 15-20% เพื่อให้ฐานข้อมูลและการอัปเดตระบบทำงานได้ปกติ จากนั้นรีสตาร์ตบริการที่หยุดไประหว่างดิสก์เต็ม เช่น sudo systemctl restart mysql (Ubuntu) หรือ sudo systemctl restart mariadb แล้วตรวจสถานะด้วย systemctl status ตามชื่อบริการ

ปัญหาที่พบบ่อย

ลบไฟล์แล้วแต่ df ยังแสดงว่าเต็ม

ไฟล์ถูกลบไปแล้วแต่ยังมีโปรแกรมเปิดค้างไว้ พื้นที่จึงยังไม่ถูกคืน หาได้ด้วย

sudo lsof -nP +L1

รายการที่ขึ้นว่า (deleted) พร้อมชื่อโปรแกรมในคอลัมน์ COMMAND ให้รีสตาร์ตบริการนั้น พื้นที่จะถูกคืนทันที ถ้าไม่มีคำสั่ง lsof ให้ติดตั้งด้วย sudo apt install lsof หรือ sudo dnf install lsof

Inode เต็ม

หาโฟลเดอร์ที่มีจำนวนไฟล์มากที่สุด

sudo du -x --inodes --max-depth=2 / 2>/dev/null | sort -n | tail -n 15

มักพบในโฟลเดอร์ Session ของ PHP, Cache ของเว็บ หรือคิวอีเมลที่ค้าง ลบไฟล์เก่าในโฟลเดอร์นั้น เช่น Session ที่เก่ากว่า 7 วัน (ตรวจ Path ให้ถูกก่อนรัน: Ubuntu ใช้ /var/lib/php/sessions ส่วน AlmaLinux/Rocky ใช้ /var/lib/php/session และ Control Panel บางตัวเก็บไว้ที่อื่น)

sudo find /var/lib/php/sessions -type f -mtime +7 -delete

du กับ df แสดงตัวเลขไม่ตรงกัน

นอกจากไฟล์ที่ถูกลบแต่ยังเปิดอยู่แล้ว อาจมีไฟล์ซ่อนอยู่ใต้จุด Mount (เขียนไฟล์ลงโฟลเดอร์ก่อนที่ดิสก์อื่นจะถูก Mount ทับ) และระบบไฟล์ ext4 จองพื้นที่ประมาณ 5% ไว้สำหรับ root ซึ่งทำให้ Avail น้อยกว่า Size ลบ Used

หากไม่แน่ใจว่าไฟล์ใดลบได้ หรือต้องการเพิ่มพื้นที่ดิสก์ ติดต่อทีมซัพพอร์ต THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security