Skip to content
isdnetworks
Go back

코드 추정보다 앞선 DB 사실

(수정됨)

한 상품에 딸린 channel_products 십여 건이 전부 이미지가 깨져 있는 상태였다. 코드를 읽으며 원인을 추정했지만 후보가 여럿이라 하나로 좁혀지지 않았다.

Table of contents

Open Table of contents

조사 — 코드가 낸 두 후보

첫째 후보는 파일 복사가 실패하는 경우였다. media_files 레코드 복제와 S3 copyObject 가 분리돼 있어서 복사가 실패하면 레코드는 있고 파일은 없는 상태가 되는데 그것이 정확히 깨진 이미지의 모양이다.

둘째 후보는 syncToChannels() 전체가 DB::transaction() 하나로 묶여 있다는 것이었다. 이미지 처리에서 예외가 나면 그 앞의 상품 정보 갱신까지 함께 롤백된다. 두 후보 다 그럴듯해서 코드만 읽어서는 어느 쪽인지 갈릴 수 없었다.

검증 — 데이터가 가른 것

그래서 코드를 덮고 데이터베이스 쪽 사실을 봤다. 십여 건 전부 created_at 과 updated_at 이 같아서 만들어진 뒤로 한 번도 안 바뀐 상태였다.

같은 대상의 product_histories 를 세어 보니 그것도 0건이었다. 두 사실을 합치면 동기화가 한 번도 성공한 적이 없다는 결론이 나오고 첫째 후보였다면 상품 정보는 갱신됐어야 하므로 둘째로 확정됐다.

상위의 수정 이력

확인차 상위 상품을 보니 그 뒤로 두 번이나 수정된 이력이 있었다. 수정할 때마다 동기화가 돌았을 텐데 자식은 처음 만들어진 시각 그대로였다.

두 번의 동기화가 다 롤백됐다는 뜻이 된다. 첫째 후보를 완전히 배제하려고 media_files.size 도 비교했는데 같은 파일명인데 크기가 달라서 복제 시점의 원본과 지금 원본이 다른 파일이었고 그 사이에 마스터 이미지가 바뀐 것이었다.

원인 — 복구를 막는 순환

이 진단의 결론이 생각보다 무거웠는데 상위를 아무리 수정해도 복구가 되지 않는다는 것이었다.

상위를 수정하면 동기화가 시작되고 이미지 처리에서 같은 예외가 나서 전체가 롤백되기 때문이다. 깨져 있어서 못 고치고 못 고쳐서 깨져 있는 순환이라 한 트랜잭션에 묶여 있는 한 부분 성공이 불가능했다.

보고에는 두 가지 방법이 있었는데 이 십여 건의 이미지를 손으로 복사해 넣고 끝내는 것과 syncToChannels() 의 이미지 처리와 상품 정보 갱신을 분리하는 것을 선행 조건으로 적는 것이다. 뒤쪽을 골랐다. 이유는 손으로 넣어도 상위를 다음에 수정하는 순간 같은 롤백이 또 나서다. 대신 복구가 코드 배포 뒤로 미뤄지는 것을 감수했다. 나누면 상품 정보는 갱신되고 이미지 처리는 별도로 실패하며 다음 시도에서 이미지만 다시 하면 된다.

판단 기준 — 두 지표와 순서

이 건에서 다른 조사에도 쓸 진단 지표 둘을 얻었는데 created_at = updated_at 이라는 것과 product_histories 가 0건이라는 것이다.

둘이 같이 나오면 이 레코드에 아무 일도 안 일어났다는 강한 증거이고 무언가 실패했나 보다가 아니라 성공한 적이 없다로 확정된다. 조사 순서는 코드로 후보를 뽑고 데이터로 판별한 뒤 배제한 것도 따로 확인하는 것인데 코드는 이럴 수 있다까지만 말하고 실제로 그랬다는 것은 데이터가 말한다.

정리


Share this post on:

Previous Post
한 단계 더 거쳐 조인한다
Next Post
개발용처럼 보이는 이름의 운영 DB