Skip to content
isdnetworks
Go back

백업을 두 곳에 뒀다

침입 조사에서 백업이 유용했던 일이 있어서 그 뒤로 백업을 제대로 해 두기로 했다. 원래도 crontab 에서 매일 밤 mysqldump 가 돌고는 있었는데 다시 보니 걸리는 것이 둘 있었다.

Table of contents

Open Table of contents

같은 서버에만 있었다

덤프 파일이 같은 서버의 다른 폴더에 쌓이고 있었다.

매일 밤 DB 덤프
같은 서버의 다른 폴더

폴더가 다르니 나눠 둔 것 같지만 디스크가 죽으면 둘 다 죽고 침입당하면 둘 다 당한다. 원본과 사본이 같은 운명을 공유하면 사본이 아니다.

두 번째는 복구를 한 번도 해 본 적이 없다는 것이었다. 확인한 것은 파일이 생긴다는 사실뿐이었다.

파일이 있는 것과 복구되는 것이 다르다는 것이 이번 작업의 핵심이었다. 파일이 있다는 것은 뭔가 만들어졌다는 뜻이고 복구된다는 것은 그것으로 되살릴 수 있다는 뜻이다. 중간에 깨진 파일은 앞의 조건만 만족한다.

그래서 시험용 서버에 며칠치를 실제로 넣어 봤다. CREATE DATABASE 로 빈 것을 만들고 mysql < dump.sql 로 부어 보는 것인데 하나가 중간에서 멈췄다.

검증 — 잘린 파일을 걸러 냈다

들어가지 않은 파일의 크기를 du 로 다른 날과 비교하니 훨씬 작았다. 중간에 끊긴 것이다.

그날 로그를 보니 덤프를 쓰는 도중에 디스크가 찼다. 문제는 그렇게 중단돼도 mysqldump 가 쓰던 파일은 남는다는 것이었다. 잘린 채로 남아서 겉으로는 정상으로 보인다.

덤프 뒤에 확인을 두 가지 넣었다.

크기가 최소값보다 큰가
tail -1 이 정상 종료 표시인가

뒤쪽이 확실했다. mysqldump 는 다 쓰고 나서 마지막에 -- Dump completed on 으로 시작하는 주석 한 줄을 붙인다. 중간에 끊기면 그 줄이 없다. 크기만 보면 그날 데이터가 적었던 것인지 잘린 것인지 애매한 경우가 있는데 이건 명확하다.

다만 이 검사에는 전제가 하나 있다. --skip-comments 를 주면 그 줄 자체가 안 나온다. 옵션을 누가 건드리면 검사가 조용히 아무것도 안 보는 상태가 된다. 그래서 덤프 명령과 검사를 같은 스크립트에 두고 옵션을 거기서만 정하게 했다.

다른 곳으로 옮기고 대조했다

첫 번째 문제도 고쳤다. 서버에서 덤프를 뜨고 그것을 다른 곳으로 보내 두 곳에 있게 했다.

그런데 여기도 같은 함정이 있었다. rsync 가 0 으로 끝났다는 것이 파일이 제대로 도착했다는 뜻은 아니다. 보낸 것과 도착한 것을 대조해야 한다.

보낸 쪽에서 계산
받은 쪽에서 계산
    비교

크기를 비교하고 양쪽에서 sha256sum 을 계산해 맞췄다. 크기만 보면 내용이 달라도 같은 값이 나올 수 있는데 해시는 내용이 다르면 다르게 나온다. 대조는 지정한 방식과 다른 방식으로 되읽는 것이어야 뜻이 있다.

보관과 삭제와 정기 시험

두 곳에 쌓이니 공간이 문제가 됐다. 보관 기간을 세 단으로 정했다.

최근 것    며칠치
주 단위    몇 주
월 단위    몇 달

가까운 것은 촘촘하게 두고 먼 것은 드물게 둔다. 어제 문제를 조사할 때는 어제 것이 필요하고 몇 달 전 상태를 볼 때는 그 무렵 것 하나면 되기 때문이다. 필요한 정도가 다르니 간격도 달라야 했다.

지우는 스크립트를 넣을 때는 잘못 지우면 백업이 없어진다는 것이 걸렸다. find -mtime 으로 대상을 고르되 처음에는 rm 없이 목록만 내게 했다. 며칠 보면서 목록이 맞는 것을 확인한 뒤에 실제 삭제를 켰다.

마지막으로 복구 시험을 한 달에 한 번 아무 날짜나 골라서 하도록 정기로 만들었다. 한 번 해 보고 끝내면 그 뒤에 깨져도 모른다.

시험할 때 무엇을 보면 통과인지도 함께 적었다.

넣는 중 오류가 없나
주요 테이블의 행 수가 그럴듯한가
최근 데이터가 들어 있나

행 수는 COUNT(*) 로 보고 최근 데이터는 MAX(reg_date) 가 그 덤프 날짜에 가까운지로 본다. 복구해 봤다는 말만으로는 부족하고 넣고 나서 무엇을 볼지가 있어야 했다.

정리


Share this post on:

Previous Post
실패 목록만 있고 이유는 없었다
Next Post
잘되는 경우만 시험했다