Backup 젬과 Whenever 젬을 이용한 서버 백업 자동화

backup젬과 whenever젬을 이용하여 데이터베이스 백업을 자동화하기.

레일스 프로젝트를 원격 서버로 배포후 제대로 동작하는 것이 확인되면 우선적으로 데이터베이스와 사용자들이 업로드한 파일들을 주기적으로 백업해야 한다.

여러가지 방법이 있지만 이 글에서는 가장 흔히들 사용하는 backup 젬과, crontab 스크립트를 편리하게 작업할 수 있게 해 주는, whenever 젬을 이용하는 방법에 대해서 필자의 짧은 경험과 함께 소개할 것이다.

(1) Backup 젬

backup 젬은 프로젝트의 gemfile로 설치하지 않고 직접 원격 서버에서 설치한다. 물론 레일스 애플리케이션이 서비스되는 서버에는 이미 루비환경이 설치되어 있게 때문에 ssh로 접속한 후 아래와 같은 명령으로 간단하게 설치할 수 있다.

$ gem install backup

이제 커맨드라인에서 backup 명령을 실행하면 아래와 같이 사용법에 대한 도움말을 볼 수 있다.

$ backup
Commands:
  backup check                                      # Check for configuration errors or warnings
  backup generate:config                            # Generates the main Backup configuration file
  backup generate:model -t, --trigger=TRIGGER       # Generates a Backup model file.
  backup help [COMMAND]                             # Describe available commands or one specific command
  backup perform -t, --triggers, --trigger=TRIGGER  # Performs the backup for the specified trigger(s).
  backup version                                    # Display installed Backup version

backup에서는 model이라는 용어를 사용하여 하나의 백업 작업을 정의한다. 따라서 위의 5번째 라인의 명령과 몇가지 옵션을 추가해서 아래와 같이 백업작업을 정의한다.

$ backup generate:model --trigger=daily_db_backup --databases='mysql' --storages='local' --compressor='gzip' --notifiers='mail'
Generated configuration file: '/home/[user_account]/Backup/config.rb'.
Generated model file: '/home/[user_account]/Backup/models/daily_db_backup.rb'.

옵션설명

--trigger : 모델명을 지정한다.

--databases : 데이터베이스명을 지정한다. ex) MySQL, PostgreSQL, MongoDB, Redis, Riak, SQLite

--storages : 백업저장 위치를 지정한다. ex) Amazon S3, Rackspace Cloud Files, Ninefold, Dropbox, FTP, SFTP, SCP, RSync, Local

--compressor : 데이터 압축프로그램을 지정한다. ex) Gzip, Bzip2, xz

--notifiers : 백업작업 완료시 결과를 알려주는 툴을 지정한다. ex) Email (SMTP, Sendmail, Exim and File delivery), Twitter, Campfire, Prowl, Hipchat, Pushover, Nagios, HTTP POST (compatible with a variety of services), Zabbix

위의 명령 실행결과 Backup이라는 폴더에 아래와 같은 파일들이 생성된다.

$ tree Backup
Backup
├── config.rb
└── models
    └── daily_db_backup.rb

1 directory, 2 files

모델 파일(daily_db_backup.rb)을 열고 자신의 서버 환경에 맞게 옵션을 변경한다.

# encoding: utf-8

##
# Backup Generated: daily_db_backup
# Once configured, you can run the backup with the following command:
#
# $ backup perform -t daily_db_backup [-c <path_to_configuration_file>]
#
# For more information about Backup's components, see the documentation at:
# http://backup.github.io/backup
#
Model.new(:daily_db_backup, 'Description for daily_db_backup') do

  ##
  # MySQL [Database]
  #
  database MySQL do |db|
    # To dump all databases, set `db.name = :all` (or leave blank)
    db.name               = "my_database_name"
    db.username           = "my_username"
    db.password           = "my_password"
    db.host               = "localhost"
    db.port               = 3306
    # db.socket             = "/tmp/mysql.sock"
    # Note: when using `skip_tables` with the `db.name = :all` option,
    # table names should be prefixed with a database name.
    # e.g. ["db_name.table_to_skip", ...]
    # db.skip_tables        = ["skip", "these", "tables"]
    # db.only_tables        = ["only", "these", "tables"]
    db.additional_options = ["--quick", "--single-transaction"]
  end

  ##
  # Local (Copy) [Storage]
  #
  store_with Local do |local|
    local.path       = "~/backups/"
    local.keep       = 5
  end

  ##
  # Gzip [Compressor]
  #
  compress_with Gzip

  ##
  # Mail [Notifier]
  #
  # The default delivery method for Mail Notifiers is 'SMTP'.
  # See the documentation for other delivery options.
  #
  notify_by Mail do |mail|
    mail.on_success           = true
    mail.on_warning           = true
    mail.on_failure           = true

    mail.from                 = "sender@email.com"
    mail.to                   = "receiver@email.com"
    mail.address              = "smtp.gmail.com"
    mail.port                 = 587
    mail.domain               = "your.host.name"
    mail.user_name            = "sender@email.com"
    mail.password             = "my_password"
    mail.authentication       = "plain"
    mail.encryption           = :starttls
  end

end

