본문 바로가기
Dev/ETC

Jenkins(Pipeline)를 이용한 DB 백업

by nakanara 2020. 2. 17.
반응형

백업용 Docker 위의 MariaDB 데이터 덤프 파일이 필요하여 Jenkins의 Pipeline와 sh을 이용하여 일 덤프 파일 생성 스크립트.

(업데이터 이전의 pipeline로 만든 스크립가 플러그인 업데이트하면서 오작동하여 수정하는데 좀 걸림 ㅜ)

  1. Jenkins에서 특정 시간에 실행하도록 pipeline 설정
  2. 시작 및 오류에 대해서 Slack 메시지 전송
  3. 파일 생성 후 특정 디렉터리로 이동(오래된 파일 삭제)
node {

  env.SERVER="remort-serv" /* 접속 서버 ssh 설정 */

  /* docker 접속해서 dumpimpl 실행 및 오래 된 파일 삭제 스크립트 */
  env.BACKUP_SH_PATH="/home/user/conf/db_backup.sh" 

  /* 덤프 파일 명을 위한 생성 일시 */
  env.CURTIME = sh(returnStdout: true, script: "date +%Y%m%d%H%M%S").trim() 
  env.BACKUP_FILE="${CURTIME}.sql" 

  env.DUMP_KEEP_DAY="10" /* 데이터 보유 일 */
  env.APP_ID  ="app"  /* APP ID */
  env.APP_PATH="webapps"  /* 경로 */
  env.DB_ID   ="mariadb" /* 도커 ID */

  /* 메세지 전송 슬랙 채널 */
  env.SLACK_CHANNEL = "#build"    

  try{

    slackSend channel: "${SLACK_CHANNEL}", color: "good", message: "Job: ${JOB_NAME} with buildnumber ${BUILD_NUMBER} 데이터 백업이 시작되었습니다."

    stage('SERVICE') {

      slackSend channel: "${SLACK_CHANNEL}", color: "good", message: "DB 백업 시작 ${SERVER} 서비스:${APP_ID}"      
      try {
        sh '''
          echo ${BACKUP_SH_PATH} ${APP_PATH} ${DB_ID} ${APP_ID}_${BACKUP_FILE} ${DUMP_KEEP_DAY}
          ssh ${SERVER} "${BACKUP_SH_PATH} ${APP_PATH} ${DB_ID} ${APP_ID}_${BACKUP_FILE} ${DUMP_KEEP_DAY}"
        '''
        /*
        * 해당 sh 파일에는 docker 에 접속해서 mysqldump 생성
        * docker exec ${DOCKER_DB} bash -c " cd ${DOCKER_BACKUP_PATH}; /usr/bin/mysqldump -u ${DB_ID} -p${DB_PW} --single-transaction --routines --databases ${DB_NAME}  > ${BACKUP_FILE} "
        */

        slackSend channel: "${SLACK_CHANNEL}", color: "good", message: "DB 백업 성공 ${SERVER} 서비스:${APP_ID}"
      } catch (e) {          
        slackSend channel: "${SLACK_CHANNEL}", color: "danger", message: "DB 백업 실패 ${SERVER} ${APP_ID} ${APP_ID}_${BACKUP_FILE} ${DUMP_KEEP_DAY} // ${e}"
      }        

    }

  } catch(err){
      slackSend channel: "${SLACK_CHANNEL}", color: "danger", message: "Job: ${JOB_NAME} with buildnumber ${BUILD_NUMBER} 데이터 백업에 실패하였습니다. ${err}"
  } finally {
      slackSend channel: "${SLACK_CHANNEL}", color: "good", message: "Job: ${JOB_NAME} with buildnumber ${BUILD_NUMBER} 데이터 백업이 종료되었습니다."
  }

}

데이터 백업 스크립트 (db_backup.sh)

echo DB Backup


echo APP_PATH=${1}
echo DOCKER_NAME=${2}
echo BACKUP_FILE=${3}
echo DUMP_KEEP_DAY=${4}

# 서비스 ID
# export APP_PATH=prod_sv 
export APP_PATH=${1} 
# Docker Contener name
# export DOCKER_DB=prod_db
export DOCKER_DB=${2}

# var
export BACKUP_FILE=${3}
export DUMP_KEEP_DAY=${4}

# 백업 저장 경로
export SQL_BACKUP_PATH=~/data/backup/${APP_PATH}
# 서비스 홈 경로
export APP_HOME=/home/user/${APP_PATH}
# 도커 DB 경로
export DOCKER_BACKUP_PATH=/var/lib/mysql

# database name
export DB_NAME=db
export DB_ID=user
export DB_PW=password
export DB_DATA_PATH=${APP_HOME}/mariadb

# 백업 경로가 없는 경우
if [ ! -d ${SQL_BACKUP_PATH} ]
  then mkdir ${SQL_BACKUP_PATH}
fi

echo ### Start dump
# https://www.lesstif.com/pages/viewpage.action?pageId=17105804
docker exec ${DOCKER_DB} bash -c " cd ${DOCKER_BACKUP_PATH}; /usr/bin/mysqldump -u ${DB_ID} -p${DB_PW} --single-transaction --routines --databases ${DB_NAME}  > ${BACKUP_FILE} "

# --single-transaction: 하나의 트랜젝션에서 덤프. 데이터 일괄성
# --routine: 프로시저와 함수 덤프
# --triggers: 트리거 덤프 (기본적으로 덤프)

# --all-databases: 모든 데이터베이스 덤프
# --databases: 특정 데이터 베이스 덤프

echo ### move Backup file > ${DB_DATA_PATH}/${BACKUP_FILE} to ${SQL_BACKUP_PATH}

# 백업 파일 이동
mv ${DB_DATA_PATH}/${BACKUP_FILE} ${SQL_BACKUP_PATH}

if [ "${DUMP_KEEP_DAY}" -gt 0  ] 
then
  echo "delete old files Over ${DUMP_KEEP_DAY}"
  echo "cd ${SQL_BACKUP_PATH}"
  cd ${SQL_BACKUP_PATH}
  pwd
  echo "find . -name '*.sql' -mtime +${DUMP_KEEP_DAY} -delete"
  find . -name "*.sql" -mtime "+${DUMP_KEEP_DAY}" -delete
fi

echo ### End dump
반응형