Database/MariaDB

mariabackup 으로 데이터 복구하기

_su_min 2024. 12. 8. 14:44

mariabackup으로 데이터 백업하기 에 이어서 데이터를 복구하는 방법에 대해 알아보려 해요.

MariaDB 10.6.5 버전 기준으로 내용을 작성했습니다.

 

좀 더 구체적으로 설명하기 위해서 장애 상황을 가정해볼께요.

 

 

 

헐.. 실수로 운영 테이블을 삭제해버렸다..!!!!!

 

 

운영 테이블을 실수로 삭제한 상황을 가정

 

 

2022-01-29 새벽 06시에 mariabackup 으로 MariaDB 의 데이터를 FullBackup 을 했어요.

 

그리고 서비스를 운영하다가 오후 20:00 에 실수로 운영 테이블을 삭제해버리는 일이 발생했어요.

 

이는 서비스 장애로 이어졌고, 현재 서비스 접속이 안되는 상황이예요.

 

장애를 해결하기 위해서 20:00 시점으로 데이터를 복구해보도록 할께요.

 

  - DB의 데이터가 쌓이는 datadir 는 /db/mysql 이라고 할께요.

  - bin-log 파일을 보존하기 위해서 DB 데이터를 백업해둔 디렉토리는 /db/temp 라고 할께요.

  - DB FullBackup 데이터가 저장된 디렉토리는 /db/backup 이라고 할께요.

 

 

1. DB 데이터 유입 차단

 

이 부분은 서비스 운영 상황에 따라 처리가 달라질 것 같은데요.

 

저 같은 경우는 Web 서버에 장애 공지 페이지를 올려서 서비스 이용자가 현재의 상황을 알 수 있게 하고, DB 서버의 MariaDB 서비스를 내리는 방법을 적용하겠습니다.

 

 

2. datadir 디렉토리의 파일을 다른 경로에 백업해둔다.

 

datadir(/db/mysql) 디렉토리의 데이터들을 /db/temp 로 복사합니다.

 

cp /db/mysql /db/temp -r

 

위 명령어로 작업을 수행해요.

 

 

3. datadir 디렉토리를 비운다.

 

datadir(/db/mysql) 디렉토리로 이동해서 아래 명령어로 디렉토리를 비워줘요.

 

rm -rf *

 

 

4. FullBackup 데이터 복구 준비

 

FullBackup 받아놓은 데이터가 저장된 디렉토리(/db/backup)로 이동해요.

 

여기서 아래 명령어로 백업 데이터에 리두 로그를 적용해줘요.

 

mariabackup --prepare --target-dir=/db/backup

 

mariabackup 은 백업을 받는 동안 발생한 리두로그들을 따로 저장해놓는데요.

 

--prepare 옵션으로 mariabackup 을 실행해주면 저장해놨던 리두로그들을 백업데이터에 적용해줘서 이 때부터 복구 가능한 데이터가 되요.

 

--target-dir 에는 백업 데이터가 위치한 경로를 적어주면 되요.

 

 

5. FullBackup 데이터 복구

 

이제 복구 데이터 준비가 끝났으니 복구를 진행해주면 되요.

 

mariabackup --copy-back --target-dir=/db/backup

 

--copy-back 옵션으로 mariabackup 을 실행해주면 백업 데이터를 datadir(/db/mysql) 로 복사해줘요.

 

datadir 로 이동해서 내용을 보면 데이터 복구된 것을 확인할 수 있는데요.

 

여기서 한 가지 주의할 점이 datadir 디렉토리의 파일들의 소유자, 그룹 권한이 root 로 되어 있어서 MariaDB 실행시 권한 에러가 발생한다는 거예요.

 

그래서 datadir(/db/mysql) 의 파일들 권한을 mysql:mysql 로 바꿔줘야해요.

 

chown -R mysql:mysql /db/mysql

 

 

6. MariaDB 서비스 시작

 

systemctl start mariadb

 

MariaDB 서비스를 시작해주면 정상적으로 구동되는 것을 확인할 수 있고 여기까지 완료되었다면 FullBackup 복구에 성공한 거예요.

 

 

7. 백업완료 지점 확인하기

 

이제부터는 FullBackup 완료시점부터 내가 원하는 시점까지 복구하는 ' 시점복구(Point in time) ' 를 진행하게 되는데요.

 

이를 위해서는 우선 FullBackup 으로 백업이 어느 부분까지 완료되었는지 확인이 필요해요.

 

이 정보는 백업 데이터가 저장된 /db/backup 디렉토리를 조회해보면 ' xtrabackup_binlog_info ' 라는 파일이 있는데요.

 

내용을 보면 백업 완료된 bin-log 파일명과 position 을 확인할 수 있어요.

 

mysql-bin.000005 59925 0-1-100

 

 

8. bin-log 파일을 쿼리파일로 변환하기

 

bin-log 파일은 이름에서도 알 수 있듯지 파일 내용이 바이너리 이진값이예요.

 

그래서 바로 확인할 수는 없고 쿼리로 변경해주고 난 다음에 볼 수 있어요.

 

이 때 사용하는 유틸리티가 ' mysqlbinlog ' 인데요.

 

mysqlbinlog mysql-bin.000005 --start-position=59925 > 000005.sql
mysqlbinlog mysql-bin.000006 > 000006.sql
mysqlbinlog mysql-bin.000007 > 000007.sql

 

위 명령문처럼 원하는 범위를 지정해서 sql 을 추출할 수 있어요. 사용할 수 있는 옵션들은 아래와 같아요.

 

  --start-position=N

  읽기 시작 지점의 포지션을 지정 N보다 크거나 같은 포지션 값의 첫 번째 이벤트부터 바이너리 로그를 읽기 시작한다.

 

  --stop-position=N

  마지막 시점의 포지션을 지정한다. N보다 크거나 같은 포지션 값의 첫 번째 이벤트에서 바이너리 로그 읽기를 중단한다.

 

  --start-datetime=datetime

  지정한 datetime 보다 크거나 같은 타임스탬프 값의 첫 번째 이벤트부터 바이너리 로그를 읽기 시작한다.

 

  --stop-datetime=datetime

  지정한 datetime 보다 크거나 같은 타임스탬프 값의 첫 번째 이벤트에서 바이너리 로그 읽기를 중단한다.

 

 

9. bin-log 에서 추출한 쿼리파일 정제하기

 

장애가 발생한 원인을 생각해보면 실수로 테이블을 삭제한 것인데요.

 

바로 'drop table' 쿼리가 날라간것이죠.

 

그래서 해당 쿼리는 bin-log 추출 쿼리 파일에서 제거해주어야해요.

 

000007.sql 파일을 열어서 끝부분을 보니까 drop table 쿼리가 보이는데요.

 

이 부분은 삭제하도록 합니다.

 

10. 시점복구하기

 

이제 sql 파일들을 데이터베이스에 적용해주면 되요.

mysql -uroot -p'{PASSWORD}' < 000005.sql
mysql -uroot -p'{PASSWORD}' < 000006.sql
mysql -uroot -p'{PASSWORD}' < 000007.sql

 

이렇게 하면 시점복구까지 마무리되어서 데이터베이스는 2022-01-29 20:00 의 상태로 돌아오게 됩니다.

 

이제 Web 서버의 장애 안내 페이지를 내리고 서비스를 다시 정상적으로 운영하면 되요.

 

여기까지 mariabackup 복구 작업에 대해서 알아봤습니다.

 

감사합니다 :)