사전 스냅샷
개념

스냅샷

gabury1고친 사람 github-actions[bot]

스냅샷은 어느 한 시점의 상태를 붙잡아 두는 일입니다. 한 번 붙잡아 두면 원본이 뒤에 어떻게 바뀌어도 붙잡아 둔 상태는 바뀌지 않습니다. 저장 장치부터 버전 관리 도구까지 여러 분야가 저마다 이 이름을 씁니다. 붙잡아 둔 상태를 나중에 읽거나 그 상태로 되돌릴 때 씁니다.

쉽고 빠른 이해

스냅샷은 어느 시점의 상태를 굳혀 두는 일입니다. 데이터베이스를 손보기 전에 지금 상태를 하나 만들어 두는 것이 그 예입니다.

이게 없으면 계속 바뀌는 데이터를 다룰 방법이 없어집니다. 처음부터 끝까지 복사하는 동안에도 원본은 계속 바뀌기 때문입니다. 그러면 앞부분과 뒷부분이 서로 다른 때의 값이 된 사본이 남습니다.

이렇게 돕니다:

  1. 지금 시점에 이름을 붙여 둡니다
  2. 데이터는 그때 복사하지 않고 원본과 나눠 씁니다
  3. 원본이 바뀌는 대목마다 옛 값을 따로 남깁니다

대가는 공간과 속도, 그리고 원본과 운명을 같이한다는 점입니다. 원본이 바뀔수록 따로 남길 옛 값이 늘어납니다. 스냅샷을 여럿 쌓아 두면 원본에 쓸 때마다 할 일이 늘어 쓰기가 느려집니다.

스냅샷은 원본과 같은 장치 안에 있습니다. 그 장치가 망가지면 스냅샷도 같이 사라집니다.

상세

단체 사진을 한 장 찍었다고 해 봅시다. 사진을 찍고 나면 사람들이 흩어지든 자리를 바꾸든 사진 속 모습은 변하지 않습니다. 스냅샷이라는 이름은 사진에서 왔습니다. 하는 일도 같습니다.

스냅샷은 어느 한 시점의 상태 전체를 가리키는 이름을 남겨, 그 뒤의 변경과 무관하게 그 상태를 읽을 수 있게 하는 것입니다. 스냅샷을 만드는 것을 흔히 「뜬다」고 합니다.

대표적인 쓰임은 이렇습니다. 데이터베이스 파일을 옮기기 전에 지금 상태를 하나 떠 둡니다. 옮기다 잘못되면 그 상태로 돌아갑니다.

이 절은 스냅샷이 붙잡는 것이 무엇인지부터 정합니다. 그다음 복사 없이 붙잡는 방법, 뜨는 순간을 고르는 문제, 분야마다 달라지는 쓰임을 봅니다. 끝은 대가, 그리고 언제 쓰고 언제 안 쓰는지입니다.

스냅샷이 붙잡는 것

붙잡는 대상은 범위를 정한 상태 전체입니다. 디스크 볼륨 하나 · 데이터베이스 하나 · 폴더 전체가 단위입니다. 그 안의 파일 하나, 표 하나가 아닙니다. 범위 안의 것들이 서로 맞물려 있어서 따로 떼면 뜻이 깨지기 때문입니다.

주문 표와 재고 표를 예로 들어 봅시다. 주문 표만 어제 상태로 되돌리면 재고와 아귀가 안 맞습니다. 둘을 한 시점으로 같이 붙잡아야 되돌린 상태가 쓸모 있습니다.

붙잡은 상태는 읽기만 됩니다. 스냅샷을 고칠 수 있으면 「그 시점의 상태」라는 말이 성립하지 않습니다. 고치고 싶으면 스냅샷에서 새 사본을 만들어 그 사본을 고칩니다.

전부 복사하지 않는 이유

한 시점을 붙잡는 가장 단순한 방법은 그 순간 데이터를 전부 복사하는 것입니다. 이 방법은 두 가지 이유로 잘 안 씁니다. 시간이 데이터 크기에 비례해 걸립니다. 공간도 원본만큼 듭니다.

