Skip to content

통계 정체를 실제 미반영 세대 기준으로 감지 (2026-09-10)

  • 기간: 2026-09-10, Codex 1세션. 오너 지시: “재발방지 작업 좀 진행해줘”.
  • 랜딩: 앱 PR #1505release/v0.17.9, 2026-09-10 12:53:07 KST, merge a72c048b786083d6443aee07983dcaf976d5db6f. 구현 커밋 63821773·e83b8343. main 반영·정기 실행은 미완료다. DB migration·Edge·앱 화면 변경은 없다.
  • 설계서: 없음. #1432 분석·Phase 계획.
  • 정본: 통계 정체 감지와 대응, 앱 scripts/monitor-stats.mjs.github/workflows/stats-health.yml.
  • 도구: 읽기 전용 Management API, 독립 PostgreSQL DB·다중 연결. 원시 로컬 로그는 작업 디렉터리의 work/에 있고 git에는 포함하지 않는다.
  • 게이트: 단위 15건·실제 DB 2건. 앱 precheck·hosted DB에 DB 회귀 등록. 전체 브라우저/화면 검사를 이번 작업에서 반복하지 않는다.
  • 버그리포트: BUG-084 PM-08 후속.

Phase 현황

Phase내용상태
Phase 1세대·필요 작업 기반 읽기 전용 판정완료, 63821773
Phase 2실제 DB 회귀와 Actions 연결완료, e83b8343
Phase 3문서·precheck·release 반영완료, 앱 #1505·문서 PR #34

1. 배경

#1432의 저장 장애와 최신 통계는 v0.17.4·v0.17.5로 복구됐고, #1465는 v0.17.7에서 예약 대기를 줄였다. 그러나 cron SQL이 성공해도 내부 worker가 실패 상태를 반환할 수 있어 성공 여부만 보는 검사는 통계 정체를 놓친다.

2. 문제 제기

2026-09-10T03:29:55Z Production 읽기 전용 실측에서 5계정 모두 최신 세대, pending/processing 0건이지만 과거 failed 52건이 남아 있었다. 단순 failed 건수 경보는 현재 정상인 상태를 장애로 오보한다. 기존 성능 probe에는 수동 집계만 있고 정기 실패 판정이 없었다.

D08 #1412는 다른 담당자가 Phase 4/5까지 worker 수리·설정 단일 원천을 구현·검증한 상태였다. D04 #1403은 v0.18.0 통합 상태, D11 #1422는 별도 통계 게시 전환 범위다. 이번 작업은 이들의 코드·브랜치를 중복 수정하지 않고 PM-08 감지를 맡았다.

3. 해결 방안

요청 세대가 게시 세대보다 앞선 경우에만 필요한 작업을 대조한다. 정체·시도 소진·만료 임대·중지된 예약·현재 저장 잠금 대기를 판정하며 개인정보 없는 집계만 남긴다. cron 성공이나 실패 행 전체 개수만 보는 안은 각각 누락·오보 때문에 기각했다. 자동 재등록·실패 삭제·제한시간 확대는 감지 범위에 포함하지 않았다.

4. 적용한 내용

Phase 1은 10초 제한의 읽기 전용 API, 집계 응답 검증, 비정상 exit 1을 구현했다. API 오류 본문이나 원본의 추가 필드를 로그·artifact에 복사하지 않는다. Phase 2는 실제 DB 상태와 두 연결의 잠금 경합으로 감지를 검증하고 15분 주기 Actions를 연결했다.

잠금 회귀는 작은 독립 DB에서 쓰기 함수가 행 잠금에 대기하는 상황을 만든다. 실제 제품 RPC 전체의 동작 검사를 대체하지 않는다. 모든 테스트 DB를 삭제하고, Production에서는 정상 상태를 읽기만 했다.

5. 적용 결과

항목결과
정기 판정수동 집계만 → 15분 예약 검사 코드 v0.17.9 release 반영. main 반영 전이므로 실제 정기 활성화는 미완료
과거 실패 오보과거 failed 52건·5계정 fresh → 정상 판정
장애 감지필요한 실패·정체·임대 만료·cron 중지 상태 → 실패, 정상 재처리·정착 상태 → 오보 제외
실제 잠금 표본DB 쓰기 차단 → 경보 → 잠금 해제 뒤 정상
단위15건 통과
실제 DB2건 통과, 약 8.94초·5.59초
Phase별 checkPhase 1 3,388통과/0실패/33조건부skip, Phase 2 3,388통과/0실패/35조건부skip. 새 DB 2건은 별도 실행에서 통과
Production2026-09-10T03:35:50Z 읽기 전용 검사 정상: 5계정·미반영 0. 데이터/cron 변경 없음. 집계 원시 결과
사전검증1회 7분37초, static·단위3388/0실패/35조건부skip·DB전체재생·스냅샷·pgTAP110파일/2001단언·실제DB19/skip0·큰이력수렴 통과
큰 이력 회귀660세션·7920세트, 계산 중 실제 생성58ms/수정44ms/삭제17ms·각 영수증1건, 최종수렴·전체재생동치·실제57014·임대교체 통과
Merge Check실행34434963601 1회 성공, 잡67초. 병합 tree 5f0cdfbef20036efcbec2ae52d77a5e8c7fcfb2c = precheck HEAD tree. 큐에서 full CI는 재실행하지 않음
문서로컬 check(약관4버전·317경로)·VitePress build·공개자산31개 통과. PR #34의 원격 checks는 조회 시 보고되지 않아 원격 CI 성공으로 기록하지 않음
실제 Actions 알림 수신미검증. GitHub 사용자 알림 설정에 따름

6. 이번 개선으로 향상된 것

과거 실패 행과 실제로 남아 있는 통계 장애를 구분하는 판정이 실행 코드와 DB 회귀로 남았다. 알림을 없애려고 원본이나 작업 상태를 바꾸지 않으며, 조회 실패도 정상으로 숨기지 않는다. 운영자가 감지 결과에 따라 조사할 절차를 정본에 정리했다.

남은 것

main 반영 후 예약 실행·GitHub 실패 알림 전달은 아직 확인 전이다. #1432 전체 종결과 D08·D11의 구조 수리·운영 반영을 이번 감지 구현 완료로 대신하지 않는다. 예약 지연과 순간 잠금 표본의 한계가 있으며 최대 탐지시간이나 모든 저장 지연을 보장하지 않는다.