← 홈Setup Tip

Setup Tip

Setup Tip — 폴더별 du를 더한 값은 확보한 공간이 아니다

디스크 경보가 울려 빌드 산출물 폴더 수십 개를 지우고, 지우기 전에 폴더마다 잰 du를 더해 "이만큼 비웠다"고 보고하기 쉽다. 하지만 하드링크로 내용을 공유하는 파일은 폴더마다 한 번씩 세어지고, 다른 링크가 남아 있으면 지워도 공간이 돌아오지 않는다. 확보량은 정리 전후의 파일 시스템 여유 공간 차이로만 말한다.

상황

작업 트리를 많이 만들어 쓰는 호스트에서는 디스크가 조용히 찬다. 트리마다 빌드 산출물 폴더가 수 기가바이트씩 붙기 때문이다. 경보가 울리면 한동안 아무도 쓰지 않은 트리의 산출물 폴더를 골라 지우는데, 이때 지우기 전에 폴더마다 du를 재서 합계를 내 두는 경우가 많다. 그 합계가 곧 "확보한 공간"으로 보고된다.

무엇이 어긋나는가

정리가 끝난 뒤 실제 여유 공간을 보면 합계보다 훨씬 적게 늘어나 있다. 계산이 틀린 게 아니라 질문이 틀렸다. du는 "이 경로 아래에 몇 바이트가 보이는가"를 답할 뿐, "이걸 지우면 몇 바이트가 돌아오는가"를 답하지 않는다. 두 질문의 답이 같은 건 모든 파일이 그 경로에만 존재할 때뿐이다.

왜 차이가 나는가

하드링크로 만든 트리나 캐시를 공유하는 빌드 도구는 같은 내용을 여러 경로에서 가리킨다. du를 폴더마다 따로 실행하면 같은 inode가 폴더 수만큼 세어진다. 한 번의 du 호출은 같은 inode를 한 번만 세지만, 사람이 결과를 모아 더하는 순간 그 보호가 사라진다. 게다가 지운 폴더 밖에 링크가 하나라도 남아 있으면 그 파일의 블록은 해제되지 않는다. 열린 채로 지워진 파일도 프로세스가 놓아줄 때까지 공간을 붙잡고 있다.

올바른 측정

정리 직전과 직후에 같은 마운트 지점의 df 여유 공간을 기록하고, 그 차이를 확보량으로 보고한다. 다른 작업이 동시에 디스크를 쓰고 있다면 그 사실도 함께 적는다. 폴더별 du는 무엇을 지울지 고르는 우선순위로만 쓰고, 결과 보고에는 쓰지 않는다. 합계가 필요하면 대상 폴더를 한 번의 du 호출에 모두 넘겨 중복 inode를 한 번만 세게 한다.

기대치 조정

하드링크를 많이 쓰는 환경일수록 정리의 효과는 원본이 함께 사라질 때 나타난다. 파생 트리의 산출물만 지우면 기대보다 적게 돌아오는 게 정상이다. 경보 기준선 아래로 확실히 내려가야 한다면, 무엇이 실제로 공간을 독점하고 있는지부터 링크 수 1인 파일을 기준으로 찾는다.

확인 방법

보고서에 적는 숫자는 df 전후 값 두 개와 그 차이 하나면 충분하다. 다음 경보에서 누군가 "지난번엔 80기가를 비웠다는데 왜 또 찼지"라고 물을 때, 처음부터 진짜 숫자가 적혀 있으면 헛된 추적을 하지 않아도 된다.