S3 의 파일 이름이 깨진 media_files 레코드들이 있어서 복구 도구에 이름 정정 로직을 넣었다. 한 번 돌리면 고쳐질 것으로 봤는데 정정은 도는데 복구가 안 됐다.
Table of contents
Open Table of contents
증상 — 안 고쳐진 복구
진단 결과를 보니 copy_from_parent 라는 이상한 분류로 들어가 있었다. 자기 원본이 있는데 상위 상품에서 복사한다는 분류였다.
도구는 상태를 판정해 처리 방법을 분류하는 diagnose 단계와 그 분류대로 처리하는 apply 단계로 돼 있었다. 정정 로직은 뒤쪽에 있는데 앞쪽이 이미 잘못 분류하고 있었다.
원인 — 판정이 쓴 깨진 이름
진단 코드를 열어 보니 깨진 original_name 으로 headObject 를 불러 존재를 확인하고 있었다. AWS 공식 문서대로 HeadObject 는 키가 없으면 404 를 돌려준다. 이름이 깨졌으면 그 키로는 못 찾고 원본이 없다고 판정한다.
그러면 자기 원본이 없으니 상위에서 복사하자는 분류로 간다. 정정은 이미 분류가 끝난 뒤에 돌기 때문에 아무리 고쳐도 분류를 못 바꾼다.
조치 — 두 곳을 같이 고쳤다
고치는 길은 두 가지가 있었다. 정정을 diagnose 앞으로 옮기는 것과 판정 쪽에 폴백을 넣는 것이다. 뒤쪽을 골랐다. 이유는 폴백은 이름과 무관하게 존재를 봐서다. 대신 폴백이 listObjectsV2 를 한 번 더 불러 진단이 느려지는 것을 감수했다.
headObject 가 실패하면 그 경로를 Prefix 로 목록 조회해 아래 객체가 있으면 원본이 있는 것으로 판정하게 했다. 이름이 무엇이든 그 아래 무언가 있으면 원본은 있다는 뜻이다. 폴백을 넣으니 분류가 backfill_self 로 바뀌었다. 정정도 같은 실행에서 돌아 단일 실행으로 복구가 성립했다. 같은 원인의 수정은 값을 고치는 곳과 그 값으로 존재를 판정하는 곳을 함께 봐야 완결된다.
주의 — 통과한 사전 실행의 함정
여기서 걸리는 것이 하나 있었다. 앞서 한 채널로 --dry-run 을 돌려 회귀 0으로 통과했고 그래서 됐다고 봤다.
그 채널에는 깨진 이름 레코드가 하나도 없었다. 없는 것을 검증한 통과라 아무것도 증명하지 않았고 0건이 통과가 아니라 아무것도 측정하지 않은 것이었다.
검증 — 실행으로 한 확인
그래서 실제로 깨진 이름을 가진 상품을 골라 진단을 찍어 봤고 거기서 잘못된 분류가 드러났다. 검증 대상을 고를 때 그 조건에 해당하는 것이 있는지를 먼저 봐야 한다.
고친 뒤에는 --dry-run 이 아니라 실제 실행으로 끝까지 돌렸다. 미디어 아홉 개에 변환 다섯 종을 곱한 45개가 생성되고 이름 정정도 반영된 것을 COUNT(*) 로 확인했다.
정리
- 정정 로직을 넣어도 그 앞의 판정이 틀린 값을 쓰면 소용없다
- 값을 고치는 곳과 그 값으로 판정하는 곳을 함께 고친다
- 단건 조회가 실패해도 목록 조회 폴백으로 존재를 확인할 수 있다
- 해당 케이스가 없는 대상의 사전 실행 통과는 아무것도 증명하지 않는다
- 검증 대상을 고를 때 그 케이스가 있는지 확인한다
- 실제 사례로 끝까지 실행해 수치로 확인한다
- 0건이 통과가 아니라 아무것도 측정하지 않은 것일 수 있다