삭제된 로그가 점유한 공간을 회수해 음원 저장하기

LinuxBeginner
지금 연습하기

소개

Community Radio에는 저녁 프로그램용 클립이 있지만 작은 미디어 디스크가 가득 찼습니다. 관리자는 큰 접근 로그의 이름을 이미 삭제했습니다. 방송국은 기존 보관 음원을 제공하지만 공간은 돌아오지 않았습니다. 소중한 녹음을 삭제하면 실제 원인을 놓치게 됩니다.

Nginx가 여전히 잡고 있는 파일을 찾고, 문서에 명시된 로그 재열기 신호를 사용한 뒤 원래 서비스가 실행되는 동안 새 클립 전체를 저장하고 재생합니다. 기본 터미널 경험만 필요하며 C, 장치 포맷, 스토리지 설정은 필요하지 않습니다. 연습 음원은 영어 합성 음성입니다.

명령은 Workstation, 듣기는 Radio Player를 사용합니다. 각 실습에는 독립적으로 준비된 장애가 있습니다. /home/labex/project/radio 안에서만 작업하고 확인한 방송국 master에만 신호를 보내세요. 관련 없는 프로세스는 학습 플랫폼 소유입니다.

방송국을 중단하지 않고 공간 회수하기

이 단계에서는 가득 찬 파일 시스템을 특정 삭제 파일과 연결하고 방송국을 실행한 채 블록을 회수합니다.

보존할 음원을 먼저 듣기

Radio Player를 열어 Archive recording, 이어 Incoming clip을 재생합니다. 보관 음원은 이미 미디어 디스크에 있고 새 클립은 그 밖에서 기다립니다. 세 번째 플레이어에는 아직 완전한 저장 녹음이 없습니다. 이는 연습용 합성 음성이며 실시간 마이크나 실제 인터뷰가 아닙니다.

Workstation에서 pwd는 현재 위치, ls는 디렉터리 항목을 보여 줍니다. 준비된 방송국 디렉터리에서 시작하며 필요하면 cd로 돌아갑니다.

cd /home/labex/project/radio
pwd
/home/labex/project/radio
ls

media/는 독립 디스크입니다. incoming/은 인스턴스의 일반 파일 시스템에 있습니다. services/에는 코스 소유 두 Nginx 설정과 master PID 파일이 있습니다. media.ext4는 LabEx가 준비한 고정 크기 backing file이며 변경하지 마세요. 파일 시스템 생성이나 마운트 설정 편집은 하지 않습니다.

실패와 경계 확인하기

findmnt -T는 경로가 속한 파일 시스템을 표시합니다. 대상은 정확히 media 디렉터리, 원본은 /dev/loop... 장치, 형식은 ext4여야 합니다. 루트 파일 시스템의 원본은 다릅니다. loop 장치는 이 코스의 크기가 제한된 디스크 이미지를 블록 장치로 제공합니다.

findmnt -T media -o TARGET,SOURCE,FSTYPE
findmnt -T incoming -o TARGET,SOURCE,FSTYPE

cp는 파일을 복사합니다. 다음 복사는 의도적으로 No space left on device 오류가 예상되며 불완전한 대상 파일을 남길 수 있습니다. 이 파일에는 필요 없는 sudo를 사용하지 마세요.

cp incoming/evening-recording.wav media/recordings/evening-recording.wav

이는 작은 미디어 파일 시스템에서 실제로 발생한 용량 부족입니다. 기존 보관 음원은 온전합니다. df -h는 블록 용량을 읽기 쉬운 단위로 표시합니다. du -xsh는 디렉터리 아래에서 이름으로 접근 가능한 할당 블록을 합합니다. -x는 같은 파일 시스템, -s는 요약, -h는 읽기 쉬운 단위입니다.

df -h media
du -xsh media

df는 거의 모든 용량이 사용 중이라고 하지만 du는 적은 양만 봅니다. 두 명령은 다른 것을 측정합니다. 차이만으로 원인을 정할 수는 없습니다. 메타데이터, 예약 블록, 권한, 다른 마운트 뷰 등도 영향을 줍니다.

실제로 파일을 잡고 있는 프로세스 찾기