그래서 실제 스냅샷은 복사를 미룹니다. 뜨는 순간에는 지금 데이터를 가리키는 목록 하나만 따로 남깁니다. 원본과 스냅샷이 같은 데이터를 나눠 쓰는 상태로 시작하는 것입니다. 그러다 원본의 어느 조각이 바뀔 때, 그 조각만 옛 값을 따로 떠서 스냅샷 쪽에 붙입니다. 이 방식을 쓰기 시 복사(copy-on-write)라고 합니다.

저장 장치는 데이터를 일정한 크기의 조각으로 나눠 담습니다. 그 조각 하나를 블록이라고 부릅니다. 그림은 블록 셋을 가진 저장소에서 두 번째 블록만 바뀐 뒤의 모습입니다.

flowchart TD
    A["지금의 원본"] --> B1["블록 1"]
    A --> B2N["블록 2 · 새 값"]
    A --> B3["블록 3"]
    S["스냅샷"] --> B1
    S --> B2O["블록 2 · 옛 값"]
    S --> B3

블록 1과 블록 3은 화살표가 둘 다 같은 곳으로 갑니다. 안 바뀌었으니 사본이 필요 없습니다. 블록 2만 둘로 갈렸습니다. 그래서 스냅샷이 실제로 차지하는 공간은 뜬 뒤에 바뀐 만큼입니다.

뜨는 순간을 고르는 일

스냅샷을 뜨는 동안에도 쓰기는 들어옵니다. 어느 쓰기까지가 스냅샷에 들어가고 어느 쓰기부터 빠지는지를 딱 자르지 못하면, 붙잡은 상태가 어느 시점도 아닌 잡탕이 됩니다. 이렇게 한 시점으로 아귀가 맞는 상태를 일관성 있는 상태라고 합니다.

자르는 방법은 쓰기를 아주 잠깐 멈추는 것입니다. 멈춘 사이에 시점 표시만 남기고 곧바로 쓰기를 다시 받습니다. 복사는 앞 소절에서 본 대로 나중으로 미루므로 멈추는 시간이 짧습니다.

저장 장치가 시점을 잘라도 그것만으로 부족할 때가 있습니다. 응용 프로그램이 메모리에만 들고 있던 값은 아직 장치에 안 내려갔기 때문입니다. 그래서 뜨기 직전에 응용 쪽에 「지금까지 쓴 것을 내려보내라」고 알리는 절차를 같이 두는 것이 보통입니다.

그림은 응용 프로그램이 값을 내려보내는 때부터 쓰기를 다시 받기까지를 순서대로 놓은 것입니다.

sequenceDiagram
    participant 앱 as 응용 프로그램
    participant 저장소
    앱->>저장소: 메모리에 들고 있던 값을 내려보낸다
    저장소->>저장소: 쓰기를 잠깐 멈춘다
    저장소->>저장소: 이 시점에 스냅샷 표시를 남긴다
    저장소->>앱: 쓰기를 다시 받는다
    앱->>저장소: 새 쓰기
    저장소->>저장소: 바뀐 조각의 옛 값을 그때 남긴다

멈춰 있는 구간은 가운데 두 줄뿐입니다. 옛 값을 남기는 일은 쓰기를 다시 받은 뒤에 일어나므로 멈춘 시간에 안 들어갑니다.

같은 이름을 쓰는 곳들

붙잡는다는 뜻은 어디서나 같습니다. 무엇을 붙잡는지만 분야마다 다릅니다.

표에 나오는 트랜잭션은 여러 읽기와 쓰기를 한 덩어리로 묶는 단위입니다. 묶인 것은 전부 되거나 전부 안 됩니다.

어디서 무엇을 붙잡나 무엇에 쓰나
저장 장치 · 파일 시스템 볼륨 하나의 모든 블록 되돌리기 · 멈춤 없는 백업
버전 관리 도구 그 시점 폴더 전체의 모습 이력 보관 · 옛 상태 꺼내기
데이터베이스 읽기 한 시점의 트랜잭션 결과 오래 걸리는 조회를 막힘 없이
복제 로그 어느 줄까지 실행한 상태 로그 줄이기 · 뒤처진 서버 따라잡게 하기

