Inode 사용법을 해제하는 방법?


275

inode 사용량이 100 % 인 df -i명령을 사용하는 디스크 드라이브가 있습니다. 그러나 파일을 실질적으로 삭제 한 후에도 사용량은 100 %로 유지됩니다.

그렇다면 올바른 방법은 무엇입니까?

디스크 공간 사용량이 적은 디스크 드라이브는 디스크 공간 사용량이 많은 디스크 드라이브보다 Inode 사용량이 더 높을 수 있습니까?

파일을 압축하여 사용 된 inode 수를 줄일 수 있습니까?


4
이 질문에 대해 50 점을 알려주세요. 어떻게해야합니까! :)
Sophy 2019

@Sophy 그렇게하지 마십시오. 자동 차단됩니다.
Steven Lu

1
@StevenLu 정보 주셔서 감사합니다! 내 문제를 해결하기 위해 며칠을 보냈기 때문에 그에게 신용을주고 싶습니다. 그러나이 문제는 나를 도울 수 있습니다. 다시 감사합니다
Sophy

1
@Sophy : 왜 SO에 대한 주제를 벗어난 것입니까? :) 그것은 얼마나 많은 공감대를 얻더라도 프로그래밍 문제가 아닙니다.
tink

빈 디렉토리는 또한 inode를 소비합니다. 삭제하면 일부 inode가 해제 될 수 있습니다. 일부 유스 케이스에서는 숫자가 중요 할 수 있습니다. find로 빈 디렉토리를 삭제할 수 있습니다. -타입 d-빈
삭제

답변:


170

디스크가 꽉 차지 않았더라도 디스크에 많은 수의 inode를 사용하는 것은 매우 쉽습니다.

inode는 파일에 할당되므로, 각각 1 바이트 씩 많은 파일이 있으면 디스크가 부족하기 오래 전에 inode가 부족하게됩니다.

파일에 여러 개의 하드 링크가있는 경우 파일을 삭제해도 inode 수가 줄어들지 않을 수도 있습니다. 내가 말했듯이, inode 는 디렉토리 항목이 아닌 파일에 속합니다 . 파일에 두 개의 디렉토리 항목이 연결되어 있으면 하나를 삭제해도 inode가 해제되지 않습니다.

또한 디렉토리 항목을 삭제할 수 있지만 실행중인 프로세스에 여전히 파일이 열려 있으면 inode가 해제되지 않습니다.

필자의 초기 조언은 가능한 모든 파일을 삭제 한 다음 파일을 열어 놓은 프로세스가 남아 있지 않도록 상자를 재부팅하는 것입니다.

그렇게해도 여전히 문제가 있으면 알려주십시오.

그런데 많은 파일이 포함 된 디렉토리를 찾는 경우이 스크립트가 도움이 될 수 있습니다.

#!/bin/bash
# count_em - count files in all subdirectories under current directory.
echo 'echo $(ls -a "$1" | wc -l) $1' >/tmp/count_em_$$
chmod 700 /tmp/count_em_$$
find . -mount -type d -print0 | xargs -0 -n1 /tmp/count_em_$$ | sort -n
rm -f /tmp/count_em_$$

12
물론, >/tmp/count_em_$$공간이있는 경우에만 작동합니다 ... 그렇다면 @simon의 답변을 참조하십시오.
alxndr

1
@alxndr, 파일 시스템을 별도로 유지하는 것이 좋은 생각 인 이유가 여기에 /tmp있습니다. 이렇게하면 다른 파일 시스템에 영향을 미치지 않습니다.
paxdiablo

귀하의 답변은 "시스템이 삭제 된 경우 재부팅 후 파일을 계속 사용하지 않습니다"에 완벽하게 적합합니다. 그러나 질문은 "아이 노드 포인터가 삭제 된 후 아이 노드를 재생하거나 재사용하는 방법"인가이다. 기본적으로 리눅스 커널은 생성 될 때마다 파일에 새로운 inode를 생성하고, 파일을 삭제할 때마다 자동으로 inode를 회수하지 않습니다.
Mohanraj