디렉터리 항목은 이름을 파일 시스템의 파일 기록인 inode에 연결합니다. 하드 링크 수는 이 inode를 가리키는 이름 개수입니다. 프로세스는 열린 파일을 참조하는 번호인 열린 파일 디스크립터도 보유할 수 있습니다. 마지막 이름을 지우면 링크 수는 0이 되지만 마지막 열린 참조가 닫힐 때까지 블록은 남습니다.

lsof는 열린 파일을 나열합니다. Nginx에는 root master가 있으므로 이 읽기 전용 조사에 sudo를 사용합니다. -nP는 호스트·포트 이름 조회를 피하고, +L1은 링크 수 1 미만, +f -- media는 media가 속한 파일 시스템을 선택하며 -a는 조건의 교집합입니다. 전역 목록에는 관계없는 삭제 메모리 파일과 플랫폼 프로세스도 있으므로 이 필터를 유지하세요.

sudo lsof -nP -a +L1 +f -- /home/labex/project/radio/media

media/logs/access.log (deleted)에 대해 master와 worker인 두 Nginx 행이 보여야 합니다. PID, FD, DEVICE, SIZE/OFF, NLINK, NODE를 읽으세요. 장치와 inode가 같고 NLINK는 0입니다. 같은 파일 크기이므로 합하지 않습니다. 4w는 4번 디스크립터가 쓰기용으로 열렸다는 뜻입니다. 이름이 없어도 장치/inode는 이 파일 시스템의 파일을 식별합니다.

cat은 텍스트를 표시합니다. 실제 설정과 master PID 파일을 읽습니다. pid, access_log 경로가 이 방송국과 삭제된 미디어 로그에 일치해야 합니다.

cat services/studio/nginx.conf
cat services/studio/nginx.pid

아래 MASTER는 셸 변수입니다. $(...)는 명령 출력을 가져오고 큰따옴표는 값을 단일 인수로 유지합니다. ps는 선택 프로세스를 보여 주며 -o는 열, -p는 해당 PID, --ppid는 그 자식들도 선택합니다. 필터링한 lsof의 master이고 설정 경로가 이 코스 것인지 확인하세요. 다른 행은 worker이며 부모 PID가 이 master입니다.

MASTER=$(cat services/studio/nginx.pid)
ps -ww -o pid,ppid,user,args -p "$MASTER" --ppid "$MASTER"

마운트, 경로, master 신원이 다르면 실행하지 마세요. PID를 추측하거나 모든 Nginx에 신호를 보내지 말고 디렉터리와 설정을 다시 확인합니다.

이 프로그램에 재열기 요청하기

신호의 의미는 프로그램에 달려 있습니다. Nginx는 USR1을 로그 파일 다시 열기로 문서화합니다. 옛 로그 참조를 닫고 설정된 이름을 다시 엽니다. TERM은 중단하고 HUP는 다른 재로드 동작입니다. man nginx로 설치된 설명서를 열고 SIGNALS를 찾은 다음 q로 돌아갑니다. Nginx 제어 문서에도 같은 계약이 있습니다.

man nginx

kill은 이름 있는 신호를 보낼 수 있으며 항상 종료를 뜻하지 않습니다. 이 root master에 신호를 보내려면 sudo가 필요합니다. 방금 확인한 master에만 문서화된 신호를 보냅니다.

sudo kill -USR1 "$MASTER"

이제 공간, 파일 보유자, master를 다시 관찰합니다. 재열기는 비동기이므로 보유자가 잠시 보이면 조금 기다린 뒤 읽기 전용 관찰을 반복하세요.

df -h media
sudo lsof -nP -a +L1 +f -- /home/labex/project/radio/media
ps -ww -o pid,ppid,user,args -p "$MASTER" --ppid "$MASTER"

공간이 돌아오고 삭제 미디어 로그 행이 사라지며 같은 master PID가 남아야 합니다. 필터링된 lsof 결과가 비어 있는 것이 정상입니다. 방송국을 멈추거나 다른 파일 시스템의 파일을 해제하지 않았습니다.

curl -fsS는 URL을 읽고 HTTP 오류에서는 실패하며 필요하면 간단한 오류를 표시합니다. 이 정상 방송국 요청은 계속 작동해야 합니다. 이어서 tail -n 2로 새 이름의 접근 로그 마지막 두 줄을 봅니다.

curl -fsS http://127.0.0.1:8080/on-air.txt
tail -n 2 media/logs/access.log

