파일 복원: Btrfs 스냅샷

2021년 10월 12일 본문 업데이트:

우분투 서버의 Live 설치 이미지는 Btrfs 서브볼륨을 자동으로 생성하지 않으므로 관련 설명 업데이트

    Btrfs 스냅샷

    리눅스의 여러 가지 파일 시스템 중에서 Btrfs는 자신의 서브볼륨 구조를 이용해서 파일을 예전 상태로 되돌릴 수 있는 스냅샷 기능을 제공한다. Btrfs 형식으로 포맷된 볼륨에서 원하는 디렉토리를 원하는 시점에 스냅샷으로 저장해두면 언제든지 저장했던 상태로 되돌릴 수 있다. 디렉토리 전체를 되돌리는 것은 물론이고 특정 파일만 되돌리는 것도 가능하다. 이 스냅샷 기능은 파일 자체를 백업하는 것이 아니라 파일의 변경 이력을 저장하는 방식을 사용하기 때문에 저장 공간도 많이 차지하지 않고 디스크 부하도 적다. 그래서 스냅샷 저장 주기를 적절하게 설정해두면 지금 작업 중인 파일의 이전 버전을 계속 백업해둘 수도 있고, 혹시 랜섬웨어에 감염되어 파일이 변형되더라도 감염되기 이전의 파일로 쉽게 되돌릴 수 있다.

    Btrfs 서브볼륨

    스냅샷 기능을 사용하려면 볼륨이 Btrfs 파일 시스템 형식으로 포맷되어야 하고, Btrfs의 기능인 서브볼륨을 생성해야 한다. 우분투 서버의 Live 설치 이미지는 Btrfs 서브볼륨을 자동으로 생성하지 않기 때문에 직접 생성하고 설정해주어야 한다. 예를 들어, 앞서 우분투 서버를 설치할 때 /mydisk 에 마운트한 데이터 저장용 디스크에 @mydisk 라는 서브볼륨을 생성하고, 시스템 시작 시에 마운트할 디스크를 관리하는/etc/fstab 파일에 subvol=@mydisk 옵션을 추가하면 이 디스크에서 Btrfs 서브볼륨을 사용할 수 있게 된다. 스냅샷은 이 서브볼륨을 이용한다. 만약에 서브볼륨 @mydisk을 5월 1일에 @05-01 이라는 이름의 스냅샷으로 저장해두었다가, 나중에 @mydisk을 삭제하고 @05-01을 @mydisk으로 이름만 바꿔서 넣어주고 재부팅 하면 바뀐 @mydisk이 /mydisk에 마운트 되어 5월 1일의 내용으로 바뀐 /mydisk을 사용할 수 있게 된다.

    서브볼륨 생성

    우분투 서버를 설치할 때 Btrfs로 포멧한 디스크를 /mydisk 에 마운트한 경우를 가정한다.

    df -h

    먼저 이 명령으로 디스크 볼륨 및 마운트 위치를 확인해본다.
    /dev/md0 80G 17M 78G 1% /mydisk
    이런 형태로 /dev/md0 볼륨이 /mydisk 에 마운트 되어 있는 것을 확인할 수 있다.

    sudo btrfs subvolume list /mydisk

    이 명령으로 현재 /mydisk에 생성된 서브볼륨이 있는지 확인한다. 아무런 결과값도 출력되지 않는다면 현재 서브볼륨이 없는 상태이다.

    sudo btrfs subvolume create /mydisk/@mydisk

    이 명령으로 /mydisk/@mydisk라는 서브볼륨을 생성한다. @mydisk 대신에 다른 이름을 사용해도 되지만 /mydisk 의 서브볼륨임이 명확하게 보이도록 mydisk 이름을 사용하고 일반 디렉토리가 아닌 서브볼륨임을 파악하기 쉽도록 이름 앞에 @을 붙여줬다.

    sudo btrfs subvolume list /mydisk

    생성된 서브볼륨이 있는지 다시 확인해보면
    ID 123 gen 12345 top level 5 path @mydisk 같은 결과값이 출력된다.

    sudo nano /etc/fstab

    디스크 마운트를 담당하는 fstab 파일을 nano 편집기로 연다.

    # /mydisk was on /dev/md0 during curtin installation
    /dev/disk/by-id/md-uuid-a123bcde:0f123456:def54321:987abc70 /mydisk btrfs defaults,subvol=@mydisk 0 1
    

    /mydisk 마운트 부분을 찾아서 위 예시와 같이 defaults 다음에 ,subvol=@mydisk 설정을 추가한다.

    sudo reboot

    우분투 서버를 재시작하면 /dev/md0의 서브볼륨 @mydisk/mydisk에 마운트되어 스냅샷 기능을 사용할 수 있게 된다.

    스냅샷 서브볼륨 설정

    스냅샷이 저장될 장소인 “스냅샷 서브볼륨”은 스냅샷의 대상이 되는 “원본 서브볼륨 (@mydisk)”과 동일한 위치에 존재하는 것이 관리에 용이하다. 만일 스냅샷 서브볼륨이 원본 서브볼륨 (@mydisk) 의 하위 경로에 위치한다면 나중에 스냅샷으로 원본을 복구했을 때 경로가 재귀적으로 꼬여서 복잡한 상황이 된다.

    또한 디스크 볼륨 전체를 스냅샷으로 저장하려면 원본 서브볼륨 @mydisk 가 위치한 동일한 경로에 스냅샷 서브볼륨을 생성해야 하는데, 앞서 원본 서브볼륨을 활성하기 위해서 @mydisk를 /mydisk 에 마운트했기 때문에 마운트한 지점 /mydisk (@mydisk) 로부터 하위의 경로에만 접근 할 수 있을 뿐 @mydisk 자체의 경로에는 접근할 수 없다. 이때에는 이 디스크 볼륨 /dev/md0 를 임의의 경로에 별도로 다시 마운트해주면 @mydisk 의 경로에 접근할 수 있다.

    sudo mkdir /mntsnap

    먼저 이 명령으로 Btrfs 디스크 볼륨을 한 번 더 마운트할 임의의 디렉토리 /mntsnap를 생성한다. 이 디렉토리 이름은 원하는 대로 정하면 된다.

    df -h

    현재 시스템에 마운트 되어 있는 디스크 볼륨을 확인한다.
    /dev/md0 80G 17M 78G 1% /mydisk
    이런 형태로 출력되는 내용에서 현재 /dev/md0/mydisk에 마운트 되어 있음을 확인한다.

    sudo mount /dev/md0 /mntsnap

    앞에서 확인한 /dev/md0 볼륨을 앞서 생성한 /mntsnap에 마운트한다.

    df -h

    df -h 명령을 한 번 더 실행해보면
    /dev/md0 80G 17M 78G 1% /mydisk
    /dev/md0 80G 17M 78G 1% /mntsnap
    이런 형태로 /dev/md0 볼륨이 /mydisk/mntsnap에 동시에 마운트 된 것을 확인할 수 있다.

    sudo btrfs subvolume list /mydisk
    sudo btrfs subvolume list /mntsnap

    이 명령으로 /mydisk/mntsnap에 존재하는 서브볼륨의 목록을 출력해본다.
    ID 123 gen 12345 top level 5 path @mydisk
    이런 형태로, 동일한 값이 출력되며 기본 마운트 서브볼륨을 뜻하는 top level 5로 출력되는지 확인한다.

    sudo btrfs subvolume create /mntsnap/@snapshot

    스냅샷이 저장될 서브볼륨 @snapshot을 @mydisk과 동등한 위치인 /mntsnap/ 에 생성한다. @snapshot 대신에 다른 이름을 사용해도 된다. 일반 디렉토리가 아닌 서브볼륨임을 파악하기 쉽도록 이름 앞에 @을 붙여줬다. 서브볼륨은 일반 디렉토리처럼 cd, ls, cp, mv 명령으로 다룰 수 있지만 rm 명령으로 삭제하지는 못한다. 삭제는 아래에서 설명하는 별도의 btrfs 명령을 사용해야 한다.

    sudo btrfs subvolume list /mntsnap

    /mntsnap에 존재하는 서브볼륨 목록을 다시 출력해본다.
    ID 123 gen 12345 top level 5 path @mydisk
    ID 234 gen 23456 top level 5 path @snapshot
    이런 형태로 출력될 것인데, @mydisk과 같은 top level 5@snapshot이 생성되었는지 확인한다.

    스냅샷 생성

    sudo btrfs subvolume snapshot /mntsnap/@mydisk /mntsnap/@snapshot/@SNAP_`date +%Y.%m.%d_%H.%M.%S`

    이제 첫 번째 스냅샷을 생성한다. 위 명령은 /mntsnap/@mydisk의 스냅샷을 /mntsnap/@snapshot 경로 밑에 @SNAP_연.월.일_시.분.초 서브볼륨을 만들어서 저장하라는 명령이다. 이 명령을 실행할 때 @SNAP_ 부분은 원하는 것으로 변경해도 되지만 `date +%Y.%m.%d_%H.%M.%S`는 반드시 이대로 작성해야만 윈도우 OS가 스냅샷을 인식하고 복원할 수 있다. `는 키보드의 ~키에 함께 있는 기호이고, date+ 사이에 공백 하나가 들어가는 것도 주의해야 한다.

    sudo btrfs subvolume list /mntsnap

    /mntsnap에 존재하는 서브볼륨 목록을 다시 출력해본다.
    ID 123 gen 12345 top level 5 path @mydisk
    ID 234 gen 23456 top level 5 path @snapshot
    ID 345 gen 34567 top level 123 path @snapshot/@SNAP_2020.05.01_11.01.00
    이런 형태로 @snapshot/@SNAP_2020.05.01_11.01.00 경로에 스냅샷이 생성된 것을 확인할 수 있다.

    스냅샷 볼륨 마운트

    위에서 본 것처럼, 스냅샷을 생성하려면 Btrfs 볼륨을 한 번 더 마운트 해야 하는데, 매번 마운트 하기 보다는 서버가 부팅될 때 Btrfs 볼륨이 자동으로 마운트 되도록 설정해두면 수시로 스냅샷을 생성하고 또 복원하기에 편리하다.

    sudo nano /etc/fstab

    디스크 마운트를 담당하는 fstab 파일을 nano 편집기로 연다.

    # /mydisk was on /dev/md0 during curtin installation
    /dev/disk/by-id/md-uuid-a123bcde:0f123456:def54321:987abc70 /mydisk btrfs defaults,subvol=@mydisk 0 1
    
    /dev/disk/by-id/md-uuid-a123bcde:0f123456:def54321:987abc70 /mntsnap btrfs defaults 0 1
    

    앞서 ,subvol=@mydisk 설정을 추가했던 /mydisk 마운트 항목을 찾아서 해당 줄 전체를 복사한 다음에, 이번에는 ,subvol=@mydisk 옵션 없이 /mydisk/mntsnap로 바꿔서 추가한다.

    추가했으면, nano 편집기에서 빠져나오기 위해서 Ctrl키와 x키를 동시에 누르면 수정한 내용을 저장하겠냐고 물어오는데 y를 입력하고, 저장할 위치를 물어오면 표시된 위치에 그대로 엔터키를 눌러서 저장한다. 이제 서버가 부팅될 때 /mydisk에 마운트 되는 것과 동일한 볼륨이 /mntsnap 위치에도 자동으로 마운트 된다.

    스냅샷 간격 설정

    스냅샷은 기본적으로 위의 명령으로 수동으로 생성해야 하는데, 위의 명령을 담은 스크립트 파일을 만들어서 우분투 서버의 스케줄러에 등록하면 원하는 시간 간격으로 스냅샷을 자동으로 생성할 수 있다.

    sudo nano /usr/local/etc/btrfs-snapshot.sh

    nano 편집기로 적당한 위치에 적당한 이름의 .sh 파일을 새로 생성한다.

    #!/bin/bash
    /bin/btrfs subvolume snapshot /mntsnap/@mydisk /mntsnap/@snapshot/@SNAP_`date +%Y.%m.%d_%H.%M.%S`
    

    .sh 파일에 스냅샷을 생성하라는 명령을 기록한다. 예시로 든 이 내용은 앞서 첫 번째 스냅샷을 생성했던 명령과 같은 형태이다. 참고로 .sh 파일은 항상 첫 줄에 #!/bin/bash를 기록해야 한다. 작성했으면 Ctrl키와 x키를 동시에 눌러 nano 편집기를 빠져나오면서 저장한다.

    sudo chmod u+x /usr/local/etc/btrfs-snapshot.sh

    생성한 .sh 파일에 실행 권한을 부여한다.

    sudo crontab -e

    우분투 서버의 기본 스케줄러인 crontab을 편집 모드로 실행한다. 만일 어떤 편집기를 사용하겠냐고 물어오면 nano 편집기를 뜻하는 숫자를 입력한다.

    1 * * * * /usr/local/etc/btrfs-snapshot.sh

    이 내용은 매 시 1분에 (1시간에 1번) 앞서 만든 btrfs-snapshot.sh 파일을 실행하라는 스케줄이다. 1 * * * * 부분은 왼쪽부터 분, 시, 일, 월, 요일을 의미한다. 5분 간격으로 스냅샷을 생성하는 스케줄은 */5 * * * * /usr/local/etc/btrfs-snapshot.sh 이다. 원하는 스케줄을 crontab의 끝부분에 기록하고, Ctrl키와 x키를 동시에 눌러 nano 편집기를 빠져나오면서 저장한다. sudo crontab -l 명령으로 crontab 내용을 확인할 수 있다.

    스냅샷 삭제

    ls -l /mntsnap/@snapshot/

    ls 명령으로 /mntsnap/@snapshot 경로 하위에 생성되어 있는 스냅샷을 확인하고, 삭제하려는 특정 스냅샷을 결정한다.
    @SNAP_2020.05.01_11.01.00
    @SNAP_2020.05.01_12.01.00
    @SNAP_2020.05.01_13.01.00
    이렇게 출력 되었다고 가정하고 @SNAP_2020.05.01_12.01.00 을 삭제한다면 아래와 같다.

    sudo btrfs subvolume delete /mntsnap/@snapshot/@SNAP_2020.05.01_12.01.00

    이렇게 btrfs subvolume delete 명령으로 스냅샷을 삭제할 수 있다. 축약형으로 btrfs subvol del 로 명령해도 된다.

    sudo btrfs subvolume delete /mntsnap/@snapshot/*

    /mntsnap/@snapshot 경로 하위에 생성된 스냅샷을 모두 삭제하고 싶다면 이 형식의 명령을 사용하면 된다. 또는 /mntsnap/@snapshot/* 부분을 변형해서 /mntsnap/@snapshot/@SNAP_2020.05.01* 이런 형태로 특정 일자나, /mntsnap/@snapshot/@SNAP_2020.05* 이런 형태로 특정 월, /mntsnap/@snapshot/@SNAP_2020* 이런 형태로 특정 연도의 스냅샷을 삭제할 수도 있다.

    스냅샷 복원

    /mydisk 디렉토리 복원

    /mydisk 디렉토리 전체를 복원하려면 다음의 절차를 따른다.

    ls -la /mntsnap/@snapshot

    생성된 스냅샷 중에서 복원할 스냅샷의 이름을 확인한다.
    @SNAP_2020.05.01_11.01.00
    @SNAP_2020.05.01_12.01.00
    @SNAP_2020.05.01_13.01.00
    이렇게 출력되었다고 가정하고, 아래는 @SNAP_2020.05.01_12.01.00 스냅샷으로 /mydisk 디렉토리를 복원하는 예를 든다.

    sudo mv /mntsnap/@mydisk /mntsnap/@latest_mydisk

    현재 /mydisk 디렉토리의 서브볼륨인 /mntsnap/@mydisk의 이름을 /mntsnap/@latest_mydisk으로 변경해서 백업한다.

    sudo mv /mntsnap/@snapshot/@SNAP_2020.05.01_12.01.00 /mntsnap/@mydisk

    @SNAP_2020.05.01_12.01.00 스냅샷을 @mydisk 으로 바꾼다. 우분투 서버는 부팅할 때 @mydisk을 /mydisk에 마운트하므로, 이제 재부팅하면 @SNAP_2020.05.01_12.01.00의 내용이 새로운 /mydisk이 된다.

    sudo reboot

    복원한 내용이 적용되도록 서버를 재부팅한다.
     

    개별 파일 복원

    개별 파일을 복원하려면 다음의 절차를 따른다.

    cd /mntsnap/@snapshot/스냅샷/경로
    
    ls -la

    cd 명령과 ls 명령으로 스냅샷 경로에 접근하면 스냅샷이 생성된 시점의 모든 파일을 확인할 수 있다.

    cp /mntsnap/@snapshot/복원할/파일/경로 /저장할/경로

    복원할 파일을 cp 명령으로 복사해온다. 권한이 필요한 경우에는 sudo cp 명령을 사용한다.

    한편, 보다 간편하게 개별 파일의 스냅샷을 확인하고 복원하는 방법으로 윈도우 PC에서 SMB로 접근해서 작업하는 방법이 있다. 자세한 내용은 다음 글 네트워크 파일 공유: SMB에서 다룬다.

     

    본 글의 저작권은 작성자 Varins에게 있습니다.
    Varins의 사전 서면 동의 없이 본 글의 전부 또는 일부를 무단으로 전재, 게시, 배포하는 것을 금지합니다.