1
@AshishKarpe, OP가 프로덕션 서버에 대해 언급하지 않았기 때문에 자신의 상황 에 대해 이야기한다고 가정 합니다. 즉시 재부팅 할 수 없다면 두 가지 가능성이 있습니다. 먼저, 비행중인 프로세스가 결국 현재 파일을 닫아 디스크 리소스를 확보 할 수 있기를 바랍니다. 둘째, 프로덕션 서버도 일정 시점에 재부팅 할 수있는 범위가 있어야합니다. 계획된 다운 타임을 예약하거나 다음 다운 타임 창이 나타날 때까지 기다리십시오.
paxdiablo

2
나는 당신이 ls -A대신 원한다고 가정합니다 ls -a. 왜 세고 싶습니까? 그리고 ..?
jarno

205

운이 좋지 않으면 모든 아이 노드의 약 100 %를 사용했으며 스쿼트를 만들 수 없습니다. 로 확인할 수 있습니다 df -ih.

그런 다음이 bash 명령이 도움이 될 수 있습니다.

sudo find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n

그렇습니다. 시간이 오래 걸리지 만 파일이 가장 많은 디렉토리를 찾을 수 있습니다.


8
그 트릭을 수행합니다. 내 문제는 / lib / php / sessions 디렉토리에 엄청난 양의 세션이 있다는 것이었다. 누군가 같은 문제가있을 수도 있습니다
SteMa

2
누군가이 찾기, 잘라 내기, 유니크 정렬을 단일 awk 명령으로 다시 작성해야합니다!
mogsie

5
@alxndr awk은 gazillion 행을 정리하고 정렬하지 않고도 디렉토리의 해시와 파일 수를 유지할 수 있습니다. 즉, 아마도 여기에 개선 find . -maxdepth 1 -type d | grep -v '^\.$' | xargs -n 1 -i{} find {} -xdev -type f | cut -d "/" -f 2 | uniq -c | sort -n이있을 것입니다 . — 이것은 마지막 목록 만 정렬합니다.
mogsie

12
당신이 어떤 파일을 만들 수없는 경우, 심지어는 실패 할 수 있기 때문에 sort메모리에 모든 것을 유지하기 위해 실패 할 수 있으며 자동으로 임시 파일을 작성하는 후퇴하려고합니다. 분명히 실패 할 것입니다 ...
Mikko Rantalainen

10
sort나를 위해 실패했지만 --buffer-size=10G어느 것이 효과 가 있었 는지 줄 수있었습니다 .
Frederick Nord

69

내 상황은 내가 아이 노드가 없어서 내가 할 수있는 모든 것에 대해 이미 삭제 한 것이었다.

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361     11  100% /

나는 우분투 12.04LTS에 있고 패키지가 없어서 apt가 손상되어 약 40 만 개의 inode를 차지하는 오래된 Linux 커널을 제거 할 수 없었습니다. inode가 없어서 새 패키지를 설치할 수 없었습니다.

약 10,000 개의 inode를 확보하기 위해 몇 가지 오래된 Linux 커널을 수동으로 삭제했습니다.

$ sudo rm -rf /usr/src/linux-headers-3.2.0-2*

이것은 누락 된 패키지를 설치하고 apt를 수정하기에 충분했습니다.

$ sudo apt-get install linux-headers-3.2.0-76-generic-pae

그런 다음 이전 Linux 커널의 나머지를 apt로 제거하십시오.

$ sudo apt-get autoremove

상황이 훨씬 나아졌습니다

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361 434719   54% /

3
이것은 비슷한 상황에서 내 자신의 접근 방식에 가장 가깝습니다. help.ubuntu.com/community/Lubuntu/Documentation/에보다
beldaz

내 사건은 정확히! 그러나 진행하려면 "sudo apt-get autoremove -f"를 사용해야했습니다
Tony Sepia