Community Radio: archive and live programme remain available.와 새 GET /on-air.txt 로그 항목이 예상됩니다. 원래 프로세스가 이제 새 이름의 로그에 씁니다. 공간이 안 돌아오면 필터링한 보유자를 다시 조사하세요. 보관 음원 삭제, 디스크립터 잘라내기, 서비스 중단, 마운트 재생성은 하지 않습니다. 새 로그가 없으면 그대로인 설정을 확인하고 올바른 master에 문서화된 재열기를 반복합니다.

전체 녹음 저장하고 사용하기

이 단계에서는 실패한 부분 복사를 전체 새 클립으로 교체하고 바이트를 확인하며 실행 중인 방송국에서 사용합니다.

새 소스와 보관 음원은 역할이 다릅니다. 둘 다 보존하세요. 같은 대상으로 cp를 다시 실행하면 실패한 부분 파일을 교체하며 소스는 바뀌지 않습니다.

cp incoming/evening-recording.wav media/recordings/evening-recording.wav

cmp는 모든 바이트를 비교하고 같으면 출력하지 않습니다. 복사 직후 확인합니다.

cmp incoming/evening-recording.wav media/recordings/evening-recording.wav

sha256sum은 내용 지문을 출력합니다. 같은 해시는 눈으로 확인할 또 다른 비교이며 평가기도 기존 보관 음원과 소스를 준비 당시 바이트와 대조합니다.

sha256sum incoming/evening-recording.wav media/recordings/evening-recording.wav

두 줄의 해시가 같아야 합니다. 이름이나 크기가 그럴듯해도 0으로 채운 파일이나 희소 파일은 녹음이 아닙니다. 다른 파일 시스템에 복사해도 방송국 미디어 전달은 완료되지 않습니다.

findmnt -T media/recordings/evening-recording.wav -o TARGET,SOURCE,FSTYPE

여전히 같은 독립 ext4 미디어 마운트여야 합니다. 방송국이 실제 저장 파일을 제공하는지 확인합니다. -o는 curl이 다운로드 응답을 미디어 디스크 밖에 저장하도록 하며 그 응답을 새 클립과 비교합니다.

curl -fsS http://127.0.0.1:8080/recordings/evening-recording.wav -o /tmp/radio-delivered.wav
cmp incoming/evening-recording.wav /tmp/radio-delivered.wav

Radio Player로 돌아와 새로 고칩니다. Your saved recording을 재생하고 끝부분으로 이동해 마무리 문장을 듣습니다. Archive recording도 다시 재생하고 Download saved recording으로 저장 녹음을 다운로드합니다. Read the on-air message를 누르면 방송국 메시지가 여전히 보여야 합니다. 브라우저 오디오는 사용자의 재생 동작이 필요하며 바이트 저장만으로 시작되지 않습니다.

플레이어가 형식이나 네트워크 오류를 보고하면 소스와 대상을 다시 비교하고 URL을 확인하세요. 디스크가 찬 상태에서 WAV 헤더나 데이터가 잘릴 수 있으므로 공간 회수 후 변경하지 않은 소스를 다시 복사합니다. 비교가 실패해도 헤더를 수리하거나 손상 대상에 맞춰 소스를 바꾸지 마세요.

df -h media

파일 시스템에는 충분한 여유 공간과 완전한 저장 클립이 있어야 합니다. 코스 검사는 최종 파일, 마운트 신원, 열린 디스크립터, 실제 서비스 상태만 읽습니다. 신호 보내기, 오디오 복사, 파일 복구, 대신 녹음 생성은 하지 않습니다.

요약

이름, inode, 열린 디스크립터를 구분해 실제 디스크 용량을 회수했습니다. 파일 시스템으로 필터링한 조사로 삭제된 로그를 올바른 Nginx master에 연결했고, 문서화된 USR1 신호로 프로세스를 교체하지 않고 옛 참조를 해제했습니다. 이후 기존 보관 음원과 서비스를 유지하며 전체 클립을 저장, 비교, 다운로드하고 재생했습니다.

df/du 차이는 단서이며 진단 자체는 아닙니다. 재열기 동작은 프로그램별로 다르므로 신호 전에 문서를 확인하세요. 이 연습은 독립 ext4 디스크와 합성 음성을 사용하며 장치 포맷, 임의 프로세스 종료, 전체 로그 순환 정책은 다루지 않습니다.