Skip to content
isdnetworks
Go back

내가 안 건드렸는데 값이 바뀌어 있었다

회원 등급을 손으로 바꿔 넣고 화면에서 확인했더니 잘 들어가 있었다. 그런데 십 분쯤 뒤에 다시 보니 원래 값으로 돌아가 있었다.

Table of contents

Open Table of contents

증상 — 십 분 뒤에 되돌아간 값

넣은 것은 이 한 줄이었다.

UPDATE member SET grade = 'VIP' WHERE no = 1042;

화면에서 확인했을 때는 VIP 였다. 십 분 뒤에 다시 보니 NORMAL 이었다. 나도 다른 사람도 그 사이에 건드린 적이 없었다.

도는 것을 먼저 찾았다

값이 저절로 바뀌면 자동으로 도는 것이 있는지부터 봐야 했다.

$ crontab -l
*/10 * * * * /usr/bin/php /app/batch/grade_update.php

grade_update.php 가 십 분마다 구매 금액으로 등급을 다시 계산해 UPDATE 하고 있었다. 내가 손으로 넣은 값을 그 배치가 덮은 것이다.

이런 것이 또 있을 것 같아 전부 봤다. crontab -l 은 지금 계정 것만 보여 준다.

$ crontab -l
$ ls /etc/cron.d/
$ sudo -u www crontab -l

계정마다 따로 있어서 셋을 다 봤더니 열한 개가 나왔다. 이름만으로는 어느 것이 끼어드는지 알 수 없어서 주기와 대상을 옆에 적었다.

grade_update.php     10분   회원 등급 재계산
stat_daily.php       매일   통계 집계
clean_temp.php       매일   임시 파일 정리
sync_product.php     1시간  상품 동기화
...

어느 MySQL 테이블을 건드리는지 적어 두니 시험할 때 어느 것을 신경 써야 하는지 바로 보였다. 만드는 데 삼십 분이 걸렸고 그 뒤로 계속 썼다.

시험 방법을 바꿨다

배치가 도는 동안은 손으로 넣은 값이 남지 않는다. 시험 방법 자체를 바꿔야 했다.

세 번째로 했다.

INSERT INTO order (member_no, amount, state) VALUES (1042, 500000, 'DONE');

grade_update.php 가 돌면 등급이 오른다. 그게 실제 동작이다. 손으로 값만 바꾸는 것은 그 경로를 건너뛰는 것이었다.

시험 서버에서는 아예 cron 에서 빼고 필요할 때만 손으로 돌리게 했다. 언제 도는지 내가 정하니 결과가 흔들리지 않았다.

덮어써도 되는지 물어봤다

시험하다 보니 손으로 조정한 등급이 계속 덮이고 있다는 것을 알게 됐다. 특별 관리 회원처럼 손으로 넣는 경우가 실제로 있었다. 물어보니 손으로 넣은 것은 유지되어야 한다는 답이 왔다.

ALTER TABLE member ADD COLUMN grade_manual char(1) DEFAULT 'N';
$sql = "UPDATE member SET grade = ? WHERE no = ? AND grade_manual = 'N'";

grade_manualY 인 줄은 배치가 건너뛴다. 시험하다 걸린 것이 실제 문제였던 셈이다.

무엇이 언제 무엇을 바꿨는지도 남기게 했다.

if ($old !== $new) {
    $log->insert([
        'member_no' => $no, 'before' => $old, 'after' => $new,
        'by' => 'grade_update.php', 'at' => date('Y-m-d H:i:s'),
    ]);
}

beforeafterby 가 남으니 값이 이상할 때 누가 바꿨는지 바로 갈린다. 넣기 전 기록은 알 수 없어서 그동안 얼마나 덮였는지는 끝내 몰랐다.

정리


Share this post on:

Previous Post
0건이 통과인지 미측정인지 몰랐다
Next Post
API가 없어서 화면을 읽었다