Skip to content
isdnetworks
Go back

지우고 다시 만들다 더 나빠졌다

썸네일 규격이 바뀌어서 기존 것을 다시 만드는 작업을 했다. 300건쯤 돌다가 원본 파일이 없는 상품에서 멈췄고, 그 시점에 썸네일이 아예 없는 상품이 300개 생겼다.

Table of contents

Open Table of contents

지우기가 먼저였다

짜 놓은 순서가 문제였다. unlink 로 옛 썸네일을 먼저 지우고 GD 로 새로 만드는 흐름이라 만들기가 실패하면 아무것도 안 남는다.

foreach ($products as $p) {
    @unlink($thumbDir . $p->thumb_name);        // 1. 지운다
    $ok = makeThumb($origDir . $p->orig_name,   // 2. 만든다
                    $thumbDir . $p->thumb_name);
}

작업 전에는 규격이 옛것일 뿐 썸네일이 있었다. 작업 후에는 없다. 실패한 결과가 시작 상태보다 나쁘다는 것이 이 순서의 문제였다.

만들고 나서 교체했다

순서를 뒤집었다. 임시 이름으로 먼저 만들고 성공했을 때만 교체한다.

$tmp = $thumbDir . $p->thumb_name . '.new';

if (!makeThumb($origDir . $p->orig_name, $tmp)) {
    log_message('error', "썸네일 생성 실패: {$p->product_no}");
    continue;                                // 옛것을 그대로 둔다
}

rename($tmp, $thumbDir . $p->thumb_name);    // 성공했을 때만 교체

실패하면 continue 로 넘어가고 옛 썸네일이 그대로 남는다. 규격은 옛것이지만 없는 것보다 낫다. 같은 파일 시스템 안의 rename 은 원자적이라 교체 중간 상태가 안 생긴다는 점도 이 순서를 쓸 수 있게 해 준다.

지우는 단계를 뒤로 미뤘다

이 원칙을 다른 작업에도 적용하려고 단계를 되돌릴 수 있는지로 나눠 봤다.

단계되돌리기
파일 생성지우면 됨
파일 교체원본이 있으면 가능
파일 삭제불가
데이터 삽입지우면 됨
데이터 갱신이전 값이 있으면 가능
데이터 삭제불가

못 지우는 쪽으로 가는 단계를 가능한 한 뒤로 미는 것이 규칙이 된다. 전부 성공한 뒤에 한꺼번에 지우는 방법도 있다. 처리하면서 지울 목록만 모아 두고 마지막에 한 번에 도는 식이다.

옛 썸네일도 그래서 안 지웠다. unlink 대신 rename 으로 이름 뒤에 표시만 붙여 뒀다.

rename($thumbDir . $name, $thumbDir . $name . '.v1');

새 규격에 문제가 있으면 반대로 하면 되고 확인 기간이 지나면 표시가 붙은 것을 지운다. 디스크가 두 배로 드는데 그만한 값이었다.

사전 준비

멈춘 이유가 원본 없음이었으니 file_exists 로 그것부터 세어 봤다. 142건이었다.

foreach ($products as $p) {
    if (!file_exists($origDir . $p->orig_name)) {
        $missing[] = $p->product_no;
    }
}

작업을 시작하기 전에 전제가 만족되는지 확인하니 실행 중 멈추는 일이 줄었다. 142건은 CSV 로 뽑아 담당자에게 넘기고 나머지만 처리했다.

전제를 확인해도 다른 이유로 멈출 수 있어서 처리한 것을 기록하게 했다. 상품마다 썸네일 버전을 MySQL 에 남기고 다음 실행에서는 버전이 낮은 것만 대상으로 잡으면 처음부터 다시 안 해도 된다.

정리


Share this post on:

Previous Post
DB 앞에 캐시를 두고 나서
Next Post
값은 옮겼는데 코드 체계가 달랐다