본문 바로가기

Dev/linux

[Linux] Shell & crontab, Google Drive api를 이용한 Mysql 데이터베이스 백업 (1)

 

 

 

이번 포스팅은 리눅스 상에서 Shell 스크립트와 crontab, 그리고 Google Drive api를 이용해 주기적으로 로컬과 클라우드에 Mysql DB를 백업하는 방법에 대해 포스팅해보겠습니다.

mysqldump로 쿼리 스크립트를 작성 후, 클라우드 상에 전송하여 서버가 죽게 되더라도 안전하게 데이터를 보존하기 위해 나름대로 고안해본 방식입니다.

 

본 포스팅은 구축 방법에 대해 세세하게 짚고 넘어가므로 분량이 꽤 깁니다.

이번 포스팅으로 작성하게 될 스크립트 결과물은 3번 포스팅 최하단에 업로드되어있으니 참고해주세요.

 

과거, 아래의 포스팅을 한 적이 있습니다.

2020.09.27 - [Dev/etc] - Linux에서의 Shell & crontab을 이용한 Mysql 데이터베이스 백업

 

Linux에서의 Shell & crontab을 이용한 Mysql 데이터베이스 백업

본 포스팅은 리눅스에서 Shell과 crontab 반복 예약 작업 기능을 활용해서 정해진 날짜, 시간에 데이터베이스의 자료를 sql 파일 형태로 백업하는 방법을 기록합니다. 테스팅 환경은 Ubuntu Linux, Arch Li

dev-overload.tistory.com

 

본 포스팅은 위 내용의 확장판에 해당하는 글입니다.

 

테스트 환경은 Ubuntu, raspberryPi입니다.

 

1. 환경 구성

  • 서버상에 MySQL 혹은 mariaDB 서버, 백업에 필요한 데이터베이스와 테이블이 정의되어있어야 합니다.
  • Python3가 설치되어 있어야 합니다.
  • Google 계정이 있어야 합니다.

 

2. 백업 디렉터리 생성

home
├── db_backup
│   ├── db_backup.sh
│   ├── db_백업본{data}.sql
│   ├── db_백업본{data}.sql
│   ├── db_백업본{data}.sql
│   └── db_백업본{data}.sql
...

 

본 포스팅에서는 /home 디렉터리에 db_backup이라는 폴더를 만들어 이곳에서 데이터 베이스 백업과 관련된 자료들을 관리할 것입니다.

아래의 명령어로 폴더를 생성해줍니다.

 

$ sudo mkdir /home/db_backup

 

백업에 필요한 쉘 스크립트 또한 이 폴더 안에서 관리될 것입니다.

 

스크립트를 작성하기 전에 MySQL 5.6 이상의 버전을 사용하는 환경이라면(mariaDB가 아닙니다.) mysql_config_editor 명령을 이용해 MySQL 로그인 패스 설정을 추가로 해 주어야 합니다.

mariaDB는 mysql_config_editor 명령이 없기 때문에, 쉘에서 직접 계정과 패스워드를 입력해 줄 예정입니다.

 

MySQL 사용자의 경우, 아래의 접은 글을 참고해 로그인 정보를 정의해 주세요.

더보기

쉘 스크립트를 통해서 데이터 베이스로 접근할 때, MySQL 5.6 이상의 환경에서는 유저 정보와 패스워드 정보를 직접 넣을 경우, 쉘에 패스워드를 직접 넣지 말라고 터미널에 경고를 띄워줍니다.

 

이럴 때는 mysql_config_editor를 이용해 로그인 정보를 설정하고, 쉘에서는 그 로그인 정보만 알려주는 방식으로 경고를 해결할 수 있습니다.

 

아래의 명령어로 로그인 정보를 설정합니다.

$ mysql_config_editor set --login-path=[path name] --host=[host addr] --user=[account name] --password --port=[port number]

 

여기서 --login-path=[path name]는 아무 이름이나 넣어도 무관합니다.

