롤백과 복구: 멈추기, 되돌리기, 회복 완료는 어떻게 다른가
신규 노출 중단, 검증한 산출물 재승격, 클라이언트의 재채택과 영속 자료 복구를 분리하고 실제 사용자 회복까지 확인한다.
목차
표준·구현·측정·해석 표시는 무엇인가요?
- 표준웹 표준이나 언어 명세가 정한 동작
- 구현특정 기술이나 브라우저가 실제로 구현한 동작
- 측정명시한 환경에서 직접 실행해 관찰한 결과
- 해석앞선 근거에서 도출한 설계 판단
- 미확인아직 공식 근거나 재현 결과를 확인하지 못한 내용
30초 요약
문제가 생겼을 때 먼저 새 사용자에게 더 퍼지는 일을 멈춘다. 이어서 이전에 검증한 산출물이나 현재 자료와 호환되는 수정본 가운데 안전한 대상을 선택한다. 그러나 배포 서버가 대상을 바꿨다고 이미 노출된 브라우저와 앱이 즉시 바뀌지는 않는다. 실제 실행 코드, 영속 자료와 사용자 흐름이 회복됐는지 따로 확인해야 한다.
반복해서 기억할 문장은 이것이다.
멈추기 ≠ 대상 변경 ≠ 회복 완료
신규 노출 중단 → 영향·자료 상태 확인 → 안전한 대상 선택
→ 검증한 산출물 재승격 또는 수정본 배포 → 클라이언트 재채택
→ 코드·자료·사용자 흐름의 실제 회복 확인롤백은 시간을 되감는 버튼이 아니다. 미래의 전달 대상을 바꾸고, 이미 바뀐 여러 상태를 다시 안전한 조합으로 수렴시키는 복구 과정이다.
멈추기, 대상 변경, 회복 완료는 서로 다르다
다음 네 면은 복구 완료를 빠뜨리지 않고 확인하기 위한 이 글의 학습용 분류다. Expo의 공식 명칭이나 모든 시스템이 따라야 하는 표준 계층은 아니다.
배포 제어면: 앞으로 누구에게 무엇을 제공할지 결정
실제 실행면: 각 브라우저·기기가 지금 무엇을 실행하는지
자료 상태면: 로컬·서버 자료가 어떤 형식과 의미를 가지는지
사용자 회복면: 핵심 흐름이 실제로 다시 성공하는지배포 제어면은 배포 도구와 서버의 목표 상태다. 실제 실행면은 사용자의 앱이나 브라우저가 실제로 채택한 상태다. 자료 상태면과 사용자 회복면까지 분리해야 “명령 성공”을 “복구 성공”으로 오해하지 않는다.
중단은 첫 대응으로 중요하다. 피해 범위가 더 커지는 일을 막아 조사할 시간을 번다. 다만 중단만 한 채 이미 노출된 집단을 잊으면 작은 비율의 사용자는 계속 실패한다.
과거 소스가 아니라 검증한 산출물을 선택한다
위험한 추정
과거 커밋으로 소스 전환(checkout) → 오늘의 의존성·도구·환경으로 재빌드
→ "예전 것과 같을 것"
검증 가능한 선택
검증했던 불변 산출물 ID 확인 → 호환성·자료 상태 확인 → 같은 산출물 재승격과거 커밋을 다시 빌드한 결과는 의존성 해석, 빌드 도구, 환경 변수와 생성 시각 때문에 달라질 수 있다. 11편에서 본 콘텐츠 다이제스트와 릴리스 매니페스트로 실제 산출물의 동일성을 확인한다.
“이전”도 충분한 선택 기준이 아니다. 다음을 만족하는 안전한 복구 후보를 고른다.
- 해당 실행환경과 호환되는가?
- 실제로 검증하고 운영한 불변 산출물인가?
- 현재 로컬·서버 자료를 읽고 쓸 수 있는가?
- 필요한 서버 API와 기능 플래그가 아직 호환되는가?
- 서명·자산과 배포 메타데이터를 온전히 제공할 수 있는가?
최신 이전 버전이 반드시 안전한 것은 아니다. 같은 결함이 있거나 현재 서버 계약과 맞지 않을 수 있다.
이전 게시본과 내장본은 복구 대상이 다르다
이전 게시본으로 복구
운영자가 안전성을 검증한 과거 OTA 업데이트를 서버가 다시 제공
내장본으로 복구
각 기기가 설치한 네이티브 빌드 안의 기본 업데이트를 선택내장본은 원격 업데이트가 모두 위험할 때 강한 탈출구가 될 수 있다. 반면 오래된 빌드의 내장본이 현재 서버 API나 자료 형식을 이해하지 못할 수도 있다. 런타임별 설치 빌드 분포와 내장 업데이트 식별자를 복구 전에 확인한다.
제품별 명령 이름과 의미는 바뀔 수 있다. 보편적으로 남는 질문은 “이 지시가 어떤 불변 산출물을, 어떤 실행환경에, 언제 실행하게 하는가?”다.
서버의 새 목표는 기기의 현재 실행 상태가 아니다
12:00 서버 목표를 안전한 업데이트 B로 변경
12:01 새로 시작한 기기 1이 B를 다운로드, 아직 C 실행
12:10 기기 1 재시작, B 실행
다음 날 오프라인이던 기기 2가 확인 후 B 다운로드이 예에서 12:00은 롤백 제어가 성공한 시각이지 모든 사용자의 복구 시각이 아니다. 웹에서도 오래 열린 탭, 브라우저의 백그라운드 갱신 코드인 서비스 워커와 캐시가 이전 JavaScript를 계속 실행할 수 있다.
강제 재시작은 항상 정답이 아니다. 작성 중인 입력이나 진행 중인 결제 같은 사용자 상태를 잃게 할 수 있다. 피해의 심각도, 업데이트 확인·다운로드 시간, 안전한 중단 지점과 사용자 안내를 고려해 즉시 재로드, 다음 시작 적용 또는 기능 차단을 선택한다.
코드 롤백은 자료 롤백이 아니다
코드 C 실행: { name: "민수" } → { profile: { name: "민수" } }
코드 B 복귀: 예전의 data.name만 읽음 → 값 없음 또는 충돌코드를 B로 바꿔도 저장소는 자동으로 예전 모양이 되지 않는다. 서버 데이터베이스 쓰기, 업로드한 파일, 전송한 메시지와 외부 결제도 마찬가지다. 이미 일어난 현실의 부수 효과를 코드 배포 명령이 취소하지 않는다.
롤백 가능한 자료 전환은 다음처럼 설계할 수 있다.
- 전환 기간에 새 코드가 이전·새 형식을 모두 읽는다.
- 이전 코드도 읽어야 한다면 새 필드를 추가하고 기존 필드를 즉시 삭제하지 않는다.
- 되돌릴 수 없는 변환은 별도 복구본·보상 작업과 검증 절차를 둔다.
- 문제가 있는 버전을 실행한 상태를 fixture로 저장해 롤백 후보를 시험한다.
fixture는 특정 상태를 반복 재현하도록 고정한 입력 묶음이다. 깨끗한 새 설치만 시험하면 실제 사용자에게 누적된 자료와의 충돌을 놓친다.
안전한 과거가 없다면 수정본을 앞으로 보낸다
선택 질문은 단순하다.
검증한 과거 산출물 + 현재 자료 + 현재 서버가 안전한가?
예 → 재승격을 우선 검토
아니오 → 현재 상태와 호환되는 수정본을 검증해 앞으로 배포실전에서는 둘을 함께 쓸 수도 있다. 아직 후보를 받지 않은 사용자의 신규 노출은 멈추고, 안전하게 돌아갈 수 있는 집단은 이전 산출물로 복구하며, 이미 비가역 자료 변환을 겪은 집단에는 호환 수정본을 전달할 수 있다. 이때 집단과 대상 산출물을 명시하지 않으면 운영자가 서로 다른 사용자를 같은 “롤백 완료” 숫자로 합칠 위험이 있다.
수정 전진은 실패한 변경 위에 임시 예외를 계속 쌓는다는 뜻이 아니다. 현재 상태를 정확히 읽고 피해를 막는 가장 작은 수정본을 검증한 뒤, 후속 정리와 영속 자료 복구를 별도 추적한다.
실제 회복은 네 면에서 확인한다
| 확인 면 | 질문 | 대표 증거 |
|---|---|---|
| 배포 제어면 | 신규 노출이 멈추고 안전한 대상이 선택됐는가? | rollout 상태, 대상 산출물 ID, 변경 감사 기록 |
| 실제 실행면 | 영향받은 기기가 실제로 안전한 코드를 실행하는가? | 실행 update ID·빌드·런타임별 채택, 실패 설치 수 |
| 자료 상태면 | 현재 코드와 로컬·서버 자료가 호환되는가? | 마이그레이션 결과, 손상·불일치 검사, 보상 작업 상태 |
| 사용자 회복면 | 원래 문제와 핵심 흐름이 회복됐는가? | 충돌 없는 세션, 핵심 요청·완료율, 지원 문의와 재현 결과 |
전체 오류율만 보면 영향을 받은 작은 집단의 실패가 희석될 수 있다. 17편처럼 문제 업데이트 ID, 복구 대상 ID, 네이티브 빌드·런타임과 제한된 집단별로 신호를 나눈다. 개인 식별자를 무제한 메트릭 레이블로 넣지는 않는다.
회복 조건도 사고 전에 적는다.
중단 완료: 새 대상 노출 증가가 멈춤
대상 변경 완료: 검증한 산출물이 올바른 경로·런타임에 지정됨
채택 완료: 영향 집단의 안전한 update ID 실행 비율이 목표 충족
자료 복구 완료: 불일치·손상 검사와 필요한 보상 작업 통과
사용자 회복 완료: 원래 실패 신호와 핵심 흐름이 합의한 기준으로 회복Web, React, React Native의 연결점
Web 배포에서는 라우터나 별칭이 이전의 불변 산출물을 가리키게 바꿀 수 있다. 그래도 이미 열린 탭은 기존 JavaScript와 React 트리를 계속 실행할 수 있다. 산출물 전환과 탭의 새로고침·캐시 갱신을 구분하고, 오래된 HTML이 이미 삭제한 분할 파일인 청크를 요청하지 않도록 이전 산출물을 보존하는 기간도 둔다.
React 상태를 이전 값으로 되돌리는 UI 동작은 배포 롤백이 아니다. 기능 플래그를 끄면 같은 산출물 안의 경로를 차단할 수 있어 빠른 완화 수단이 되지만, 문제가 번들 시작이나 공통 런타임에 있으면 플래그만으로 복구할 수 없다.
React Native OTA에서는 서버 대상, 설치된 네이티브 빌드, 다운로드한 업데이트와 현재 실행
업데이트가 각각 다를 수 있다. updateId, runtime version, 내장 업데이트로 시작했는지와 사용자
흐름을 함께 남겨 어떤 집단이 어느 복구 경로에 있는지 확인한다.
자주 실패하는 대응
중단 버튼이 성공하면 사고를 종료한다
추가 노출만 막혔을 수 있다. 이미 실행 중인 집단의 재채택과 사용자 회복을 계속 추적한다.
과거 커밋을 급히 다시 빌드한다
검증했던 바이트와 달라질 수 있다. 보관한 산출물 ID·다이제스트를 확인해 같은 것을 재승격한다.
가장 최근 이전 버전을 무조건 고른다
같은 결함, 현재 서버 계약이나 자료 형식과의 불일치가 있을 수 있다. “최근”보다 호환성과 검증 증거로 선택한다.
코드와 자료가 함께 과거로 돌아간다고 가정한다
로컬 저장소, 서버 쓰기와 외부 부수 효과는 남는다. 코드 선택과 자료 복구 계획을 분리한다.
전체 오류율만 보고 회복을 선언한다
작은 영향 집단의 실패가 평균에 가려질 수 있다. 문제·복구 update ID와 런타임별로 신호를 나눈다.
모든 상황에서 즉시 강제 재시작한다
작업 중 자료를 잃거나 네트워크가 느린 사용자를 시작 화면에 가둘 수 있다. 피해 심각도와 안전한 적용 지점을 기준으로 선택한다.
롤백과 복구를 판단하는 순서
- 문제 후보의 확대를 멈추고 대상 산출물·집단·시각을 기록한다.
- 실제 실행 update ID와 사용자 피해로 영향 집단을 확인한다.
- 과거 산출물, 내장본과 수정본 후보의 코드·런타임·서버·자료 호환성을 비교한다.
- 재빌드하지 않은 검증 산출물 재승격 또는 충분히 검증한 수정 전진을 선택한다.
- 클라이언트가 확인·다운로드·활성화할 경로와 사용자 안내를 정한다.
- 실행 ID별 채택, 자료 일관성과 핵심 사용자 흐름을 함께 관찰한다.
- 네 면의 종료 기준을 충족한 뒤 복구 완료를 선언하고 재발 방지 항목을 남긴다.
19편에서는 사고 뒤 한 번에 크게 올리는 대신 호환성 표, 변경 기록, fixture와 회귀 검증으로 프레임워크·의존성 업그레이드 위험을 줄이는 방법을 다룬다.
한 문장으로 다시 설명하기
롤백은 시간을 되감는 버튼이 아니라 신규 노출을 멈추고 안전한 산출물을 다시 지정한 뒤 이미 영향을 받은 클라이언트가 그 대상을 채택하고 현재 자료로 핵심 흐름을 회복했는지 확인하는 과정이다. 안전한 과거 코드와 현재 자료의 조합이 없다면 검증한 수정본을 앞으로 배포한다.
스스로 확인하기
- 배포 확대 중단, 복구 대상 변경과 사용자 회복 완료는 왜 서로 다른가?
- 과거 커밋 재빌드보다 보관한 불변 산출물 재승격이 검증 결과를 더 잘 유지하는 이유는 무엇인가?
- 이전 게시본 롤백과 내장 업데이트 롤백은 실제 대상을 어떻게 다르게 고르는가?
- 서버가 안전한 대상으로 바뀐 뒤에도 이미 노출된 기기의 회복이 늦을 수 있는 이유는 무엇인가?
- 코드 롤백이 AsyncStorage, 파일과 서버 자료를 자동으로 되돌리지 않는 이유는 무엇인가?
- 어떤 조건에서 과거 산출물 재승격보다 수정 전진이 더 안전한가?
- 복구 완료를 배포 제어면·실제 실행면·자료 상태면·사용자 회복면에서 각각 어떻게 증명할 것인가?
- Web의 열린 탭, React 기능 플래그와 React Native OTA는 롤백에서 어떤 서로 다른 역할을 하는가?
Active recall
기억에서 꺼내 보기
답을 쓰지 않아도 됩니다. 먼저 머릿속으로 답한 뒤 펼쳐서 정답·이유·흔한 오해를 비교하세요.
01문제가 감지돼 점진 배포를 중단했다면 이미 새 코드를 실행한 사용자도 복구됐다고 볼 수 있을까?
정답
아니다. 중단은 추가 노출을 제한하지만 이미 실행한 클라이언트는 안전한 대상을 다시 확인·다운로드·활성화해야 한다.
관련 설명 다시 읽기왜 그런가
서버의 배포 결정과 각 기기의 현재 실행 상태는 별도 시계로 움직인다.
선택한 상태와 다음 복습일은 이 브라우저에만 저장됩니다.
02과거 커밋을 다시 빌드해 나온 파일을 이전에 검증한 산출물과 같은 롤백 대상으로 볼 수 있을까?
정답
동일하다고 증명하기 전에는 안 된다. 입력·환경·의존성이 달라질 수 있으므로 보관한 불변 산출물을 식별해 재승격하는 편이 검증 결과를 유지한다.
관련 설명 다시 읽기왜 그런가
소스가 같다는 사실과 배포 바이트가 같다는 사실은 다르다.
선택한 상태와 다음 복습일은 이 브라우저에만 저장됩니다.
03내장 업데이트로 롤백하면 모든 사용자가 정확히 같은 JavaScript를 실행한다고 볼 수 있을까?
정답
아니다. 내장 업데이트는 각 기기에 설치된 네이티브 빌드 안의 묶음이므로 설치 빌드가 다르면 내장 코드도 다를 수 있다.
관련 설명 다시 읽기왜 그런가
롤백 지시는 하나여도 실제 대상은 설치된 빌드와 런타임에 따라 달라질 수 있다.
선택한 상태와 다음 복습일은 이 브라우저에만 저장됩니다.
04이전 JavaScript를 다시 실행하면 새 코드가 바꾼 AsyncStorage와 파일도 자동으로 과거 형식으로 돌아갈까?
정답
아니다. 코드 선택과 영속 자료 전환은 별도 작업이며 과거 코드가 현재 자료를 읽지 못하면 롤백이 더 위험할 수 있다.
관련 설명 다시 읽기왜 그런가
실행 코드, 기기 자료와 서버 자료는 서로 다른 상태를 가진다.
선택한 상태와 다음 복습일은 이 브라우저에만 저장됩니다.
05영속 자료가 바뀌었다면 언제나 이전 코드로 롤백해야 할까?
정답
아니다. 안전한 이전 코드와 자료 조합이 없다면 현재 자료와 호환되는 새 수정본을 검증해 앞으로 배포해야 한다.
관련 설명 다시 읽기왜 그런가
롤백과 수정 전진은 이름이 아니라 실제로 만들 코드·자료 조합의 안전성으로 선택한다.
선택한 상태와 다음 복습일은 이 브라우저에만 저장됩니다.
출처와 검증 범위
아래 날짜는 링크를 마지막으로 열어 본 날입니다. 문서 상단의 검증일은 글의 설명과 적용 범위를 다시 확인한 날입니다.
- RollbacksExpo · 공식 문서 · 확인 2026-08-04
- RolloutsExpo · 공식 문서 · 확인 2026-08-04
- Error recoveryExpo · 공식 문서 · 확인 2026-08-04
- Deploy updatesExpo · 공식 문서 · 확인 2026-08-04
- Downloading updatesExpo · 공식 문서 · 확인 2026-08-04