개발 slecs

공급사 포털 데이터 정합성 불일치 원인 분석 보고서 작성

목차

공급사 포털처럼 외부 데이터가 유입되는 시스템은 데이터 정합성 문제가 비교적 자주 생긴다. 내부 로직이 완벽해도 공급사 측 입력 형식이 조금만 달라지거나 처리 타이밍이 어긋나면 집계 숫자가 틀어진다. 문제는 이런 불일치가 로그에 대놓고 에러로 찍히는 게 아니라는 거다. 그냥 숫자가 미묘하게 맞지 않거나, 누락 건이 조용히 쌓이거나. 에러가 없으니 알람도 없고, 나중에 수동으로 숫자를 맞춰보기 전까지는 모르고 지나간다.

이번에 작성한 보고서(20260426 0027 supplier portal ralplan)도 그런 맥락에서 시작됐다. 운영 중 특정 수치 불일치가 감지됐고, 단순 로그 확인으로는 전체 그림이 안 보였다. SQL로 직접 집계해서 데이터를 눈앞에 꺼내놓는 게 필요했다.

왜 보고서를 먼저 쓰는가

코드를 바로 고치러 들어가지 않은 이유가 있다. 가설이 틀린 상태로 수정에 들어가면 엉뚱한 곳을 건드리게 되고, 운이 없으면 다른 문제를 새로 만들기도 한다. 수정 이후에 "정말 고쳐진 게 맞아?"를 검증할 기준도 없어진다. 보고서가 먼저 있어야 수정 전/후를 비교할 수 있다.

분석 프로세스 자체는 단순하다.

  • 관련 내부 테이블에서 집계 쿼리 실행
  • 기대값 vs 실제값 비교 섹션 구성
  • 이상 항목을 표로 나열하고 원인 가설 기재
  • 재현 케이스 정리 및 후속 액션 도출

이 순서에서 중요한 건 발견과 가설을 같은 단계에서 처리하는 것이다. 이상한 숫자를 발견했으면, 바로 옆에 "왜 그럴 것 같다"를 붙여놓는다. 나중에 다시 볼 때 맥락이 남아있고, 다른 사람이 봐도 흐름을 따라갈 수 있다. 발견만 쌓아두면 나중에 다시 열었을 때 왜 이걸 기록했는지 모를 때가 생긴다.

보고서 포맷으로 HTML을 선택한 건 숫자 테이블이 많아서다. 마크다운도 가능하지만 렌더링이 환경에 따라 달라지고, 테이블이 많을수록 편집기 미리보기와 실제 출력 사이에 차이가 생긴다. HTML은 브라우저에서 열면 그냥 보인다. 차트를 인라인으로 넣기도 쉽고, 파일 하나로 닫혀있어서 공유할 때도 첨부 하나로 끝난다.

집계 쿼리 패턴

데이터 정합성 분석에서 핵심은 기대값과 실제값을 나란히 뽑는 것이다. 어디가 다른지 찾으려면 두 숫자를 같은 행에 붙여놓는 쿼리가 필요하다.

SELECT
    s.supplier_id,
    s.expected_count,
    COUNT(r.id)                       AS actual_count,
    s.expected_count - COUNT(r.id)    AS diff
FROM supplier_submissions s
LEFT JOIN records r
    ON r.submission_id = s.id
   AND r.status != 'cancelled'
GROUP BY s.supplier_id, s.expected_count
HAVING s.expected_count != COUNT(r.id)
ORDER BY diff DESC;

HAVING 조건으로 차이가 있는 것만 걸러내면 이상 항목이 바로 튀어나온다. diff 내림차순 정렬로 가장 큰 불일치부터 보이니까 우선순위도 자연스럽게 잡힌다. 단순한 구조지만, 이 쿼리 하나가 "어디서 숫자가 틀렸는지"를 가장 빠르게 알려준다.

처리 누락 건 확인은 LEFT JOIN의 null 체크로 처리했다.

SELECT s.id, s.created_at, s.supplier_id
FROM supplier_submissions s
LEFT JOIN records r
    ON r.submission_id = s.id
WHERE r.id IS NULL
  AND s.created_at < NOW() - INTERVAL '1 hour';

1시간 이상 지났는데 처리 레코드가 없으면 누락 의심 케이스로 분류한다. 시간 기준은 시스템 SLA에 따라 달라야 하지만, 이 형태의 쿼리가 누락 후보를 추려내는 표준 패턴이다. 처음 짤 때는 시간 조건 없이 돌렸다가 오래된 취소 건까지 다 걸려서 노이즈가 심했다. 조건을 하나씩 추가하면서 범위를 좁혀나가는 과정이 분석의 일부다.

이번 분석 결과와 후속 처리

항목 상태
데이터 정합성 일부 불일치 발견
처리 누락 건 확인 및 후속 조치 필요
쿼리 성능 허용 범위 내
엣지 케이스 추가 검토 필요

정합성 불일치와 누락 건은 각각 별도 커밋으로 픽스했다. 보고서 → 수정 → 재검증을 한 사이클로 묶는 방식이다. 수정 이후 같은 집계 쿼리를 다시 돌려서 diff가 0이 됐는지 확인하는 것으로 마무리한다. 이 검증 단계를 빠뜨리면 "고쳤다"와 "고쳐진 것 같다" 사이 어딘가에서 끝나게 된다.

엣지 케이스는 이번 사이클에서 완전히 닫지 않았다. 재현 조건이 명확하지 않은 케이스를 성급하게 수정하면 사이드 이펙트 리스크가 생긴다. 일단 모니터링 대상으로 분류하고, 동일 케이스가 다시 발생하면 그 시점의 데이터와 함께 재분석하는 쪽을 선택했다. 지금 당장 고치는 것보다 재현 조건을 확실히 잡는 게 더 안전하다.

쿼리 성능은 현재 허용 범위 내였지만, 집계 대상 테이블이 커지면 인덱스 전략을 다시 봐야 한다. submission_id, status, created_at 조합 인덱스가 없으면 나중에 풀스캔이 나온다. 지금 당장 문제가 없다고 넘어가는 게 아니라, 보고서에 미래 리스크로 별도 메모해두는 편이다. 나중에 성능 이슈가 생겼을 때 "이미 알고 있었던 항목"으로 대응 속도가 달라진다.

가장 효과적인 분석 방법은 결국 단순하다. "내가 예상한 숫자"와 "실제 DB 숫자"를 나란히 놓고 비교하는 것. 차이가 있는 곳이 버그나 로직 오류의 위치를 가리킨다. 이 원칙만 지키면 어떤 도메인의 정합성 문제든 접근법은 같다. 도구나 형식은 바뀌어도 이 비교 구조가 흔들린 적은 없었다.

데이터 기반으로 의사결정하는 루틴을 유지하는 이유도 거기 있다. 쿼리가 쌓이고, 보고서 포맷이 표준화되고, 이 유형의 문제는 이쪽을 보면 된다는 패턴이 생긴다. 이번 보고서도 그 아카이브에 하나 추가됐다.

댓글 0

첫 댓글 달아줘.