로컬에서만 로그인 정보를 사용할 경우 --host=localhost --port=3306으로 설정합니다.

--user는 MySQL 계정을 입력합니다.

 

아래의 명령어로 로그인 정보가 제대로 반영되었는지 확인합니다.

$ mysql_config_editor print --login-path=[path name]

 

위 사진과 유사한 형태라면 정상적으로 로그인 정보가 등록된 것입니다.

 

3. DB 백업 Shell 스크립트 작성

home/db_backup 디렉터리에 db_backup.sh이라는 이름으로 파일을 하나 생성하고 에디터를 이용해 아래의 정보를 작성합니다.

먼저 MySQL의 경우와 mariaDB의 경우의 스크립트를 따로 구분했습니다.

해설은 스크립트 이후에 이어집니다.

 

 

MySQL 사용자를 위한 스크립트

### sudo vim /home/db_backup/db_backup.sh
### MySQL환경: 아래의 #!bin/sh 내용부터 작성합니다.

#!bin/sh

LOGIN_PATH=로그인 패스 입력(따옴표 생략)
DBNAME=백업할 데이터베이스이름을 입력합니다(따옴표 생략)
BACKUP_DIR=/home/db_backup # 백업할 경로
BACKUP_ROTATE=30 # 현재 시점 30일 전보다 과거의 파일을 삭제하기 위한 변수

today=$(date +%Y%m%d)

# dump 실행
/usr/bin/mysqldump --login-path=${LOGIN_PATH} ${DBNAME} > ${BACKUP_DIR}/${DBNAME}-${today}.dump

# dump 파일 생성 성공 여부 체크
if [ $? -eq 0 ]; then
    #dump 파일 압축
    gzip ${BACKUP_DIR}/${DBNAME}-${today}.dump
    
    # 외부에서 함부로 지울 수 없도록 파일의 소유권을 root로 지정
    chown root:root ${BACKUP_DIR}/${DBNAME}-${today}.dump.gz
    
    # root 이외의 계정은 열람만 가능하고 수정은 불가 하도록 권한 설정
    chmod 755 ${BACKUP_DIR}/${DBNAME}-${today}.dump.gz

    # 오래된 백업 압축 파일을 찾아서 삭제
    find ${BACKUP_DIR} -name ${DBNAME}-*.dump.gz -mtime +${BACKUP_ROTATE} | xargs rm -f
else
	# 백업본 생성 실패 시, /var/log/message에 기록을 남긴다
	logger 'mysqldump command failed!'
fi

 

 

mariaDB 사용자를 위한 스크립트

### sudo vim /home/db_backup/db_backup.sh
### mariaDB환경: 아래의 #!bin/sh 내용부터 작성합니다.

#!bin/sh

DBUSER=데이터베이스 유저명을 입력합니다.
DBPASS=데이터베이스 패스워드를 입력합니다.
DBNAME=백업할 데이터베이스이름을 입력합니다(따옴표 생략)
BACKUP_DIR=/home/db_backup # 백업할 경로
BACKUP_ROTATE=30 # 현재 시점 30일 전보다 과거의 파일을 삭제하기 위한 변수

today=$(date +%Y%m%d)

# dump 실행
/usr/bin/mysqldump -u${DBUSER} -p${DBPASS} ${DBNAME} > ${BACKUP_DIR}/${DBNAME}-${today}.dump

# dump 파일 생성 성공 여부 체크
if [ $? -eq 0 ]; then
    #dump 파일 압축
    gzip ${BACKUP_DIR}/${DBNAME}-${today}.dump
    
    # 외부에서 함부로 지울 수 없도록 파일의 소유권을 root로 지정
    chown root:root ${BACKUP_DIR}/${DBNAME}-${today}.dump.gz
    
    # root 이외의 계정은 열람만 가능하고 수정은 불가 하도록 권한 설정
    chmod 755 ${BACKUP_DIR}/${DBNAME}-${today}.dump.gz

    # 오래된 백업 압축 파일을 찾아서 삭제
    find ${BACKUP_DIR} -name ${DBNAME}-*.dump.gz -mtime +${BACKUP_ROTATE} | xargs rm -f