위의 소스 코드에서 19번 라인의 db.name 속성값은 18번 라인의 코멘트와 같이 :all을 지정하여 모든 데이터베이스를 한꺼번에 백업할 수도 있다. 여기서는 불필요한 24번 코드라인을 코멘트 처리하였고, 28, 29번 코드라인은 전체 데이터베이스를 백업할 것이기 때문에 사용할 필요가 없어서 코멘트 처리하였다.

여기서는 project1_production이라는 데이터베이스를 백업하는 것으로 가정한다. 따라서 db.name 값을 project1_production으로 지정한다.

위에서 설명한 바와 같이 모델을 작성하는 커맨드라인을 다시 한번 상기해 보자.

$ backup generate:model --trigger=daily_db_backup --databases='mysql' --storages='local' --compressor='gzip' --notifiers='mail'

--storages='local'은 백업을 저장할 매체를 지정하는 것인데, 여기서는 local, 즉, 동일한 서버에 저장하겠다는 의미이다. 언급한 바와 같이 scp를 지정하여 다른 서버로 백업본을 저장할 수도 있다.

--nofifiers='mail'은 백업 결과를 알려주는 매체를 지정한다. mail로 지정하면, 백업 결과를 이메일로 발송해 준다.

리눅스 서버의 sendmail 기능을 이용하면 구글 SMTP 서비스를 사용하지 않아도 된다. 위의 모델 파일에서 59~65 코드라인을 코멘트 처리하고 아래의 코드라인을 추가한다.

mail.delivery_method = :sendmail

이제부터는 백업이 실행되면 서버의 sendmail 기능을 이용하여 메일을 발송하게 된다.

지금까지 변경한 내용을 반영한 모델 파일의 내용은 아래와 같다.

# encoding: utf-8

##
# Backup Generated: daily_db_backup
# Once configured, you can run the backup with the following command:
#
# $ backup perform -t daily_db_backup [-c <path_to_configuration_file>]
#
# For more information about Backup's components, see the documentation at:
# http://backup.github.io/backup
#
Model.new(:daily_db_backup, 'backups project1_production database') do

  ##
  # MySQL [Database]
  #
  database MySQL do |db|
    # To dump all databases, set `db.name = :all` (or leave blank)
    db.name               = "project1_production"
    db.username           = "[account-name]"
    db.password           = "[account-pass]"
    db.host               = "localhost"
    db.port               = 3306

    db.additional_options = ["--quick", "--single-transaction"]
  end

  ##
  # Local (Copy) [Storage]
  #
  store_with Local do |local|
    local.path       = "~/backups/"
    local.keep       = 5
  end

  ##
  # Gzip [Compressor]
  #
  compress_with Gzip

  ##
  # Mail [Notifier]
  #
  # The default delivery method for Mail Notifiers is 'SMTP'.
  # See the documentation for other delivery options.
  #
  notify_by Mail do |mail|
    mail.on_success           = true
    mail.on_warning           = true
    mail.on_failure           = true

    mail.delivery_method      = :sendmail
    mail.from                 = "sender@email.com"
    mail.to                   = "receiver@email.com"

  end

end

자, 이제, 서버의 커맨드라인에서 아래와 같이 백업 명령을 실행해 보자.

$ backup perform -t daily_db_backup

제대로 동작했다면 서버의 /home/[account-name]/backups/ 폴더에 백업 파일이 저장되고 결과가 메일로 발송되었을 것이다. 추가로 백업 명령의 로그를 저장하고 싶을 때는 아래와 같이 옵션을 추가할 수 있다.

$ backup perform -t daily_db_backup >> /home/[user-account]/Backup/config/cron.log 2>&1

(2) Whenever 젬

다음은 마지막으로 실행한 명령을 시스템 cron job으로 등록해 보도록 하자. 여기서는 cron job 설정을 편리하게 하기 위해서 whenever 젬을 사용하기로 한다. 이를 위해서 서버로 접속한 후 아래와 같이 whenever 젬을 시스템에 설치한다.

$ gem install whenever

그리고 Backup 디렉토리로 이동한 후 config 디렉토리를 생성한다. whenever 젬에서 필요로로 하는 파일을 생성하기 위해서 아래와 같이 명령을 수행한다.

$ wheneverize .

위의 명령을 실행하여 생성된 config/schedule.rb 파일을 열고 아래와 같이 수정한다.

every 1.day, :at => '12:00 am' do
  command "backup perform -t daily_db_backup >> /home/[user-account]/Backup/config/cron.log 2>&1"
end

즉, 매일 자정에 백업 작업을 실행하라는 루비 코드를 작성한 것이다.

이제 마지막으로 해야할 일은, 이 스케쥴파일을 실제로 crontab에 반영하기 위해서 crobtab을 업데이트하는 것이다.

$ whenever --update-crontab

그리고 crontab -l 명령으로 제대로 반영되었는지를 확인한다.

(3) 요약

지금까지 설명한 내용을 요약하면, 데이터베이스 덤프파일을 작성하여 압축한 후 특정 매체에 저장하도록 하였고 이 작업을 cron job으로 등록하여 데이터베이스의 자동 백업을 기능을 구현해 보았다.

참고문서

1. Backup a Rails Database With the Backup and Whenever Gems
2. Scheduled Backups with Clockwork and Backup Gem
3. Schedule Cron Jobs with the Whenever Gem

글쓴이: 최효성

외과전문의,웹프로그래밍,컴퓨터 일러스트레이션 / Surgeon, Medical Illustration, Web Programmer

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중