sudo rm -rf /usr/src/linux-headers-3.2.0-2*커널을 사용하고 있지 않다고 확신한다면 이 작업을 수행하는 것이 안전 합니까?
Mars Lee

@MarsLee 현재 "uname -a"로 실행중인 커널을 확인할 수 있습니다
Dominique Eav

$ sudo apt-get autoremove혼자 부르는 것은 나를 위해 속임수를 썼다.
Morten Grum

49

내 해결책 :

이것이 다음과 같은 inodes 문제인지 확인하십시오.

df -ih

inode 수가 많은 루트 폴더를 찾으십시오.

for i in /*; do echo $i; find $i |wc -l; done

특정 폴더를 찾으십시오.

for i in /src/*; do echo $i; find $i |wc -l; done

이것이 리눅스 헤더 인 경우 다음을 사용하여 가장 오래된 것을 제거하십시오.

sudo apt-get autoremove linux-headers-3.13.0-24

개인적으로 나는 그것들을 마운트 된 폴더로 옮기고 (마지막 명령이 실패했기 때문에) 다음을 사용하여 최신을 설치했습니다.

sudo apt-get autoremove -f

이것은 내 문제를 해결했습니다.


1
제 경우에는 문제가있었습니다 SpamAssasin-Temp. find /var/spool/MailScanner/incoming/SpamAssassin-Temp -mtime +1 -print | xargs rm -f일을했다 :) 감사합니다!
조이스틱

4
나에게 이것은 시간이 걸렸다. 그러나 간단한 해결책이 있습니다. 두 번째 명령이 특정 디렉토리에서 정지하면 현재 명령을 종료하고 / *를 정지 한 디렉토리로 변경하여 다시 시작하십시오. <분>에 범인에게 드릴 다운 할 수있었습니다.
마이클 테리

같은 줄에 숫자를 인쇄하기 위해이 명령의 변형을 사용했습니다. for i in /usr/src/*; do echo -en "$i\t"; find $i 2>/dev/null |wc -l; done
cscracker

for i in /src/*; do echo "$i, `find $i |wc -l`"; done|sort -nrk 2|head -1010 가장 큰 디렉토리를 과시하십시오
Mark Simon

12

나는 같은 문제가 있었고 PHP의 디렉토리 세션을 제거하여 수정했다.

rm -rf /var/lib/php/sessions/

/var/lib/php5이전 PHP 버전을 사용 중인 경우 아래에 있을 수 있습니다 .

다음 권한으로 다시 작성하십시오.

mkdir /var/lib/php/sessions/ && chmod 1733 /var/lib/php/sessions/

데비안의 디렉토리에 대한 기본 권한이 drwx-wx-wt표시됨 (1733)


1
왜 이런 일이 일어나는지 아십니까?
Sibidharan

1
내 경우에는 @Sibidharan 이전 PHP 세션을 지우는 PHP cron 작업이 작동하지 않았기 때문입니다.
grim

3
rm -rf /var/lib/php/sessions/*아마도 더 나은 명령이 될 것입니다-세션 디렉토리를 제거하지 않고 그 내용 만 ... 그런 다음 다시 만들 걱정할 필요가 없습니다.
Shadow

나는 PHP 세션이 없었지만 이와 비슷한 magento 세션 문제가있었습니다. 방향 감사합니다.
Mohit

PHP 세션은 cron 작업, php.ini 파일에서 설정의 session.gc_maxlifetime을 통해 취소 안 php.net/manual/en/...

2

스팸 공격 후 HostGator 계정 (모든 호스팅에 inode 제한을 두는)에서이 문제가 발생했습니다. /root/.cpanel/comet에 수많은 큐 레코드가 남았습니다. 이러한 상황이 발생하고 빈 inode가없는 경우 쉘을 통해이 cpanel 유틸리티를 실행할 수 있습니다.

/usr/local/cpanel/bin/purge_dead_comet_files

2

RSYNC를 사용하여 많은 수의 파일을 삭제할 수 있습니다

rsync -a --delete blanktest/ test/

파일이 0 인 빈 테스트 폴더를 만들면 명령이 테스트 폴더를 많은 파일과 동기화합니다 (이 방법을 사용하여 거의 5M 파일을 삭제했습니다).

http://www.slashroot.in/which-is-the-fastest-method-to-delete-files-in-linux 덕분에


기사 / 주석에서 알 수 있듯이 rm *와일드 카드를 확장하고 각 인수를 전달 / 처리하기 때문에 많은 파일 보다 빠르지 만 많은 파일 rm test/test/포함 된 폴더 를 삭제하는 데 좋습니다.
mwfearnley

잘 작동하지만 빈 디렉토리에서 권한을 올바르게 설정했는지 확인하십시오! 나는 이것을하지 않았고 실수로 PHP 세션 디렉토리의 권한을 변경했습니다. 내가 망친 것을 알아 내기 위해 두 시간을 걸었다.
오름

1

eaccelerator는 PHP를 블록으로 컴파일하기 때문에 문제를 일으킬 수 있습니다 ...로드가 많은 사이트의 Amazon AWS 서버 에서이 문제가 발생했습니다. 계속 문제가 발생하면 / var / cache / eaccelerator에서 eaccelerator 캐시를 삭제하여 Inode를 비우십시오.

rm -rf /var/cache/eaccelerator/*

(또는 캐시 디렉토리에 관계없이)


1

우리는 최근 비슷한 문제에 직면했습니다. 프로세스가 삭제 된 파일을 참조하는 경우 Inode가 릴리스되지 않으므로 lsof /를 확인하고 프로세스를 종료 / 다시 시작하면 inode가 해제됩니다.

여기서 틀렸다면 바로 정정하십시오.


1

앞에서 언급했듯이 작은 파일이 많은 경우 파일 시스템에 inode가 부족할 수 있습니다. 여기에 대부분의 파일이 포함 된 디렉토리를 찾을 수있는 방법이 있습니다 .


0

늦은 답변 : 제 경우에는 세션 파일이었습니다.

/var/lib/php/sessions

Inode를 사용하고있었습니다.
심지어 crontab을 열거 나 삭제 작업을 트리거하는 것 외에도 새 디렉토리를 만들 수 없었습니다. PHP를 사용하기 때문에 예제 1의 코드를 복사하고 코드의 해당 부분을 실행하도록 cronjob을 설정하는 이 안내서 가 있습니다.

<?php
// Note: This script should be executed by the same user of web server 
process.

// Need active session to initialize session data storage access.
session_start();

// Executes GC immediately
session_gc();

// Clean up session ID created by session_gc()
session_destroy();
?>

crontab을 어떻게 열 었는지 궁금하다면 CLI를 통해 수동으로 일부 세션을 삭제했습니다.

도움이 되었기를 바랍니다!


0

이 정보를 볼 수 있습니다

for i in /var/run/*;do echo -n "$i "; find $i| wc -l;done | column -t

-2

지금 까지이 답변에 대한 많은 답변과 위의 모든 내용이 구체적으로 보입니다. 나는 당신이 갈 때 사용 stat하면 안전하다고 생각 하지만 OS에 따라 일부 inode 오류가 발생할 수 있습니다. 따라서 오버플로 문제를 피하기 위해 자신의 stat통화 기능을 구현 64bit하면 상당히 호환되는 것으로 보입니다.


우리는 여기서 예제를 좋아합니다;)
Bohne

-3

도커를 사용하는 경우 모든 이미지를 제거하십시오. 그들은 많은 공간을 사용했습니다 ....

모든 컨테이너를 중지

docker stop $(docker ps -a -q)

모든 컨테이너 삭제

docker rm $(docker ps -a -q)

모든 이미지 삭제

docker rmi $(docker images -q)

나에게 작동


"너무 많은 inode"가 문제인지 여부를 감지하는 데 도움이되지 않습니다.
Mark Stosberg 2018 년

이것은 Docker와 관련이 없습니다.
Urda
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.