본문 바로가기
mysql

웹호스팅의 DB 자동 백업하기

by 씨엔아이소프트 2022. 2. 11.
반응형

출처 : https://asteroid.b-612.net/79

 

 

1. 웹호스팅 서버에서의 설정

웹호스팅 서버에서 원하는 위치에 다음과 같은 php파일을 만든다. 나는 웹 루트 디렉토리에 backup이라는 디렉토리를 새로 만들고, 그 아래에 db_backup.php 파일을 생성했다. 아무나 DB를 가져갈 수 있는 문제를 막기 위해 간단하게 POST 변수를 사용하기로 했다. 페이지에 접근했을 때 POST 방식으로 key 파라미터가 넘어오지 않거나 내가 정한 key값과 다르면 백업이 수행되지 않고 종료되도록 했고, 정상적인 접근이라면 기존 백업파일 삭제 → 새로운 백업 생성 → 새로 생성된 백업파일 주소 json형식으로 출력 과정을 실행하게 된다.

아래 스크립트 코드에는 php의 system 함수를 사용해서 .sql.gz 확장자를 갖는 모든 파일을 삭제하는 부분이 포함되어 있습니다.
실제 운영하는 서버라면 주의해서 사용하시기 바랍니다.
 
<?php
    /* 정상적인 접근인지 확인하고 인증 안되면 빈 데이터 출력 */
    if (!isset($_POST['key'])){
        header('Content-Type: application/json');
        echo json_encode(array("url" => ""));
        die();
    }else{
        if ($_POST['key'] != "/* 내가 정한 인증 키 */"){
            header('Content-Type: application/json');
            echo json_encode(array("url" => ""));
            die();
        }
    }

    /* DB 접속 계정 정보 */
    $DB_HOST = 'localhost'; // DB 서버 주소. 웹호스팅을 이용할 때는 보통 localhost만 사용가능
    $DB_USER = '(DB 아이디)';
    $DB_PASS = '(DB 비밀번호)';
    $DB_NAME = '(데이터베이스 이름)';

    /* 백업 데이터 위치 및 파일명 설정 */
    $BACKUP_PATH = '/free/home/사용자아이디/html/backup'; // 백업파일을 저장할 절대경로
    $BACKUP_NAME = date("Ymd_His").'.sql.gz'; // 백업파일명 (20170219_200101.sql.gz 형태)
    $BACKUP_FILE = $BACKUP_PATH.$BACKUP_NAME;

    /* 기존 백업 파일 삭제 */
    system("rm ".$BACKUP_PATH."*.sql.gz"); 

    /* MySQL Dump 시작 */
    system("mysqldump -h$DB_HOST -u$DB_USER -p$DB_PASS $DB_NAME /* 백업할테이블1 백업할테이블2... */ --opt | gzip > $BACKUP_FILE");
    // 데이터베이스의 모든 테이블을 백업하고 싶을 때는 백업할 테이블 이름을 비워두면 된다.

    /* 결과 리턴 */
    header('Content-Type: application/json');
    echo json_encode(array("url" => "http://example.com/backup/".$BACKUP_NAME));
?>

 

이제 이 스크립트를 브라우저에서 접근하게 되면 POST 변수가 없으므로 빈 데이터가 반환되고,  {"url":""} curl을 사용하든 form을 사용하든 POST 방식으로 내가 정한 key 를 제대로 전송하면 백업파일의 주소가 반환된다. {"url":"http://example.com/db_backup.sql.gz"} 참고로 소스코드에서, 굳이 DB백업을 gzip으로 압축하는 이유는 웹호스팅에서 sql 파일의 전송을 막고 있기 때문이다. 사용하고 있는 웹호스팅서비스에서는 테스트해보니 sql 파일을 생성하고 다운받으려고 하면 에러 페이지로 자동으로 리다이렉트됐다.

 

2. 서버에서의 설정

서버에서 할 일은 1번에서 만든 php에 올바른 key 값을 POST 형식으로 전송해서 백업된 파일의 주소를 받고, 이 주소를 이용해 백업파일 데이터를 받아 서버의 원하는 위치에 저장하는 것이다. 이 과정을 수행할 PHP 스크립트를 만들고, crontab 을 이용해서 주기적으로 실행해 백업을 자동으로 수행하게 한다.

 

파일명은 backup_from_remote.php 로 했다. 주의할 점은, 스크립트로 실행할 것이므로 첫줄에 #!/usr/bin/php 를 입력해서 php를 통해 이 스크립트를 실행해야 한다고 알려주어야 하고 파일 작성이 끝난 뒤에는 스크립트 파일에 실행 권한을 주어야 한다는 것이다. 스크립트 파일이 있는 위치에서 아래 명령어를 입력하면 된다.

chmod +x backup_from_remote.php

 

물론 이렇게 하지 않고 그냥 크론탭에 등록할 때 /usr/bin/php (스크립트 경로/스크립트파일.php)  이런식으로 등록해도 된다. 취향대로.

 

#!/usr/bin/php
<?php
    // 인증을 위해 POST 형식으로 보낼 파라미터를 설정한다.
    $post_data = array("key" => "(아까 정한 key값)");
    
    // curl을 이용해 데이터를 받아올 예정이다.
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://(백업스크립트가 있는 도메인)/db_backup.php");
    // 웹호스팅 서비스에서 스크립트를 이용한 접근을 막고 있으므로 유저에이전트를 설정해서 사람이 접근하는 것처럼 보이게 한다.
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); // POST 전송
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $json = curl_exec($ch);
    $data = json_decode($json, true); // 실행 및 변수에 결과 저장

    // 결과데이터에 백업 url이 있을 경우에만 실행
    if ($data['url'] != ""){
        // 슬래시(/)를 기준으로 나누어서 파일명만 추출한다.
        $arr = explode("/",$data['url']);
        $filename = $arr[count($arr)-1];

        // 다시 curl을 이용해서 백업 url에 있는 백업 파일을 가져온다.
        $ch = curl_init();
        curl_setopt($ch, CUdRLOPT_URL, $data['url']);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $dump = curl_exec($ch);

        // 가져온 백업 데이터를 원하는 위치에 저장하고 압축을 푼다
        file_put_contents("/free/home/사용자아이디/html/backup/".$filename,$dump);
        system("gzip -d /free/home/사용자아이디/html/backup/*.gz");
        // (선택) 백업된 데이터를 서버의 데이터베이스에 복원한다.
        system("mysql -u(아이디) -p(비밀번호) (복원대상 데이터베이스 이름) < (백업이 존재하는 절대경로) + "/".str_replace(".gz","",$filename));
    }else{
        echo "DB 백업시 오류가 발생했습니다.";
    }
?>

 

 

크론탭 설정

크론탭 설정 (데비안에서는 쉘에서 crontab -e 를 입력하면 된다) 에서 아래 내용을 추가하고 저장한다.

0   23  *   *   0   /(스크립트절대경로)/backup_from_remote.php

 

 

모든 과정이 완료되었다. 이제 매주 일요일 오후 11시에 웹호스팅에 있는 DB는 자동으로 백업되어 내 서버로 저장되고, 내 서버 DB에도 자동으로 복원되어 같은 데이터베이스를 사용할 수 있게 되었다.

반응형

댓글