[Docker] mysql volume자동 백업

최영섭·2024년 2월 4일
0
post-thumbnail

0. 배경 및 요구사항

  • mysql 5.7.12버전을 도커 컨테이너로 ubuntu 20.04버전에 올려두고 사용하고 있다.
  • database혹은 container에 문제가 생길것을 대비하여 데이터를 주기적으로 백업해두려고한다.
  • 백업본은 항상 세 개까지로 유지되어야 한다.

1. volume백업을 선택한 이유

우선 mysqldump를 활용하는 것이 더 무결하게 데이터를 백업할 수 있는 방법이지만 아래 이유로 해당 방법을 실행하지 않았다.

  • 개발자 2명에서 서비스를 유지보수하면서 현재 다른 중요한 기술적 요구사항이 많이 남아있는상태
  • 서비스 초기이고 유저가 500명 정도 되는 상황에서 새벽 4시정도에 백업을 진행하면 어느정도 무결하게 데이터가 보존될것이라 예상
  • 무결하게 데이터가 처리되지 않았을 경우의 확률과 그 시기에 데이터베이스에 문제가 생겨 백업 본을 사용해야할 확률 그리고 해당 확률에 영향을 받은 유저 수의 cs 규모를 예측했을 때 충분히 감당가능한 수준이라고 판단했다.

굉장히 마음이 불편하지만 지금 시기는 앞단 퍼널의 기술적 요구사항을 해결하는 것이 맞다고 생각한다.

2. mysql volume백업하기

