Skip to content
isdnetworks
Go back

운영에 손대기 전에 확인하는 것

운영 환경에서 무언가를 바꿔야 할 때가 있고 그런 경우는 대개 급하다.

급할수록 순서를 지키기가 어려운데 빨리 고쳐야 한다는 압박이 확인하는 단계를 먼저 밀어내기 때문이다.

그런데 급할 때 낸 사고가 원래 문제보다 큰 경우를 몇 번 봤다. 그래서 매번 생각하지 않아도 되게 목록으로 만들어 뒀다.

Table of contents

Open Table of contents

사전 준비 — 원래 상태로 돌아갈 수 있는가

목록의 첫 항목은 이 작업을 취소할 수 있느냐다. 취소가 되는 작업이면 조금 과감하게 해도 되고 틀렸을 때는 원래 상태로 돌리면 된다.

취소가 안 되는 작업이면 그 전에 전부 확인해야 한다. 그리고 대개는 취소가 가능하게 만드는 것이 조치보다 먼저다.

지우기 전에 → 백업을 뜬다
덮기 전에   → 원본을 복사한다
바꾸기 전에 → 현재 값을 기록한다

세 줄이 전부 같은 말이다. 대상을 건드리기 전에 지금 상태를 어딘가에 남기는 것이다.

표 하나가 작으면 mysqldump 로 통째로 뜨는 편이 빠르고 크면 바꿀 행만 골라 남긴다.

지금 값이 무엇인지 남긴다

바꾸기 전에 현재 상태를 파일로 남긴다.

SELECT * FROM t WHERE id IN (...) \G

\G 로 세로로 뽑으면 열이 많아도 읽을 수 있다. 이 결과를 화면에서 보고 넘어가지 않고 파일로 저장한다.

나중에 원래 값이 무엇이었느냐는 물음이 반드시 오는데 그때 화면은 이미 지나갔고 터미널 기록도 세션이 끊기면 없다.

검증 — 조건이 몇 건을 잡는가

WHERE 가 몇 건을 잡는지를 바꾸기 전에 센다.

SELECT COUNT(*) FROM t WHERE 조건;

UPDATE 와 똑같은 조건으로 SELECT COUNT(*) 를 돌려 보는 것이다. 예상한 수와 다르면 거기서 멈춘다.

열 건일 줄 알았는데 만 건이 나오면 조건이 틀린 것이다. 자료가 예상과 다르거나 조인이 어긋났거나 둘 중 하나다.

이 확인을 안 하고 UPDATE 를 돌리면 결과 줄을 보고서야 몇 건이 바뀌었는지 알게 되는데 그때는 이미 바뀐 뒤다.

복구 문장을 먼저 쓴다

바꾸는 문장을 쓸 때 원래대로 만드는 문장도 같이 쓴다.

-- 적용
UPDATE t SET status = 'B' WHERE id IN (1,2,3);

-- 복구
UPDATE t SET status = 'A' WHERE id IN (1,2,3);

두 문장을 나란히 적어 두면 급할 때 다시 생각하지 않아도 된다. 나중에 쓰면 된다고 미루면 정작 필요한 순간에 못 쓴다.

복구 문장이 안 써지는 작업이면 그 작업은 하지 않는다. 못 쓴다는 것은 원래 상태로 갈 방법이 없다는 뜻이다.

조치 — 트랜잭션으로 감싸기

지원되는 자리면 트랜잭션 안에서 하고 확인한 뒤에 확정한다.

BEGIN;
UPDATE t SET ... WHERE ...;
-- 영향 행 수 확인
SELECT * FROM t WHERE ...;   -- 결과 확인
COMMIT;   -- 또는 ROLLBACK

BEGINCOMMIT 사이에서 바뀐 행을 SELECT 로 직접 본다. 의도와 다르면 ROLLBACK 으로 그 자리에서 끝난다.

감싸지 않으면 문장 하나하나가 그 자리에서 그대로 확정된다. MySQL 문서도 새 연결마다 자동 확정이 켜진 채로 세션이 시작되고 오류가 없으면 문장마다 확정한다고 적고 있다.

다만 트랜잭션을 오래 열어 두면 그동안 잠금이 걸리므로 확인은 하되 빨리 끝내야 했다.

시간대를 고른다

급하지 않으면 요청이 적은 시간을 잡는데 같은 작업이라도 부하가 높을 때 하면 잠금이 다른 요청까지 물고 늘어지기 때문이다.

급해도 지금 무엇이 돌고 있는지는 본다.

SHOW PROCESSLIST;

SHOW PROCESSLIST 에 같은 표를 만지는 배치가 떠 있으면 그것이 끝나기를 기다린다. 배치가 도는 중에 같은 자리를 건드리면 서로 부딪힌다.

변경 내용 — 무엇을 왜 했는지 남기기

작업이 끝나면 한 덩어리로 적어 뒀다.

2016-11-03 14:20  jhcheong
대상: t 테이블 3건 (id 1,2,3)
변경: status A → B
사유: 잘못된 상태로 등록됨 (문의 #1234)
백업: /tmp/backup_20161103.sql
복구: UPDATE t SET status='A' WHERE id IN (1,2,3);

대상과 변경과 사유와 백업 자리와 복구 문장이 한 자리에 있다. 며칠 뒤에 이 변경이 원인일 수 있는 문제가 나면 여기가 출발점이 된다.

기록이 없으면 그때 기억에 의존하게 되는데 무엇을 몇 건 바꿨는지를 정확히 기억하는 경우는 드물었다.

혼자 하지 않는다

큰 변경은 다른 사람이 문장을 보게 하고 맞는지를 묻는 절차를 뒀다.

이렇게 해서 조건이 틀린 것을 몇 번 잡았는데 보는 사람은 내가 놓친 자리를 본다.

내가 그 조건을 만들었으니 나는 그것이 맞다고 생각하면서 읽는다. 처음 보는 사람은 조건과 의도를 따로 놓고 읽으므로 어긋난 자리가 보인다.

정리


Share this post on:

Previous Post
둘 중 무엇을 지울지 몰랐다
Next Post
옮기고 나서 가리키는 것을 안 고쳤다