Skip to content
isdnetworks
Go back

개수가 아니라 실패로 판정한다

앞서 있었던 InnoDB 교착 사고 때 자식 항목 넷이 깨졌다고 판정해 두었다. 판정 근거는 이것 하나였다.

SELECT COUNT(*) FROM media WHERE model_id = <자식 ID>;
-- 0

자체 media 가 0개라는 것이었다. 복구 작업을 준비하다가 그 판정을 한 번 더 확인해 보기로 했다.

Table of contents

Open Table of contents

상위가 살아 있었다

복구 스크립트를 짜다가 본문이 실제로 무엇을 가리키는지 확인했다.

SELECT html FROM html_contents WHERE id = <자식 본문 ID>;

거기서 뽑은 이미지 ID 둘을 다시 조회하니 model_type 이 상위 항목이었고 저장소에도 존재해 응답이 정상이었다. media 행이 없는데 정상인 이유가 본문이 상위 media 를 가리키고 있기 때문이었다.

왜 상위 것을 가리키는지 코드를 보니 복사가 성공해야 도는 치환이 있었다.

// 복사 후 본문 치환
private function rewriteCopiedHtmlBody($child, $mapping)
{
    // {도메인}/{원본 ID}/  →  {자식 ID}
}

rewriteCopiedHtmlBody 가 복사된 media 로 본문 주소를 바꾸는 것이다. 복사가 실패하면 rewriteCopiedHtmlBody 가 안 돌아 본문이 상위 주소를 그대로 가리키고, 상위가 살아 있으면 화면은 아무 문제가 없다. 즉 media 가 없는 것이 깨진 것이 아니라 치환이 아직 안 된 상태였다.

판정 기준을 바꿨다

그래서 깨짐 판정을 mediaCOUNT(*) 가 아니라 실제 응답으로 하기로 바꿨고 조회해서 정상적으로 돌아오면 깨지지 않은 것으로 본다.

그 기준으로 html_contents 를 따라가며 다시 세어 보니 대상이 크게 줄었고 목록도 달라졌다. 처음 판정에 있던 것 일부가 빠지고 없던 것 일부가 들어왔다. 기준을 바꾸니 대상 자체가 바뀌는 것이라 복구 계획도 다시 짜야 했다.

잘못된 대상에 복구했다면

처음 판정대로 복구를 돌렸으면 어떻게 됐을지도 생각해 봤다. 멀쩡한 항목에 자식 행을 새로 INSERT 하는 결과가 된다.

INSERTmedia 는 아무것도 안 고치고 자리만 차지하는데 정작 실제로 깨진 것은 목록에 없어 그대로 남는다. 그리고 실제로 깨진 것은 목록에 없으니 그대로 남는다. 복구 작업이 아무 효과도 없이 끝나면서 끝났다고 보고될 뻔했다.

완료 판정도 같은 기준

복구 뒤에 무엇으로 완료를 판정할지도 같은 문제였다. COUNT(*) 가 늘어난 것을 완료로 보면 앞의 오판이 그대로 반복된다.

그래서 복구 뒤에도 실제로 조회해서 정상 응답이 오는지로 판정하게 했다. 만든 개수가 아니라 의도한 상태가 됐는지를 보는 것이다. 앞뒤 판정 기준이 같아야 복구 작업 전체가 일관된다.

교훈 — 재기 쉬운 것과 중요한 것

이 일에서 남은 것은 재기 쉬운 것과 중요한 것이 다르다는 점이었다. mediaCOUNT(*)SELECT 한 줄이면 나오지만 응답 확인은 실제로 불러 봐야 나온다.

그래서 쉬운 쪽을 지표로 삼았고 그것이 잘못된 신호였다. 편한 측정이 답을 주지 않을 때는 불편한 측정을 해야 한다. 마지막에는 LEFT JOIN 으로 두 조건을 합친 SELECT 하나로 대상을 확정할 수 있게 정리했다.

정리


Share this post on:

Previous Post
OS 업데이트가 아니라 벤더 도구로
Next Post
옛 망 구성을 기록으로 남겼다