스토리지 장애대응 보고
연휴 동안 퍼포스 서버 스토리지가 터져 복원해야 했습니다. 백업이 있었지만 복원 과정에서 바보같은 실수를 여러 번 했습니다. 백업이 있다면 종종 전체 복원 연습이 필요하다는 교훈을 얻었습니다.

얼마 전 왜 셀프 호스팅을 해야 하는가?라는 글을 읽었습니다. 여러 가지 이유로 가능하다면 사용하는 서비스들을 셀프호스팅 하는 것이 좋다는 내용입니다. 개인적으로도 홈랩을 통해 여러 서비스를 호스팅하고 있습니다. 작년에 디지털 - 휴먼 API (2024)를 통해 대략 어떤 서비스들을 사용하고 있는지 소개한 적 있는데 이 서비스 중 상당수는 홈랩에서 셀프호스팅 하고 있습니다. 하지만 개인적으로는 셀프호스팅을 썩 권하지는 않는데 가장 큰 이유는 모든 종류의 문제해결을 직접 해내야 하기 때문입니다. 가령 적절한 보안 수준을 갖춰야 하고 긴급한 보안 업데이트를 늦지 않도록 수행해야 하며 기기가 장애를 일으키거나 소프트웨어가 충돌하는 등의 문제를 모두 직접 해결해야 합니다. 사실 이런 문제들은 셀프호스팅을 하기 전에는 문제로 느끼지도 않는 것들입니다. 기기가 장애를 일으킨다면 그냥 껐다 켜면 되고 또 소프트웨어가 충돌한다면 다시 설치하거나 어느 한쪽을 삭제하면 그만입니다. 하지만 일단 홉랩을 통해 셀프호스팅을 시작하면 이런 문제를 해결해야만 합니다. 2025년 10월 현재 아직 홈랩으로 사용하는 맥미니 기계의 OS 메이저 업데이트를 적용하지 않고 있는데 OS 업데이트 동안 서비스가 중단되는 문제 뿐 아니라 업데이트 후 무슨 일이 생길지 알 수 없기 때문입니다. 보안 업데이트가 아닌 이상 최대한 늦게 따라가려고 하는데 이 역시 업데이트 후 어떤 소프트웨어 충돌이 일어날지 모르기 때문입니다. 그저 며칠에 한번씩 검색을 통해 맥OS 26에서 도커 데스크탑이 문제를 일으킨다는 글이 나타나지는 않는지 눈치를 보고 있을 뿐입니다.
올해만 해도 장시간 서비스를 중단시킨 문제가 두 건 있었습니다. 둘 다 개인적으로 사용하는 퍼포스 서버 장애였는데 다행히 저와 소수의 사람들만 사용하는 서비스여서 장시간 서비스가 중단돼도 큰 문제가 되지는 않았습니다. 올해 초 발생한 퍼포스 서버 데이터베이스 오류 문제해결은 파일시스템에 문제가 생겨 퍼포스 데이터베이스 파일 중 하나가 깨져 서버가 오동작하는 문제였는데 이 때는 정확한 원인과 원인에 대한 정확한 해결책을 사용하는 대신 데이터베이스 파일 백업에서 이전 파일 세트를 꺼내다가 덮어씌워 문제를 해결했습니다. 당시에는 정확히 어느 데이터베이스 파일에 문제가 생겼는지 확인하는 명령을 몰랐기 때문에 이렇게 대응했고 앞으로는 문제가 생긴 파일을 찾아 정확히 그 파일만 덮어쓸 작정이었지만 지금은 이전과 같이 백업으로부터 멀쩡한 상태의 데이터베이스 파일을 덮어 쓸 작정입니다. 이 방법이 문제를 해결할 뿐 아니라 문제가 생긴 데이터베이스 파일을 체크포인트로부터 재생성하는 절차보다 단순하고 훨씬 덜 위험하기 때문입니다. 물론 이럴 수 있는 이유는 백업 소프트웨어가 파일시스템이 제공하는 스냅샷에 근거해 동작하기 때문입니다. 만약 백업 소프트웨어가 스냅샷 기반으로 동작하지 않는다면 절대 이렇게 할 수 없습니다. 두 달 전에 겪은 개인 퍼포스 장애 대응 보고는 엄밀히 말하면 장애라기보다는 제 착각이었지만 한순간 퍼포스 서버 전체가 사라졌다고 생각해 오싹해졌습니다. 앞서 소수의 인원만이 사용하므로 어느 정도 장애가 일어나도 괜찮다고 말했지만 그건 장애를 복구할 수 있을 때 이야기이지 데이터가 유실되어도 괜찮다는 의미는 전혀 아닙니다. 이를 위해 백업에 신경 쓰고 있는데 대단한 것 없이 그저 3-2-1 원칙을 정확히 지키는 정도입니다.
한편 이번에는 착각이 아니라 정말 스토리지 장애가 일어났습니다. 원래 퍼포스 서버는 독립된 레이드 1 기계를 사용하고 있었습니다. 2베이 기계를 살 때 굳이 더 많은 베이를 쓸 수 있는 기계를 피한 이유는 제 선에서 시중에서 구입할 수 있는 하드디스크 최대 크기인 24테라바이트 또는 30테라바이트 정도면 완전 충분했기 때문이기도 하고 또 레이드 1을 벗어나면 관리가 상당히 복잡해지기 때문이었습니다. 레이드 1은 그냥 하드디스크 두 개 중 어느 하나가 고장나면 이를 교체하기만 하면 됩니다. 리빌드 과정은 그저 두 하드디스크를 동기화 하는 것 뿐입니다. 하지만 레이드 5로 넘어가면 하드디스크 하나에 장애가 생길 때 교체하는데까지는 동일하지만 리빌드 과정은 많은 계산을 필요로 하고 이 과정에서 문제가 생길 여지가 너무 많았습니다. 당시 퍼포스 서버 전체 용량은 약 3테라바이트 정도였고 대략 1년에 최대 1테라바이트 정도 증가할 것으로 예상했는데 이 정도면 2베이 장비로도 아주 오랫동안 사용할 수 있을 거라고 예상했고 이 예상은 지금도 꽤 잘 들어맞고 있습니다. 그렇게 퍼포스 서버를 기존 단일 하드디스크에서 2베이 기계에서 레이드 1을 통해 운용하기 시작했습니다. 한동안은 딱히 불만을 가지지 않았지만 모든 작업이 한 박자 느린 것은 좀 신경 쓰였습니다. 퍼포스는 주로 내부 네트워크를 통해 사용될 것을 가정하고 만들어졌습니다. 그렇다고 인터넷을 통한 사용을 금지하지는 않지만 p4v나 p4a 같은 클라이언트의 동작을 살펴보면 서버가 아주 빨리 응답할 것을 가정하고 만들어져 있습니다. 하지만 인터넷을 통하면 여러 작업들이 한 박자씩 느려지는데 여기에 하드디스크를 통하면 좀 더 느려집니다. 이 점이 항상 불만이었습니다. 그러다가 아마존에서 외장형 SSD를 아주 싸게 구할 기회가 있었습니다. 레이드 1 기반으로 퍼포스 서버를 운용하던 이유는 이 데이터가 절대 사라지지 않아야 하기 때문입니다. 하드디스크 두 대 중 어느 하나에 장애가 발생하더라도 그냥 놀란 가슴을 진정시키며 하드디스크를 교체하고 아무 일 없었던 듯 사용하기만 하면 되는 상황을 기대햇습니다. 그런데 이 때 외장 SSD로 대체하면서 빠른 속도를 얻었지만 동시에 스토리지 기계에 장애가 일어날 때 서비스가 중단될 위험을 얻었습니다. 하지만 SSD는 어지간해서 장애가 일어나지 않는다고 알고 있었고 실제로 게임하는데 주로 사용하는 윈도우 기계의 SSD가 몇 년 째 완전히 멀쩡하게 동작하는 것을 생각하니 별로 걱정되지는 않았습니다. 게다가 문제가 생기더라도 백업으로부터 복원할 수 있으니 최악으로 치닫지는 않을 거라고 생각했습니다. 이 생각은 어느 정도 맞았지만 완전히 맞은 것은 아니었습니다. 근본적으로 아마존에서 싸게 산 외장형 SSD는 데이터를 옮기거나 이따금씩 사용하는 수준에는 적합했지만 홉랩 기계에 물려 24시간 사용하기에는 적절하지 않았습니다. 실은 이를 처음부터 알고 있었지만 어차피 소수의 인원이 사용하는 수준이었기에 문제 되지 않을 거라고 생각했습니다. 게다가 이전보다 훨씬 빨라진 응답 속도는 스토리지 기계에 장애가 생기면 서비스에 장애가 일어난다는 위험을 잊기에 충분했습니다.
그러다가 얼마 전 처음으로 SSD가 의도하지 않게 언마운트되는 현상이 일어났습니다. 모든 장치가 완전하게 동작할 수는 없고 1년에 한 번 정도 문제가 일어난다고 생각하면 대수롭지 않다고 봤습니다. 그냥 컨테이너를 삭제하고 스토리지를 다시 마운트 한 다음 컨테이너를 재생성하는 정도로 서비스를 복구했고 데이터베이스와 파일시스템 모두 문제 없었습니다. 그런데 이때부터 의도하지 않은 언마운트는 좀 더 자주, 그러니까 한 달에 한 번, 그 다음에는 한 주에 한 번 정도 발생하기 시작했습니다. 그런데 제가 사용한 외장 SSD는 SMART 정보를 외부에서 볼 수 있는 종류의 제품이 아니었습니다. 그래서 가격이 저렴할 수 있었다고 생각합니다. 그래서 SSD에 구체적으로 어떤 문제가 있는지 알 수 없었습니다. 뭔가 문제가 있다는 사실을 분명히 인지했지만 어떤 조치를 취해야 할 지 결정하기 어려웠습니다. 똑같은 SSD를 준비해야 할까요? 아니면 미리 이전에 사용하던 레이드 1 기계로 다시 서비스를 옮겨야 할까요? 전자는 비용 문제로 실행하기 어려웠고 후자는 긴 다운타임이 필요했을 뿐 아니라 서비스를 느리게 만들 것을 알고 있었습니다. 때문에 어느 쪽 조치도 딱히 취하지 않은 채 시간이 지나갔습니다. 그러던 어느 날 이번에도 의도하지 않은 언마운트가 일어났고 이번에도 같은 절차를 통해 서비스를 복구하다가 문득 백업 소프트웨어 로그를 쳐다보니 이 SSD를 백업할 때 APFS 스냅샷을 생성하지 않고 있었습니다. 앞서 스냅샷에 기반한 백업이 중요하다는 이야기를 했는데 스냅샷은 파일시스템의 특정 시점의 상태를 보장해줍니다. 백업 소프트웨어가 파일시스템에 스냅샷을 요청하면 운영체제는 그 시점의 파일에 접근을 보장합니다. 이 시점 이후에도 파일은 자유롭게 수정할 수 있지만 스냅샷 시점의 파일에 별도로 접근할 수 있도록 해줍니다. 이런 조치가 필요한 이유는 특히 데이터베이스의 경우 모든 파일이 정확히 같은 시점일 때 백업해야만 복원할 때 문제가 일어나지 않기 때문입니다. 만약 스냅샷 없이 파일을 백업한다면 파일마다 백업 시점이 달라지게 됩니다. 만약 이 사이에 특정 파일에 변경이 일어난다면 파일은 모두 백업 되어 있지만 각 파일의 백업 시점이 달라 정합성이 깨진 상태가 될 수 있습니다. 그래서 매번 데이터베이스를 익스포트 해서 백업할 것이 아니라면 반드시 스냅샷에 기반해 백업해야만 합니다. 그런데 퍼포스 스토리지로 사용되는 SSD가 스냅샷에 근거하지 않고 그냥 파일 단위로 백업되고 있었습니다. 뭔가 일이 잘못되고 있었습니다. 여전히 SSD는 파일에 접근할 수 있는 상태였지만 SMART 정보에 접근할 수 없는 이상 잦은 언마운트, 스냅샷 생성 실패는 더 이상 두고 볼 수 없었습니다. 이 SSD는 임시 데이터에 사용할 수는 있겠지만 24시간 동작해야 하는 라이브 서비스를 뒷받침하는데 사용할 수는 없었습니다. 모든 서비스를 이전에 사용했던 레이드 1 기계로 다시 옮기기로 결정합니다.
퍼포스 서버 스토리지를 하드디스크로 이전하기로 결정하자 다음 질문은 어떤 데이터로부터 파일을 가져올 것인지로 변했습니다. 선택은 크게 두 가지입니다. 3-2-1원칙에 따라 백업했을 때 이전에 사용할 수 있는 데이터는 총 세 가지입니다. 이 고민을 하는 순간에도 라이브로 동작하고 있는 원본 SSD, 로컬 백업, 오프사이트 백업입니다. 일단 원본과 로컬 백업을 사용할 수 있었으므로 오프사이트 백업에 손 댈 필요는 없었습니다. 하지만 원본과 로컬 백업 중 어느 것을 선택할지는 고민이었습니다. 원본 SSD 스토리지는 확실히 오동작하고 있었지만 데이터베이스나 파일시스템이 깨지지는 않았습니다. 또 앞서 데이터베이스 파일의 정합성에 문제가 생길 수 있다고 말했지만 로컬 백업 역시 스냅샷에 기반해 백업되지 않고 있었지만 다행히 데이터베이스 파일들이 모두 같은 시점에 백업 되어 있었습니다. 원본 SSD로부터 파일을 복사한다면 맥OS의 ditto
명령으로 모든 파일을 복사해 올 수 있었고 로컬 백업으로부터 복원한다면 Arq Backup으로부터 복원할 수 있었습니다. 이 고민을 할 시점에 이미 서비스를 중단하고 그 이후 백업이 수행된 상태였기 때문에 원본과 로컬 백업 양쪽 모두 최신 상태가 반영되어 이 주제로 어느 한 쪽을 선택하는데 영향을 줄 필요는 없었습니다. 아무래도 ditto는 파일 단위로 복사하고 또 싱글스레드로 복사할테니 시간이 많이 걸릴 거라고 예상했습니다. 반면 Arq Backup은 파일을 재구축하는데 CPU 자원이 필요하지만 여러 파일을 동시에 처리할 수 있으니 시간이 덜 걸릴 거라고 예상했고 이 예상은 어느 정도 맞았습니다. 그래서 스토리지 이전은 백업으로부터 복원하는 것으로 결정하고 실행했습니다. 최신 백업을 복원하되 복원 대상을 레이드 1 기계로 지정했습니다. 복원 예상 시간이 표시되지는 않지만 단위시간 당 복원되는 속도로 미루어 이틀 정도 걸릴 것 같았습니다. 하드디스크도, 인터페이스도 훨씬 더 빠른 속도를 지원하지만 항상 이들이 광고하는 속도에 비해 턱없이 느린 속도로 동작할 거라는 사실을 이미 알고 있었습니다. 백업 소프트웨어는 디듀플리케이션을 위해 파일을 약 64킬로바이트 단위 블록으로 나눠 저장하고 저장할 때마다 기존 블록 해시와 비교해 같은 블록이라고 판단하면 이 블록을 백업하지 않고 이전에 백업한 블록과 연결하기만 합니다. 그러니까 백업은 여러 64킬로바이트 단위 블록과 각각의 파일이 어떤 블록들로 구성되어 있는지 해시를 나열한 정보로만 구성되어 있습니다. 때문에 백업으로부터 파일 하나를 복원하려면 먼저 해시에 해당하는 블록들을 가져와 이들을 이어붙여야 합니다. 이 구간에 시간이 걸리기 때문에 복원은 하루에 2테라바이트 수준의 속도로 이루어졌습니다. 그래서 약 5테라바이트를 복원하는데 이틀 정도 시간이 걸릴 것을 예상했습니다. 만 하루가 지날 즈음 약 2.5테라바이트 정도가 복원되어 이 예상은 크게 틀리지 않았습니다.
하지만 그 만 하루가 지난 시점에 복원 과정에 문제가 있다는 것을 알게 됩니다. 개인적으로 퍼포스의 파일 관리를 정말 좋아하지만 파일을 실제 파일 경로와 이름에 근거해 저장하는 점은 좋아하지 않습니다. 만약 파일을 별도 포멧으로 저장하고 데이터베이스에 기록한 경로와 이름을 근거로 복원하는 구조라면 경로 길이, 경로나 파일 이름에 포함된 특수문자 등에 영향을 받지 않을 겁니다. 하지만 퍼포스는 파일 정보를 데이터베이스에 기록하기는 하지만 파일 자체는 파일 이름과 경로를 그대로 사용합니다. 그래서 운영체제 수준에서는 파일 이름에 허용되는 문자라도 퍼포스에서는 문제가 생길 수 있습니다. 가령 @
, …
, '&
' 같은 문자는 운영체제 수준에서 파일 이름에 사용할 수 있습니다. 하지만 퍼포스에서 이 문자들은 예약 문자로 사용되어 서브밋, 업데이트, 리네임 등을 수행할 때 대부분의 명령에 -f
인자를 붙여 강제로 수행해야만 명령이 수행되도록 만듭니다. 또 파일 이름과 경로에 한글을 포함한 다양한 범위의 문자가 포함될 수 있기 때문에 이 역시 파일시스템의 안정성에 근본적인 의문을 가지게 만듭니다. 퍼포스 관리 매뉴얼을 살펴보면 이런 이유 때문에 퍼포스 서버를 서로 다른 운영체제 간에 이전할 수 없다고 못 박고 있습니다. 사실 기술적으로 이전 가능해 보이지만 운영체제 별 개행문자의 차이, 유니코드 처리방식의 차이 때문에 데이터베이스에 기록한 경로와 실제 파일시스템에 기록된 경로 사이에 차이가 발생할 수 있기 때문에 서로 다른 운영체제 사이에 서버 이전은 불가능하다고 말하는 것 같습니다. 어쨌든 퍼포스는 파일을 원본 파일의 이름과 경로에 근거해 저장하므로 파일시스템으로부터 문제를 일으킬 여지가 있습니다. 이는 복원 과정에서 즉시 문제를 일으켰는데 일부 경로 길이가 아주 긴 파일들이 복원에 실패하고 있었습니다. 전체 복원되는 파일 수에 비하면 아주 작은 부분에 불과하지만 어쨌든 복원에 실패하고 있었습니다. 이들은 특정 파일의 특정 리비전일 뿐이므로 복원에 실패한 채로 놔둬도 아마 서버 사용에는 아무런 문제를 일으키지 않을 겁니다. 다만 p4 verify
명령을 실행할 때 에러를 내긴 하겠지만요. 복원이 진행되는 동안 문제가 생긴 파일을 수동으로 꺼내 복원하려고 시도했습니다. 백업 소프트웨어가 사용할 것으로 보이는 운영체제 API 수준에서 긴 경로를 처리하는데 실패했더라도 다른 방식으로 파일을 복원할 수 있을 거라고 예상했기 때문입니다. 이전에도 타임머신 백업으로부터 복원할 때 긴 경로를 복원하는데 실패했었지만 타임머신 GUI에서 실패하던 것이 타임머신 CLI 환경에서는 아무 문제가 없던 경험이 있었습니다.
일단 백업 소프트웨어 GUI가 복원에 실패했지만 GUI에 머물러 보기로 했습니다. 백업 소프트웨어로부터 복원에 실패한 파일을 더 짧은 다른 경로에 복원하자 문제 없이 복원되었습니다. 그 다음에는 그냥 맥OS의 파인더로 파일이 원래 있어야 할 위치에 복사해 봤습니다. 예상대로 복사에 실패했습니다. 하지만 이 동작을 CLI에서 수행하면 성공할 거라고 강하게 예상했습니다. 윈도우도 맥OS도 GUI의 동작과 CLI의 동작이 서로 다른 경우가 있습니다. 가령 윈도우에서 무슨 짓을 해도 파일이 삭제되지 않을 때가 있습니다. 파일을 사용 중인 프로세스도 없고 권한도 충분하지만 무슨 짓을 해도 익스플로러에서 삭제할 수 없습니다. 재시작을 하고 스토리지를 다시 마운트 하는 등 별 짓을 다해도 삭제에 실패합니다. 이럴 때 문제 해결 방법을 검색했다가 7zip 매니저의 GUI를 사용해 삭제하면 된다는 내용을 봤는데 허무맹랑하다고 생각했습니다. 7zip이 뭐라고 삭제되지 않는 파일을 삭제할 수 있다는 것인지 납득되지 않았습니다. 하지만 안 해보는 것보다는 낫겠다 싶어 시도했는데 너무나 말끔하게 아무 문제 없이 순식간에 파일이 삭제되는 것을 보고 당황했습니다. 몇 시간에 걸쳐 별 짓을 다 해도 삭제되지 않던 파일이 너무 순식간에 사라졌기 때문입니다. 이게 도대체 무슨 일인가 싶어 좀 더 찾아보니 윈도우 API를 사용해 파일을 삭제하는 대부분의 소프트웨어가 파일 삭제에 실패하는 상황이더라도 7zip 파일 매니저는 뭔가 제가 모르는 다른 방식으로 파일을 삭제하기 때문에 삭제 불가능한 파일을 삭제할 수 있다는 모양입니다. 맥OS에도 비슷한 문제가 있는데 타임머신 백업으로부터 복원할 때 아름답게 동작하는 타임머신 GUI는 파일시스템이 허용하는 긴 경로를 복원하는데 실패하지만 타임머신 CLI를 통해 복원하면 멀쩡히 복원됩니다. 타임머신 CLI는 GUI만큼 아름답지는 않지만 그냥 특정 시점의 백업을 볼륨으로 마운트 한 다음 파일을 꺼내 오는 식으로 아주 단순하게 동작하고 아주 긴 경로도 멀쩡히 복원합니다. 그런데 터미널 환경에서 앞서 더 짧은 경로에 성공적으로 복원한 파일을 원래 경로로 복사하려 하자 권한이 없어 실패합니다. 뭔가 이상한 상황입니다. 권한이 없을 수가 없었습니다. 커맨드 앞에 sudo
를 붙여 다시 시도해봤지만 또 실패했습니다. 파일 복사에 실패하는 긴 경로로 직접 이동해 ls
를 해봤지만 이번에도 ‘Operation not permitted’ 메시지가 나타납니다. 저는 이 메시지를 이전에 AWS에서 EBS 볼륨에 문제가 생겼을 때 볼륨이 읽기전용으로 바뀌었을 때 본 적이 있습니다. 때문에 저는 이 상황을 또 다른 ‘스토리지 장애’로 인식했습니다. 복원을 중단하고 상황을 좀 더 살펴봤지만 얻을 수 있는 정보가 없었습니다. 터미널 환경에서 레이드 1 기계에 파일 복사가 실패하고 있었고 파일 리스팅 뿐 아니라 du
같은 명령도 실패했습니다. 뭔가 단단히 꼬인 것 같습니다. 아무래도 디스크 유틸리티에서 볼륨을 다시 만들고 처음부터 다시 시작해야 할 것 같습니다. 이렇게 퍼포스 서버 다운타임의 첫 24시간이 헛되이 사라집니다.
그런데 이 시점에 여전히 원본 SSD는 접근 가능했습니다. 다만 뭔가의 문제로 라이브 서비스에 사용할 수 없는 상태일 뿐입니다. 여전히 모든 파일에 접근할 수 있었고 이 스토리지를 기반으로 한 백업도 스냅샷을 통하지 않는다는 점을 제외하면 정상 수행되었습니다. 그렇다면 백업에서 파일을 꺼내 오는 대신 그냥 이 원본 SSD로부터 ditto
로 레이드 1 기계에 파일을 복사하면 문제를 해결할 수 있지 않을까 하는 생각이 듥었습니다. 일단 레이드 1 기계에 볼륨을 재생성하고 바로 복사를 시작했습니다. 하지만 앞서 예상한 대로 백업 소프트웨어는 한 번에 여러 파일을 복원했지만 이번에는 단일 스레드로 한 번에 한 파일씩 복사했기 때문에 속도가 훨씬 느렸습니다. 대략 이전의 2배 정도 시간이 걸릴 것으로 예상했는데 그렇다면 약 4일이 걸린다는 의미입니다. 실은 시간이 걸리더라도 멀쩡히 복원된다면 큰 문제는 아닙니다만, 만약 이번에도 복원에 실패한다면 멀쩡한 백업이 두 카피 있음에도 문제가 좀 더 복잡해집니다. 달리 뭘 할 수 있지도 않은 것 같아 이번에는 그냥 기다리기도 합니다. 복원에는 약 50시간 정도가 걸릴 예정이었고 이 시간 동안 사일런트힐 f를 플레이 하며 보냈습니다. 고맙게도 파일 복사가 일어나는 동안 원본 SSD는 저혼자 언마운트 되지 않았습니다. 헌데 복원이 진행되는 동안 이번에도 앞서 경로 길이가 길어 문제가 일어났던 경로가 복원되기를 기다렸다가 터미널로 그 경로로 다시 이동해봤습니다. 이번에는 에러 없이 그냥 넘어갔기에 그 자리에 파일이 멀쩡히 있는지 확인해볼 생각이었습니다. 하지만 이번에도 ls
는 ‘Operation not permitted’를 토해냈고 저는 굉장히 혼란스러워졌습니다. ditto는 여전히 파일을 느리지만 꿋꿋하게 복사하고 있었고 겉보기에는 스토리지에 별다른 문제도 없어 보였습니다. 하지만 파일 목록을 볼 수는 없었고 이전과 마찬가지로 용량을 확인하거나 전체 파일 목록을 확인할 수도 없었습니다. 혼란스러운 시간 동안 잠시 진정하고 곰곰이 생각했습니다. 어쩌면 이 상황과 앞서 겪었던 상황은 사실 스토리지 문제가 아닐 수 있습니다. 물론 ditto는 멀쩡히 동작하는데 ls는 동작하지 않는 상황은 충분히 혼란스러웠지만 혹시 이게 맥OS의 권한 관리 문제가 아닐까 싶은 생각이 들었습니다. 윈도우에서라면 터미널은 내 권한 또는 관리자 권한으로 동작합니다. 내 권한으로 도는 터미널이 권한 부족으로 문제를 일으키면 관리자 권한으로 터미널을 실행하면 됐습니다. 그러면 그 안에서 실행되는 프로그램은 관리자 권한으로 실행됩니다. 맥에서도 그럴 거라고 생각했습니다. 내 권한으로 열린 터미널은 내 권한으로 실행되고 관리자 권한이 필요하면 명령어 앞에 sudo를 붙이면 된다고 생각했습니다. 그래서 ditto는 sudo ditto
로 실행했고 멀쩡히 돌고 있습니다. 하지만 sudo ls
는 동작하지 않았습니다. 이건 내 권한이나 관리자 권한 문제가 아니라는 뜻으로 이해했습니다.
설정 앱으로 이동해 프라이버시 메뉴를 눌러 ‘Full Disk Access’ 권한을 살펴봤습니다. 예상대로 제가 사용하던 Warp 터미널에는 권한이 없었습니다. 권한을 부여하고 터미널을 재시작한 다음 이전과 똑같이 파일 목록을 요구하자 이번에는 아무 문제 없다는 듯 결과를 토해냈습니다. 그러니까 터미널에서 내 계정의 권한으로 명령을 수행하더라도 터미널에게 스토리지 접근 권한이 없으면 명령에 실패하는 것이었습니다. 운영체제 입장에서는 사용자 권한으로 실패하든 스토리지 접근 권한이 없어 실패하든 어쨌든 실패는 실패이고 원인은 명령 수행을 허용하지 않는다고 말할 뿐이었지만 저는 이 메시지가 스토리지의 문제로부터 일어났다고 생각했습니다. 이전에 AWS에서 겪었던 문제 때문에 착각했습니다. 여전히 파일은 멀쩡히 복사되고 있었고 앞서 백업 소프트웨어로부터 복원할 때 문제를 일으키던 경로들이 아무 문제 없이 복사되었습니다. 마음을 좀 진정시킨 다음 상황을 살펴보니 문득 백업의 전체 복원 연습이 얼마나 중요한지 깨달았습니다. 사실 이전에도 백업 일부를 복원한 적은 여러번 있습니다. 기본적으로 퍼포스를 사용하는 이상 대부분의 작업 파일의 이전 버전을 꺼내 오는 건 복원의 영역이 아니라 그냥 형상관리도구에서 이전 버전을 꺼내오는 것에 불과합니다. 백업으로부터 일부 파일을 복원할 때는 뭔가 기술적인 문제가 생겼을 때 이를 복원학 위한 것이 대부분이었습니다. 일부 파일만 복원할 때는 아무 문제도 발생하지 않았습니다. 하지만 백업에 관심을 가지고 있는 입장에서 전체 복원 연습이 필요하다는 것을 알고는 있었지만 그게 어떤 의미인지는 잘 몰랐고 또 전체 복원 연습을 수행할 방법을 찾기도 어려웠습니다. 언젠가 시간 날 때 스크립트를 만들어 한 두어 달에 한 번 정도 전체 복원을 시도하고 각각의 파일을 복원해 해시를 확인하고 삭제하는 식으로 전체 복원 연습을 해야겠다는 생각을 하고 있었을 뿐 실행하지는 않았었습니다. 이렇게 실제로 전체 복원을 해 보니 복원 시간이 생각보다 굉장히 오래 걸린다는 점, 백업 소프트웨어 GUI 상에서는 파일시스템은 허용하지만 GUI 수준에서 허용하지 않는 경로 길이 문제가 일어난다는 점, 터미널에 권한이 부족할 경우 계정에 권한이 충분하고 또 sudo를 붙여 명령을 실행하더라도 실행에 실패해 스토리지가 고장난 것으로 착각할 수 있다는 점 등을 결코 알 수 없었을 겁니다.
첫 24시간을 헛되이 보내고 나서 다음 약 45시간이 경과하고 나서 복사가 끝났고 도커 컴포즈 파일을 새 경로에 맞춰 수정하고 실행하자 서버는 금새 정상으로 돌아왔습니다. 첫 몇 시간 동안은 레이드 1 빌드하는데 시간이 걸려 전체적으로 속도가 엄청나게 느려 이 상황이 그냥 놔두면 해결되는 것인지 아니면 개입해서 뭔가 조치를 취해야 하는 것인지 고민하게 만들었지만 빌드가 어느정도 진행되자 속도는 이해할 수 있는 수준으로 돌아왔습니다. 하지만 SSD에서 돌던 것만큼 빠릿하지는 않습니다. SSD에서 하드디스크로 바뀌었지만 여전히 스토리지가 기계적으로 고장날 가능성은 얼마든지 있습니다. 다만 이번에는 레이드 1 환경이니 하드디스크 두 개가 동시에 고장날 가능성은 낮은 편이고 또 백업도 로컬과 오프사이트 두 개 있으니 최악의 상황이 일어나지는 않을 거라고 예상합니다. 상황은 마무리되었고 이제 이번 스토리지 장애 대응으로 깨달은 점을 다시 정리해보겠습니다. 이미 앞서 충분히 여러번 말했지만 정리해두면 도움이 될 것 같습니다.
전체 복원 교훈:
- ‘3-2-1 원칙'에 따른 백업은 무조건.
- 전체 복원 테스트를 실제로 해 봐야 함. (경로 길이 문제, 터미널 권한 문제, 복원 시간 등 실제로 해 보지 않으면 알 수 없는 것이 많음. 또한 암호화된 볼륨에 접근할 수는 있는지, 오프사이트 백업 계정에 로그인은 할 수 있는지 등도 복원 테스트에 포함해야 함.)
- 터미널에서 명령이 실패하면 먼저 권한을 의심할 것. (맥OS에서 터미널 앱에 스토리지 접근 권한이 없으면 sudo를 붙여도 실패함.)
- 복원에는 웬만하면 CLI 환경을 사용할 것. (타임머신, Arq Backup 양쪽 모두 GUI 상에서는 경로 길이 제한이 있으나 양쪽 모두 CLI 환경에서는 이런 제한이 없음.)
- ditto는 싱글스레드로 동작하므로 백업 소프트웨어에 비해 복원이 느림.
- '4'를 미리 알았다면 불안한 SSD로부터 파일을 복사해오는 위험한 짓을 하지 않았을 것.