else
	# 백업본 생성 실패 시, /var/log/message에 기록을 남긴다
	logger 'mysqldump command failed!'
fi

 

mysql일 때와 mariaDB 스크립트의 차이점은 mysqldump 명령어 수행에 있습니다.

mysql의 경우 login_path로 접근하며, mariaDB에서는 직접 유저명과 패스워드로 접근합니다.

 

위 스크립트는 과거 제가 포스팅했던 2020.09.27 - [Dev/etc] - Linux에서의 Shell & crontab을 이용한 Mysql 데이터베이스 백업 에서의 스크립트보다 한층 더 개선시킨 스크립트입니다.

 

코드의 실행 순서를 나열하자면 다음과 같습니다.

  • mysqldump 명령어를 수행합니다.
  • 명령어가 정상적으로 동작했는지 여부를 체크합니다.
  • 명령이 실패했다면 logger를 이용해 /var/log/message에 실패 사실을 기록합니다.
  • 명령이 성공했다면 gzip 명령어를 이용해 dump 파일을 압축합니다.
  • 압축파일의 소유권을 root로 변경해 외부에서 쉽게 지우지 못하게 합니다.
  • 압축파일의 접근 권한은 root 계정 이외에는 열람 권한만 부여하고 수정을 못하게 합니다.
  • 과거의 백업 파일을 삭제합니다.

여기서 과거의 파일을 삭제하는 명령어를 살펴보겠습니다.

 

find ${BACKUP_DIR} -name ${DBNAME}-*.dump.gz -mtime +${BACKUP_ROTATE} | xargs rm -f

 

find 명령어를 이용해 백업 폴더에서 -name으로 전체 백업본 중 +${BACKUP_ROTATE} 파라미터로 과거의 파일들을 찾아냅니다.

예시에서 BACKUP_ROTATE는 30으로 지정했으므로 현재 기준 30일 이전의 파일들을 찾아낸다는 의미가 됩니다.

여기서 xargs rm -f 명령을 조합해 30일 이전의 파일들을 모두 삭제하도록 처리하였습니다.

 

이와 같이 처리한 이유는, dump 파일은 기본적으로 텍스트 파일로, DB 데이터가 쌓일수록 용량이 많이 늘어나는데, 이러한 데이터들이 계속 쌓여 용량 점유율이 100%에 도달하게 될 경우 시스템이 다운될 수 있기 때문입니다.

 

이러한 이유로 백업 파일의 저장 한도를 제한해 둘 필요가 있습니다.

gzip 명령을 사용해 dump 파일을 압축한 것도 이와 같은 맥락입니다.

 

이제 다음의 명령어로 실행 모드를 추가하고 스크립트가 정상적으로 동작하는지 확인해 보겠습니다.

 

# 실행모드 추가
$ sudo chmod +x /home/db_backup/db_backup.sh

# 실행
$ sudo /home/db_backup/db_backup.sh

 

만약 mysqldump 명령이 잘못되었다면 /var/log/message에 아래와 같이 로그가 쌓일 것입니다.

데이터베이스는 매우 중요한 자료이고 데이터가 휘발된다면 복구하기가 매우 힘들기 때문에 백업이 수시로 잘 이루어지고 있는지 확인할 필요가 있습니다.

mysqldump 명령 실패

 

정상적으로 실행이 완료되었을 때의 폴더 내용입니다.

의도한 대로 dump.gz 형태로 백업이 잘 이루어졌습니다.

 

이제 위 코드를 근간으로 Google Drive에 저장하도록 점차 확장시켜보도록 하겠습니다.

 

다음 포스팅에서는 이렇게 생성된 백업 압축 파일을 자신이 사용하고 있는 Google Drive에 2중으로 안전하게 보존하기 위한 준비 절차에 대해 알아보도록 하겠습니다.