대량 재전송 작업을 하기 전에 한 건으로 카나리를 돌리기로 했다. 대상 하나를 고르고 그 채널의 status 를 확인한 뒤 조작 직전에 하나를 더 봤다.
Table of contents
Open Table of contents
제약 — 채널별 행이 붙는 구조
이 시스템은 한 상품에 채널별 행이 붙는다.
상품 X
├─ 채널 A 행
├─ 채널 B 행
└─ 채널 C 행
그런데 화면의 전송하기 버튼은 distribution_products 가 아니라 상품 단위로 동작한다.
의도한 채널만 나가는 것이 아닐 수 있다는 뜻이다. 한 채널만 보고 안전하다고 판단하면 다른 채널에서 일어나는 변화를 못 본다.
검증 — 전 채널을 셌다
스냅샷 쿼리에 서브쿼리를 하나 넣었다.
SELECT
dp.id, dp.channel, dp.status, ...,
(SELECT COUNT(*) FROM distribution_products d2
WHERE d2.product_id = dp.product_id
AND d2.deleted_at IS NULL) AS live_dps_all_channels
FROM distribution_products dp
WHERE dp.id = ?;
live_dps_all_channels 로 그 상품의 전 채널 활성 행 수를 같이 뽑는다.
결과는 이랬다.
live_dps_all_channels 1
deleted_at 이 비어 있는 행이 하나뿐이라 다른 채널로 파급될 행 자체가 없었다.
판단 기준 — 1이면 안전하다
live_dps_all_channels 가 1이면 파급이 구조적으로 불가능하다.
2 이상이면 둘 중 하나를 고른다.
[선택 1] 그 상품을 카나리 대상에서 뺀다
[선택 2] 다른 채널 영향까지 사전 합의하고 진행
선택 1 이 낫다고 봤다. 어느 쪽을 택하든 그 사실을 모르는 채로 진행하는 것보다는 낫지만 대상을 바꾸는 편이 간단하다.
주의 — 검증 결과의 오염
live_dps_all_channels 가 2 이상인 상품은 결과 해석을 어렵게 만든다.
카나리 결과가 이상함
↓
내 조작 때문인가, 다른 채널로 나간 것 때문인가
↓
구분이 안 된다
카나리의 목적은 그 UPDATE 하나의 효과를 보는 것인데 다른 변수가 섞이면 그것을 못 본다.
카나리 대상은 변수가 적어야 한다. 다채널 상품은 변수가 여럿이고 단일 채널 상품은 하나라서 대상 선정 자체가 실험 설계였다.
조치 — 스냅샷 쿼리에 상시 포함
이 COUNT(*) 확인을 일회성으로 두지 않았다.
live_dps_all_channels 를 스냅샷 쿼리에 상시 포함해서 카나리를 돌릴 때마다 자동으로 확인되게 했다.
사람의 기억에 의존하는 확인 항목은 급할 때 가장 먼저 빠진다. 절차에 넣어 두면 다음에 누가 하더라도 그 값이 함께 나온다.
사전 준비 — 스냅샷이 되돌림 근거
조작 전 값을 남기는 것까지가 절차다.
조작 후 이상함
↓
원래 값이 뭐였지?
↓
스냅샷에 있다
SELECT 로 떠 둔 스냅샷이 없으면 되돌릴 근거가 없다.
무엇을 담을지도 정리해 뒀다.
연동 행: ID, 채널 상품번호, 상태, 승인 유형, 생성 시각
상품: ID, 부모 참조, 상태, 승인 상태, 버전
작업: 미완료 작업 수
파급: 전 채널 활성 행 수
SELECT 하나로 네 가지를 다 뽑는다.
여러 번 나눠 뽑으면 그 사이에 값이 바뀔 수 있고 빠뜨리기도 한다. 조작보다 그 앞에 남기는 기록이 더 중요한 경우가 자주 있었다.
정리
- 한 상품에 채널별 행이 붙으면 조작이 다른 채널로 파급된다
- 한 채널만 보고 판단하면 나머지를 못 본다
- 카나리 전에 전 채널 활성 행 수를 센다
- 그 값이 1이면 파급이 구조적으로 불가능하다
- 1이 아니면 대상에서 빼거나 영향까지 합의한다
- 다채널 대상은 검증 결과를 오염시킨다
- 카나리 대상 선정이 곧 실험 설계다
- 확인을 스냅샷 쿼리에 상시 포함해 잊지 않게 한다
- 조작 전 값을 남기는 것까지가 절차다
- 스냅샷은 한 쿼리로 다 뽑는다