1) volume복제

  • test-volume을 생성
    docker volume create --name test-volume
  • tikkle-mysql-volume을 test-volume으로 복사

    docker run --rm -v tikkle-mysql-volume:/from -v test-volume:/to alpine ash -c "cd /from && cp -a . /to"
    • docker run: 새 Docker 컨테이너를 실행하는 명령.
    • -rm: 컨테이너 실행이 완료된 후 자동으로 컨테이너를 삭제. 이 옵션은 일시적인 작업에 유용하며, 작업 후 정리 과정을 자동화.
    • v tikkle-mysql-volume:/fromtikkle-mysql-volume이라는 Docker 볼륨을 컨테이너의 /from 디렉토리에 마운트합니다. 이 볼륨에는 복사하려는 데이터가 들어 있습니다.
    • v test-volume:/totest-volume이라는 또 다른 Docker 볼륨을 컨테이너의 /to 디렉토리에 마운트합니다. 이 볼륨은 복사된 데이터를 받을 대상입니다.
    • alpine: 사용할 Docker 이미지. Alpine은 경량화된 Linux 배포판으로, 간단한 작업에 적합하다.
    • ash -c:ash는 Alpine Linux에 내장된 셸입니다. c 옵션은 뒤따르는 문자열에 포함된 명령어를 실행하도록 지시합니다.
    • "cd /from && cp -a . /to"cd /from은 컨테이너 내에서 /from 디렉토리(즉, tikkle-mysql-volume 볼륨)로 이동합니다. &&는 첫 번째 명령어가 성공적으로 실행된 후에 뒤따르는 명령어를 실행하도록 합니다. cp -a . /to는 /from 디렉토리에 있는 모든 파일과 하위 디렉토리(.)를 재귀적으로(-a/to 디렉토리(즉, test-volume 볼륨)로 복사합니다.
  • init.sql을 copy하는 부분을 제거하고 image를 build

    # Dockerfile
    
    # MySQL 이미지를 기반으로 이미지 생성
    FROM mysql:5.7.12
    
    # 환경 변수 설정
    ENV LC_ALL C.UTF-8
    
    # 포트 설정 (기본 MySQL 포트는 3306)
    EXPOSE 3306
    docker build -t volume-test .
  • 해당 이미지로 test-volume을 마운트하여 도커 실행

    docker run --name volume-test-container -v test-volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=[비밀번호] -p 3307:3306 -d volume-test

    위와 같이 정상적으로 데이터가 복원된것을 확인할 수 있다.

3. 스크립트 만들기

위에서 테스트한 복사과정을 아래와 같이 스크립트로 만들 수 있다.

backup.sh

#!/bin/bash

# Docker 볼륨 이름
SOURCE_VOLUME="tikkle-mysql-volume"

# 백업 볼륨 이름
TARGET_VOLUME="backup-volume"

# 기존 백업 볼륨이 있으면 삭제
if docker volume ls | grep -q $TARGET_VOLUME; then
    docker volume rm $TARGET_VOLUME
fi

# 새로운 볼륨 생성
docker volume create --name $TARGET_VOLUME

# 데이터 복사
docker run --rm -v $SOURCE_VOLUME:/from -v $TARGET_VOLUME:/to alpine ash -c "cd /from && cp -a . /to"

4. cron job 설정하기

리눅스 크론탭(Linux Crontab) 사용법 :: JDM's Blog

  1. 스크립트 저장: 위 스크립트를 backup.sh 파일로 저장

  2. 실행 권한 부여chmod +x /path/to/backup.sh 명령으로 스크립트에 실행 권한을 부여

    **chmod +x [backup.sh파일 경로]**
  3. Cron 작업 추가crontab -e를 사용하여 2일마다 스크립트가 실행되도록 Cron 작업을 설정

    0 0 */2 * * /path/to/backup.sh

좀 더 정교하게 할 시간이 있다면….

Docker 환경에서 MySQL 볼륨을 주간으로 복사하고 매일 스냅샷을 찍어 일주일간 보관하는 전체 스크립트는 다음과 같이 구성할 수 있습니다. 이 스크립트는 주간으로 새로운 볼륨에 데이터를 복사하고, 매일의 데이터 상태를 스냅샷으로 보관하며, 일주일 이상된 스냅샷을 자동으로 삭제합니다.

#!/bin/bash

# 백업 파일 저장 경로 (호스트 시스템 기준)
BACKUP_PATH="/path/to/backup"
SNAPSHOT_PATH="/path/to/snapshot"

# 현재 날짜
DATE=$(date +\%F)

# Docker 볼륨 이름
SOURCE_VOLUME="tikkle-mysql-volume"
TARGET_VOLUME="backup-volume-$DATE"

# 매주 월요일에 새 볼륨 생성 및 데이터 복사
if [ $(date +%u) -eq 1 ]; then
    # 기존 백업 볼륨 확인 및 삭제
    if docker volume ls | grep -q $TARGET_VOLUME; then
        docker volume rm $TARGET_VOLUME
    fi

    # 새로운 볼륨 생성
    docker volume create --name $TARGET_VOLUME

    # 데이터 복사
    docker run --rm -v $SOURCE_VOLUME:/from -v $TARGET_VOLUME:/to alpine ash -c "cd /from && cp -a . /to"
fi

# 매일 스냅샷 생성
rsync -a --delete /var/lib/docker/volumes/$SOURCE_VOLUME/_data/ "$SNAPSHOT_PATH/snapshot-$DATE"

# 일주일 이상된 스냅샷 삭제
find "$SNAPSHOT_PATH" -type d -name "snapshot-*" -mtime +7 -exec rm -rf {} \;

스크립트 설명

  • 볼륨 복사: 매주 월요일에 원본 볼륨(tikkle-mysql-volume)의 데이터를 새로운 볼륨(backup-volume-$DATE)으로 복사합니다.
  • 스냅샷 생성: 매일 원본 볼륨의 현재 상태를 스냅샷 디렉토리(snapshot-$DATE)에 복사합니다.
  • 스냅샷 삭제: 일주일 이상된 스냅샷 디렉토리를 삭제하여 공간을 확보합니다.

스크립트 실행 및 관리

  1. 스크립트 저장: 위 스크립트를 backup.sh 파일로 저장합니다.

  2. 실행 권한 부여: chmod +x 명령으로 스크립트에 실행 권한을 부여합니다.

    chmod +x /home/ubuntu/backup.sh
  3. Cron 작업 설정: crontab -e를 사용하여 매일 자정에 스크립트가 실행되도록 Cron 작업을 설정합니다.

    0 0 */2 * * /home/ubuntu/backup.sh

profile
세상에 필요한 것을 고민하고 그것을 만드는 과정에서 문제를 해결하는 일이 즐겁습니다. 창업, 백엔드, RAG에 관심을 가지고있습니다.

0개의 댓글