유대선

테이블은 완료라는데 실제 일은 안 끝나 있었다

ERP로 보내는 트랜잭션 인터페이스가, 뒤쪽 작업은 실제로 실패했는데도 행을 "성공"으로 찍고 있었다. 로그는 어떤 건 빠지고 어떤 건 두 번 남았다. 무엇이 깨졌는지, 그리고 코드에 없던 한 줄에 대한 짧은 기록.

·2 분 소요·English version →

ERP로 보내는 트랜잭션 인터페이스가, 뒤쪽 작업은 실제로 안 끝났는데 행을 "성공"으로 찍고 있었다.

구조는 이랬다. 공장 현장과 ERP 사이에 연계 서버가 하나 앉아서, 수십 개 사이트의 작업을 ERP로 밀어 넣었다 — 하루에 수천 건 단위. 작업마다 상태 테이블에 행을 쓰고 플래그를 "성공"으로 넘겼는데, 그 플래그가 요청을 보낸 시점에 찍혔다. 커밋된 결과가 돌아온 시점이 아니라. 그래서 반대편 실제 작업이 실패했는데도 행은 "완료"로 읽힐 수 있었다.

로그도 도움이 안 됐다. 어떤 작업은 로그가 한 줄 빠져 있었고, 어떤 작업은 같은 게 두 번 남아 있었다. 테이블과 실제로 일어난 일을 맞춰보려면 둘 다 읽어야 했는데, 둘 중 어느 쪽도 혼자서는 믿을 수 없었다.

결과는 테이블과 현장이 어긋난 상태, 그리고 어느 행이 거짓말하는 행인지 작업 하나하나 따라가 보지 않고는 깔끔하게 가려낼 방법이 없는 상태였다.

성공 플래그는 "요청 보냄"이 아니라 실제로 커밋된 뒤쪽 결과를 보고 찍어야 한다. 로그는 idempotent해야 한다 — 한 작업에 대조 가능한 로그 한 줄, 몇 번을 재시도하든.

두 줄이다. 그땐 둘 다 아니었다. 플래그를 넘기기 전에 커밋된 결과를 확인하는 단계가 없었고, 재시도가 새 줄 대신 같은 줄을 쓰도록 로그에 키를 잡아둔 것도 없었다.