RDS 백업과 복구, 되돌리면 새 인스턴스가 생기는 이유
RDS에서 백업으로 되돌리면 지금 쓰는 데이터베이스가 되감기지 않고 새 DB 인스턴스가 생긴다.
그래서 연결 주소를 옮기고, 설정 묶음을 다시 붙이고, 복구 직후의 느린 성능까지 따로 챙겨야 한다.
이 글의 목차RDS가 백업을 남기는 방식6
RDS로 데이터베이스를 운영하다 보면 데이터를 되돌려야 하는 날이 온다.
조건을 잘못 건 일괄 수정으로 여러 행이 한꺼번에 바뀌었거나, 지우면 안 되는 테이블을 지웠을 때가 그렇다.
RDS는 데이터베이스 서버의 설치와 백업, 패치를 AWS가 대신 맡아 주는 서비스다.
콘솔의 자동 백업 메뉴에서 ‘특정 시점으로 복원’을 고르고 시각을 정하면 새 DB 인스턴스의 이름을 적으라는 칸이 나온다.
RDS는 데이터베이스 서버 한 대를 DB 인스턴스라고 부른다.
되돌린다는 말에서 지금 쓰는 DB가 그 시각으로 되감기는 모습을 떠올렸다면 이 칸이 이상해 보인다.
RDS의 복구는 지금 쓰는 인스턴스를 되감지 않는다.
RDS가 백업을 남기는 방식
자동 백업은 하루에 한 번, 정해 둔 백업 시간대에 돌아간다.
이때 RDS는 DB 인스턴스의 저장 공간 전체를 스냅샷으로 뜬다.
스냅샷은 디스크를 그 순간의 모습 그대로 떠 둔 사본이다.
인스턴스 안에 데이터베이스가 여러 개 있어도 전부 한꺼번에 담긴다.
자동 백업과 별개로 원할 때 직접 떠 두는 스냅샷도 있는데, 이것은 수동 스냅샷이라고 부른다.
자동 백업은 정해 둔 보관 기간 동안 남는다.
보관 기간은 0일에서 35일 사이로 정하고, 콘솔에서 인스턴스를 만들면 기본값은 7일이다.
0으로 두면 자동 백업이 꺼진다.
스냅샷이 하루에 한 번이라면 그 사이에 바뀐 데이터는 어떻게 될까.
RDS는 데이터 변경을 차례로 적은 트랜잭션 로그를 5분마다 AWS의 저장소 서비스인 S3에 따로 올려 둔다.
스냅샷과 이 로그를 함께 쓰기 때문에 보관 기간 안이라면 원하는 시각을 고를 수 있다.
가장 최근 몇 분은 로그가 아직 올라가지 않았을 수 있어서, 콘솔에 나오는 ‘복원 가능한 최근 시간’은 대개 지금보다 몇 분 전이다.
복구는 원본을 건드리지 않는다
시점 복구는 원본 인스턴스를 바꾸지 않고 새 DB 인스턴스를 만든다.
스냅샷에서 복구할 때도 같다.
기존 인스턴스에 덮어쓰는 방법은 없고 언제나 새 인스턴스가 생긴다.
원본이 그대로 남아 있으니 복구한 데이터와 나란히 놓고 비교할 수 있다.
시각을 잘못 골랐다면 다른 시각으로 한 번 더 복구하면 된다.
대신 애플리케이션 쪽에 할 일이 생긴다.
앱은 여전히 원본에 붙어 있고, 복구가 끝났다고 해서 알아서 새 인스턴스를 읽기 시작하지 않는다.
복구를 실행하면 새 DB에 과거 기록이 돌아오지만, 앱은 연결을 전환한 뒤에야 그 기록을 읽는다.
기록을 지우기 전 시점으로 새 DB를 만든 뒤 앱의 연결이 어디를 향하는지 보여 준다.
원래 DB
기록 없음앱이 여기를 읽음
복원 DB
아직 없음원래 DB
기록 없음앱이 여기를 읽음
새 복원 DB
과거 기록 있음아직 앱과 연결 안 됨
원래 DB
그대로 남음기록 없음
새 복원 DB
과거 기록 있음앱이 여기를 읽음
RDS 시점 복구는 원래 DB 옆에 새 DB를 만든다. 앱이 그 DB를 읽으려면 연결도 전환해야 한다.
앱은 기록이 지워진 원래 DB를 읽고 있다.
복원 시점 뒤의 쓰기는 새 DB에 포함하지 않는 예시다. 설정·성능 회복과 실제 전환 준비는 별도로 확인해야 한다.
새 인스턴스는 주소도 새로 받는다
앱은 데이터베이스에 접속할 때 엔드포인트라는 주소를 쓴다.
RDS가 인스턴스마다 만들어 주는 도메인 이름 형태의 주소인데, 이 주소 안에 인스턴스 이름이 들어간다.
이름이 다른 새 인스턴스는 주소도 다르다.
앱이 새 인스턴스를 보게 하는 방법은 두 가지다.
첫째는 앱의 연결 설정에 적힌 주소를 새 엔드포인트로 바꾸는 것이다.
설정을 고치고 앱을 다시 띄우면 되니 가장 단순하다.
둘째는 이름을 맞바꾸는 방법이다.
원본의 이름을 다른 것으로 바꿔 비켜 두고 복구한 인스턴스에 원래 이름을 붙이면, 엔드포인트가 예전과 같아져 앱 설정은 손대지 않아도 된다.
이름 바꾸기에는 조건이 붙는다.
먼저 원본으로 가는 트래픽을 모두 멈춰야 한다.
이름을 바꾸면 옛 주소는 바로 지워지지만, 새 주소는 10분쯤 지나야 통한다.
그동안은 그 인스턴스에 접속할 수 없고, 이름을 바꿀 때 재부팅도 일어난다.
어느 방법을 쓰든 놓치기 쉬운 것이 하나 있다.
고른 시각 뒤에 원본에 들어온 쓰기는 새 인스턴스에 없다.
사고 뒤에도 서비스가 원본에 계속 쓰고 있었다면, 그 데이터를 따로 옮길지 먼저 정하고 전환해야 한다.
RDS 장애 조치 글에서 다룬 전환에서는 RDS가 같은 이름이 다른 서버를 가리키도록 바꿔 준다.
복구에는 그런 자동 전환이 없어서 사람이 직접 옮겨야 한다.
설정 묶음과 보안 그룹은 다시 붙인다
RDS는 데이터베이스 엔진의 설정값을 파라미터 그룹이라는 묶음으로 관리한다.
최대 연결 수나 시간대 같은 값이 여기 들어간다.
엔진별 부가 기능을 켜는 옵션 그룹도 따로 있다.
복구한 인스턴스에는 기본 파라미터 그룹과 기본 옵션 그룹이 붙는다.
원본에서 조정해 둔 값은 따라오지 않는다.
콘솔로 복구했다면 끝난 뒤에 다시 지정하고, AWS CLI 같은 명령줄 도구나 API로 복구한다면 요청할 때 함께 지정한다.
이것을 놓치면 데이터는 맞는데 동작이 다른 상태로 서비스가 돌아간다.
원본에서 최대 연결 수를 늘려 두었다면, 복구한 쪽은 바쁜 시간에 더 일찍 연결을 거절할 수 있다.
보안 그룹도 다시 봐야 한다.
시점 복구를 할 때는 VPC의 기본 보안 그룹을 쓸지 다른 보안 그룹을 붙일지 고른다.
VPC는 AWS 안에 따로 만든 내 사설 네트워크다.
앱 서버의 접속을 허용하는 보안 그룹이 붙지 않으면 새 인스턴스는 앱의 연결을 받지 못한다.
보안 그룹이 연결을 어떻게 걸러 내는지는 포트와 방화벽 글에서 기초부터 다뤘다.
복구 직후에는 아직 느리다
복구가 끝나도 데이터가 전부 디스크에 내려와 있지는 않다.
인스턴스가 사용 가능해진 뒤에도 저장 볼륨은 백업이 있는 S3에서 데이터 블록을 계속 내려받는다.
이 동안 인스턴스는 동작하지만 성능은 아직 제 상태가 아닐 수 있다.
이런 방식을 지연 로딩(lazy loading)이라고 부른다.
아직 내려오지 않은 데이터를 읽으면 그 자리에서 S3에서 가져오므로, 처음 읽는 테이블은 응답이 느려지기 쉽다.
헷갈리기 쉬운 것은 콘솔의 상태 표시다.
시점 복구 뒤 초기화가 도는 동안에도 상태는 ‘사용 가능(available)‘으로 보인다.
진행률은 인스턴스 정보를 조회하는 DescribeDBInstances API의 응답에서 저장소 작업 항목으로 따로 확인한다.
그래서 복구 직후의 응답 속도만 보고 성능 문제라고 단정하지 않는다.
자주 쓰는 테이블을 처음부터 끝까지 한 번 읽어 미리 내려받게 하는 방법도 있다.
사고 전에 한 번 복구해 보기
AWS는 원본 인스턴스가 망가졌을 때 스냅샷에서 새 인스턴스를 만드는 것을 재해 복구 방법으로 안내한다.
절차는 어렵지 않지만, 처음 해 보는 날이 사고 당일이면 앞의 조건들을 한꺼번에 만난다.
그래서 실무에서는 복구를 미리 해 본다.
테스트용 인스턴스로 복구해 걸리는 시간을 재고, 다시 붙여야 할 파라미터 그룹과 보안 그룹을 적어 두고, 앱을 그쪽에 붙여 조회가 실제로 되는지 확인한다.
인스턴스를 지울 때도 백업을 함께 챙긴다.
삭제할 때 자동 백업 보존을 고르지 않으면 자동 백업도 인스턴스와 함께 지워진다.
수동 스냅샷은 인스턴스를 지워도 남는다.
삭제 화면에서 지우기 직전의 최종 스냅샷을 만들게 할 수도 있다.
연습으로 만든 인스턴스에도 요금이 나간다.
시점 복구로 만드는 인스턴스는 생성 중일 때부터 과금되고, 다 만들어진 뒤에는 일반 인스턴스와 똑같이 청구된다.
확인이 끝나면 바로 지운다.