데이터베이스 읽기가 조금 다릅니다. 저장 장치의 스냅샷은 파일로 남지만, 읽기 시점 스냅샷은 대개 아무것도 안 남깁니다. 「이 조회는 이 시점까지의 결과만 본다」는 약속만 세웁니다. 그 뒤에 커밋된 변경을 안 보여 주는 식으로 시점을 흉내 냅니다.

복제 로그는 다른 서버에 같은 변경을 그대로 재생하려고 쌓아 두는 기록입니다. 줄이 계속 쌓이면 늦게 붙은 서버가 처음부터 다 재생해야 합니다. 그래서 어느 줄까지 실행한 상태를 스냅샷으로 떠 둡니다. 뒤처진 서버에는 그 스냅샷부터 보내 따라잡게 합니다.

대가

공간은 뜬 뒤에 바뀐 만큼 늡니다. 스냅샷을 오래 둘수록 원본과 갈라진 조각이 쌓이므로, 가만히 두어도 공간은 계속 늘어납니다. 그래서 대개는 며칠이나 몇 주 같은 보존 기간을 정해 두고 지난 것을 지웁니다.

쓰기가 느려집니다. 스냅샷이 걸린 원본에 쓰려면 옛 값을 먼저 남겨야 하므로, 한 번 쓸 것을 두 번 쓰게 됩니다. 스냅샷을 여럿 쌓아 두면 이 일이 쌓입니다.

백업을 대신하지 못합니다. 스냅샷은 원본과 같은 장치 안에서 데이터를 나눠 씁니다. 장치가 망가지면 원본과 함께 사라집니다.

다른 장치나 다른 지역으로 실제로 옮겨 놓은 것만 백업입니다. 스냅샷은 그 옮기는 동안 원본이 안 바뀌게 붙잡아 주는 역할에 가깝습니다.

쓸 때와 안 쓸 때

바꾸기 전에 되돌아갈 곳을 만들어 두고 싶을 때가 첫째입니다. 큰 변경을 하기 전, 판올림 전, 위험한 작업 전에 하나 떠 둡니다. 잘못되면 그 시점으로 돌아가면 됩니다.

멈추지 않고 일관된 사본을 얻고 싶을 때가 둘째입니다. 서비스를 내리지 않고 백업을 뜨거나, 운영 데이터를 시험 환경으로 옮길 때 씁니다.

반대로, 긴 보관이 목적이면 스냅샷만으로 끝내지 않습니다. 원본과 운명을 같이하기 때문입니다.

캐시 항목 하나하나처럼 값마다 지워질 때가 다른 데이터에도 안 맞습니다. 스냅샷은 범위 전체를 한 시점으로 묶기 때문입니다. 값마다 수명을 다르게 주는 일은 TTL(Time to Live, 살아 있을 시간)이 맡습니다.

관련 항목

스냅샷을 떠 두는 저장 계층

파일 시스템 · 볼륨 · 블록 장치 · 디스크 · 가상 머신 · LVM 스냅샷 · ZFS 스냅샷

스냅샷이 복사를 미룰 때 쓰는 기법

쓰기 시 복사 · 참조 카운트 · 하드링크 · 블록 · 중복 제거

같은 목적으로 스냅샷 대신 쓰는 수단

백업 · 전체 백업 · 증분 백업 · 덤프 · 복제 · 시점 복구 · 아카이빙

버전 관리에서 스냅샷을 담는 단위

커밋 · 트리 객체 · 브랜치 · 태그 · Git · 머클 트리

데이터베이스가 읽기 시점을 고정하는 장치

MVCC · 스냅샷 격리 · 직렬가능 스냅샷 격리 · 격리 수준 · 트랜잭션 · 리비전 · 낡은 데이터

복제 로그를 줄이려고 스냅샷을 쓰는 장치

Raft · 로그 압축 · 체크포인트 · 선행 기록 로그 · 컴팩션 · 변경 데이터 캡처

쌓인 스냅샷을 줄일 때 거는 규칙

보존 기간 · TTL · 축출 · 콜드 스토리지 · 계층형 저장소

다른 이름: snapshot · 스냅숏