[Tutorial] how to dump and restore postgresql from production env on AWS EC2 for Rails

自從機器從 heroku 搬到 AWS 上後,資料庫的備份再也不是容易的事情惹,中間牽扯到 firewall, VPC, postgresql version 等等的問題,有點被 heroku 寵壞。過了一年多,終於有時間好好正視這個問題處理一下,不然常常很多特殊交易狀況都無法在開發環境被還原。

雖然找到許多的 gem 可以協助做這件事情,但用起來都不符合需求,後面再來提。最後還是用最土砲的方式:rake task 加上 postgresql cli 搞定。

資料庫版本

第一個會遇到的問題是資料庫版本不符合,RDS 用的 postgresql 是 9.5,但透過 opsworks 建的 ubuntu 環境 postgresql 是 9.3,便沒辦法正常使用 pg_dump。這部分可以參考這篇文章 upgrade postgresql on ubuntu

備份指令

關於指令部分可以參考這份 gist,有做過兩個特別處理:

  1. 針對 production 環境若誤下 restore 指令不會生效,做基本的預防
  2. 在資料庫的 username 設定,如果 database.yml 沒有設定會自動以自己機器的 username 為主

如何下載

當作完以上 db.rake 設定後,只要下 rake db:dump 就會開始備份跑出一個 {app name}.dump 檔案,這時就要開始煩惱下載的問題。

這部分有非常多解法,像是 ftp, scp, rsync, http server 等等,但會遇到這問題的通常資料庫都是上 GB 的功能。這邊測試後 rsync 的速度會最快,甚至差到 10 倍以上,如下:

rsync -ravc --delete --verbose --progress --stats --compress source_path destination_path 
# --compress 這參數很重要,加速的關鍵
# 路徑的下法跟 scp 一樣,例如 ubuntu@123.321.1.23:/home/ubuntu/xxx

下載完後便可使用 rake db:restore 做到還原惹!

其他作法

這邊有兩個 gem 也可以推薦用來作為還原資料庫的方式:

seed_bump

第一個是 seed_bump,它是會把資料庫整個 dump 成 db/seeds.rb 檔案,裡面都是 ActiveRecord 的指令。實際做過的心得是,小資料庫(大概幾百 MB 那種)可以,但再大的話完全不建議。

Polo

另個是 polo,由 IFTTT 這個擅於串接各方服務團隊所做的套件。這個比較像是根據實際資料庫內容,模擬幾筆很像的資料出來,若資料庫沒有太複雜的商業邏輯(如簡單的 CMS 平台)會蠻推薦的。