Skip to content
isdnetworks
Go back

포기한 것과 지운 것을 같이 다뤘다

실패한 작업이 계속 재시도되면서 큐를 먹고 있었다. 정리하려고 상태를 하나 만들었다.

ready → working → done
                → failed
                → deleted   (새로 만든 것)

deleted 로 바꾸면 더 이상 안 집는다. 그런데 이름 때문에 문제가 생겼다.

Table of contents

Open Table of contents

이름이 뜻을 흐렸다

한 달쯤 뒤에 다른 사람이 정리 배치를 만들었다.

DELETE FROM reward_job WHERE status = 'deleted' AND reg_date < DATE_SUB(NOW(), INTERVAL 7 DAY);

deleted 상태니까 지워도 되겠다고 판단한 것이다.

그런데 그 상태는 지워도 되는 것이 아니라 더 이상 처리하지 않기로 한 것이었다. 왜 포기했는지가 그 행에 남아 있었는데 DELETE 하고 나니 그 정보가 없어졌다.

두 가지가 달랐다

정리해 보니 이런 차이였다. 처리 포기는 이 작업을 더 진행하지 않는다는 것이고 왜 포기했는지는 남으며 통계에도 잡힌다. 기록 삭제는 이 행 자체를 없애는 것이라 아무것도 안 남는다.

앞은 상태고 뒤는 행위다. 앞의 것은 처리를 멈추는 결정이고 뒤의 것은 자료를 버리는 결정이라 두 결정이 같은 이름을 쓰면 그 차이가 사라진다.

이름을 바꿨다

ready → working → done
                → failed     (실패, 재시도 대상)
                → abandoned  (포기, 재시도 안 함)

abandoned 로 바꾸니 지워도 되는 것으로 읽히지 않는다. 포기한 이유도 컬럼에 남겼다.

ALTER TABLE reward_job
  ADD COLUMN abandon_reason VARCHAR(100) NULL,
  ADD COLUMN abandon_date   DATETIME NULL;
abandoned  대상 계정 없음        2016-03-04
abandoned  아이템 삭제됨          2016-03-04
abandoned  재시도 5회 초과        2016-03-05

GROUP BY abandon_reason 으로 이유별로 세어 보면 무엇을 손봐야 하는지 나온다. status 만 남기면 그 작업이 왜 안 됐는지를 다시 조사해야 한다.

실제로 지우는 것의 처리

행을 영원히 두면 표가 커지므로 지우는 것도 필요하다. 다만 지우기 전에 남길 것을 남겼다.

INSERT INTO reward_job_archive
SELECT * FROM reward_job
WHERE status IN ('done', 'abandoned') AND reg_date < DATE_SUB(NOW(), INTERVAL 90 DAY);

DELETE FROM reward_job
WHERE status IN ('done', 'abandoned') AND reg_date < DATE_SUB(NOW(), INTERVAL 90 DAY);

90일이 지난 것은 reward_job_archive 로 옮기고 본 표에서 지운다. 보관 표는 CREATE TABLE ... LIKE 로 뜨고 조회가 드무니 인덱스를 최소로 뒀다.

본 표는 작게 유지되고 이력은 남는다. 자주 조회하는 표에서 안 쓰는 행을 덜어 내는 것이 목적이었다.

검증 — 상태 문서와 개수 세기

상태가 다섯 개가 됐으니 각각이 무슨 뜻인지 적었다.

ready      대기. 처리기가 집을 대상
working    처리 중. 집은 처리기 정보가 worker_id 에 있음
done       완료
failed     실패. 재시도 대상 (try_count < 5)
abandoned  포기. 재시도 안 함. 이유는 abandon_reason 에 있음

각 상태에서 어느 상태로 갈 수 있는지도 적었다.

ready → working → done
                → failed → ready (재시도)
                         → abandoned (5회 초과)
                → abandoned (복구 불가)

이 그림이 있으면 새 상태를 넣을 때 어디에 넣을지가 정해진다.

문서를 만들고 나서 실제 자료가 그대로인지 봤다.

SELECT status, COUNT(*) FROM reward_job GROUP BY status;
ready       12
working    847   ← 이상하다
done      4128
failed      23
abandoned   91

working 이 847개다. 처리 중인 것이 그렇게 많을 리 없다.

집어 놓고 죽은 것들이 회수 안 된 채 쌓여 있었고 회수 배치가 멈춰 있었다. 상태별 개수를 세어 보니 멈춘 것이 드러난 것이고 문서를 만드는 과정에서 나왔다. 정의에 없는 값이 들어 있는 행도 이 집계에 한 줄로 나타난다.

정리


Share this post on:

Previous Post
로그에 변동량과 총액이 같이 있었다
Next Post
배열을 문자열에 넣어 뒀다