DB 백업은 매일 돌고 있었다. crontab 에 등록돼 있고 파일도 쌓여 있었다. 그런데 그걸로 정말 복구가 되는지는 한 번도 확인한 적이 없었다.
Table of contents
Open Table of contents
돌고는 있었다
스크립트는 간단했다.
#!/bin/bash
mysqldump -u root -p'****' shopdb > /backup/shopdb_$(date +%Y%m%d).sql
매일 새벽에 돌고 날짜별 파일이 쌓였다. 크기도 매일 조금씩 커지고 있어서 겉으로는 정상으로 보였다. 확인한 것이 파일이 생긴다는 사실뿐이라는 것을 그때는 몰랐다.
넣어 보니 셋이 걸렸다
시험용 DB를 만들어 어제 파일을 넣어 봤다.
mysql -u root -p test_restore < /backup/shopdb_20150121.sql
첫째로 오류가 나도 계속 진행됐다. 중간에 오류가 몇 개 지나갔는데 그대로 넘어갔고 끝나고 SHOW TABLES 로 세니 원본보다 적었다.
나중에 안 것인데 mysql 은 원래 SQL 오류가 나면 거기서 멈춘다. 계속 가게 하는 것은 --force 이고 우리 스크립트에 그것이 붙어 있었다. 붙여 둔 이유는 아무도 기억하지 못했다. 떼고 나니 오류가 나는 자리에서 바로 멈춰서 무엇이 문제인지가 보였다.
둘째로 시간이 오래 걸렸다. 파일이 몇 GB 였는데 넣는 데 40분 넘게 걸렸다. 실제 장애라면 그 40분 동안 서비스가 멈춰 있는 것인데 그 생각을 안 하고 있었다.
셋째로 어제 것이라 오늘 데이터가 없었다. 새벽 3시 백업이면 그 뒤 하루치가 통째로 없다. 주문이 들어오는 쇼핑몰에서 하루치가 사라지면 그건 복구라고 부르기 어렵다.
파일 자체에도 문제가 있었다
복구를 해 보니 백업 쪽도 다시 보게 됐다. 같은 디스크에 저장하고 있어서 디스크가 고장 나면 DB 와 백업이 함께 사라진다. 보관 기간이 없어 파일이 계속 쌓이고 있었고 언젠가 가득 차면 백업이 실패하는데 알림이 없어 실패한 줄도 모를 상황이었다.
비밀번호는 스크립트에 적혀 있는 것보다 더 나쁜 자리에 있었다. -p 뒤에 붙여 명령줄로 넘기면 그 배치가 도는 동안 ps 로 아무나 볼 수 있다. 매뉴얼도 명령줄에 비밀번호를 주는 것은 안전하지 않다고 보고 옵션 파일을 쓰라고 안내한다.
네 가지를 고쳤다. 같은 서버 안에만 두지 않고 다른 장비로 하나 더 보내게 했고 $? 를 보고 실패하면 알림이 가게 했다.
mysqldump ... > $FILE
if [ $? -ne 0 ]; then
# 실패 알림
fi
여기서 하나 더 알게 됐다. 명령이 성공해도 파일이 온전하다는 보장은 없다. 디스크가 가득 차면 중간에 잘린 파일이 만들어지고 $? 는 0 으로 나올 수 있다. 그래서 파일 크기가 이전 것과 비슷한지도 함께 봤다.
오래된 것은 며칠치만 남기고 지우게 했다. 지우는 스크립트를 잘못 짜면 백업이 통째로 날아가므로 실제로 지우기 전에 목록만 출력해 몇 번 확인했다. 비밀번호는 chmod 600 으로 소유자만 읽는 옵션 파일에 넣고 스크립트가 그것을 참조하게 했다.
아직 못 푼 것
하루치 손실을 못 풀었다. 하루에 한 번 뜨는 것으로는 그 사이 데이터가 없고 더 자주 뜨면 그만큼 부하와 시간이 든다. 바이너리 로그를 켜 두고 mysqlbinlog 로 백업 시점 이후를 다시 먹이는 방법이 있다고 하는데 아직 이해가 부족하다. 다음에 이걸 봐야 한다.
복구에 걸리는 40분도 그대로다. 이걸 줄이는 방법이 있는지 아직 모른다. 다만 못 푼 것을 못 풀었다고 적어 두는 것과 모르는 채 두는 것은 다르다고 보고 목록에 남겼다.
정리
- 백업이 있다는 것과 복구가 된다는 것은 다르다
mysql은 원래 오류에서 멈춘다 —--force가 붙어 있으면 지나간다- 끝난 뒤
SHOW TABLES로 개수를 세어 본다 - 같은 디스크에 두면 백업이 아니다. 다른 곳으로 하나 더 보낸다
$?가 0 이어도 파일이 온전한지는 별개다. 크기를 이전 것과 비교한다-p뒤에 비밀번호를 붙이면ps로 보인다 —chmod 600옵션 파일에 둔다- 삭제 스크립트는 목록만 먼저 내 보고 켠다
- 하루치는
mysqlbinlog로 메우는 방법이 있다. 아직 못 풀었다