정리 대상 디렉터리에 DB 백업이라는 이름이 붙은 폴더가 있었다. 12기가였고 반드시 보존이라는 메모가 붙어 있어서 그냥 두면 되는 상황이었는데 안을 열어 봤다.
Table of contents
Open Table of contents
상황 — 12기가의 구성
mysqldump 결과가 아니라 DB 서버 네 대의 로그 디렉터리였고 데이터가 한 행도 없었다.
| 내용 | 크기 |
|---|---|
InnoDB 리두 로그 ib_logfile0·ib_logfile1 | 약 8G |
tar.gz 와 그 해제본 (같은 내용 이중) | 약 8G |
다른 폴더와 sha256sum 이 완전히 같은 순수 중복 | 약 2G |
나머지 — slow.log·error.log·binlog | 수백 M |
리두 로그가 8기가쯤을 차지하고 있었는데 MySQL 5.7 참조 매뉴얼의 InnoDB 리두 로그 항목대로 그것은 크래시 복구 때 불완전 트랜잭션이 데이터 파일에 쓴 것을 바로잡는 용도이고 체크포인트가 지나면 오래된 것부터 잘리므로, ibdata1 과 *.ibd 없이는 복구에 쓸 수 없다. 데이터 파일이 하나도 없는 이 아카이브에서 그 8기가는 아무것도 복구하지 못한다.
판단 기준 — 남긴 20메가의 근거
리두 로그와 중복을 걷어내니 12기가가 20메가가 됐다. 두 가지 방법이 있었는데 전부 지워 0 으로 만드는 것과 slow.log 만 남기는 것이다. 뒤쪽을 골랐다. 이유는 느린 쿼리 로그 안에 그 시절 스키마에 대한 실제 쿼리 텍스트가 들어 있어서다. 대신 20메가짜리 폴더가 무엇인지 다음 사람이 또 묻게 되는 것을 감수했다. 지금은 그 스키마 정의가 어디에도 없어서 쿼리 패턴을 역으로 볼 수 있는 유일한 자료였다.
그래서 남기되 남긴 이유를 함께 적었다.
ib_logfile0/1 제외 — 리두 로그는 순환 버퍼라 ibdata1·*.ibd 없이 복구 불가
db4/slow.log 보존 — 2020년 스키마에 대한 실제 쿼리 텍스트, 패턴 분석용
이걸 안 적으면 다음 사람이 또 12기가짜리 판단을 처음부터 하거나 남은 20메가를 찌꺼기로 보고 지운다.
아카이브 최상위 이름 충돌
네 서버의 tar.gz 를 한 디렉터리에 풀려다 문제를 발견했다. 넷 다 최상위 디렉터리 이름이 log/ 로 같았다.
db3.tar.gz → log/...
db3r.tar.gz → log/...
db4.tar.gz → log/...
db4r.tar.gz → log/...
같은 곳에 풀면 서로 덮어써서 마지막에 푼 것만 남는다. 최상위를 서버명으로 치환해 다시 묶어 넷을 나란히 풀 수 있게 했다.
검증 — 0건 검사와 대조군
재압축한 뒤 제외 대상을 뺀 모든 파일의 sha256sum 을 원본과 하나씩 맞췄고 전부 일치했다. 새 아카이브에 ib_logfile* 이 있는지도 tar -tzf 로 셌더니 0건이었다.
여기서 멈추지 않았다. 0건은 없다는 뜻일 수도 있고 검사가 아무것도 안 셌다는 뜻일 수도 있다. 그래서 원본 아카이브에 똑같은 검사를 걸었더니 몇 건이 나왔다. 검사식이 실제로 잡는다는 것이 확인됐으므로 새 아카이브의 0건은 진짜 0건이다.
이 한 번의 대조군 실행이 검증을 검증으로 만든다. 없으면 그저 0이 나왔다는 사실만 남는다.
원본 격리와 로그의 마지막 줄
12기가를 삭제하지 않고 _trash/ 로 옮겼다. 20메가짜리를 한동안 써 보고 아쉬운 것이 없으면 그때 지운다. 지우는 것은 언제든 할 수 있고 되살리는 것은 못 한다.
남은 error.log 를 열어 보니 한 시간이 안 되는 분량이었고 마지막 줄이 mysqld: Shutdown complete 였다. 운영 트래픽이 아니라 누가 가상 머신을 마지막으로 한 번 켜서 잠깐 돌리고 끈 기록이었다.
그리고 진짜 운영 덤프는 다른 데 있었다. 서버의 다른 디렉터리에 .sql.gz 덤프 파일 십여 개가 수십 기가로 있었고 그것을 복원한 라이브 DB도 있었다. 반드시 보존이 붙은 12기가는 진짜 백업이 아니었고 진짜 백업은 라벨 없이 다른 데 있었다.
라벨의 성질
이 라벨은 붙일 당시에는 맞았을 것이다. 급하게 서버를 정리하면서 일단 로그 디렉터리를 통째로 떠 두자는 판단이었을 것이고 그때는 안에 무엇이 있는지 확인할 시간이 없었을 것이다.
문제는 라벨이 그 상태로 굳는다는 점이다. 판단의 근거는 사라지고 결론만 남으므로 다음 사람은 검증할 방법이 없어 그대로 둔다. 몇 년이고 그렇게 남는다.
그래서 크기를 가치로 읽지 않고 보존 라벨을 만나면 안을 확인하며, 줄이고 남긴 것에는 남긴 이유를 적고, 0건 검사는 대조군을 만든 뒤에 믿고, 원본은 격리하되 지우지 않는다.
정리
- 반드시 보존이라던 12기가가 로그 디렉터리였고 데이터는 0행이었다
- 리두 로그는 데이터 파일 없이는 복구에 쓸 수 없다
- 12기가를 20메가로 줄이고 0이 아니라 20메가인 이유를 적었다
- 아카이브 최상위 이름이 같으면 한 곳에 풀 때 덮어쓴다
- 0건 검사는 원본에 같은 검사를 걸어 유효성을 확인한 뒤에 믿는다
- 원본은 삭제하지 않고 격리한다
- 라벨은 그때의 판단이고 결론만 남고 근거는 사라진다