การ Backup ฐานข้อมูล MySQL ไปเก็บไว้บน Amazon S3

Screen Shot 2556-01-29 at 10.17.29 AM

เรื่องก็มีอยู่ว่าอยากจะทำการ backup ฐานข้อมูลทั้งหมดของ MySQL ไปเก็บไว้นอก database server ซึ่งปกติก็มักจะเป็น backup server ที่เราจัดหาไว้สำหรับ backup ข้อมูลภายในองค์กร แต่การจะจัดซื้อ server สักเครื่องก็ไม่ใช่เรื่องง่าย เพราะเงินไม่ใช่ของเรา วิธีการที่ง่ายกว่าคือหาพื้นที่ข้างนอกที่ให้ใช้งานฟรี หรือเช่าพื้นที่ข้างนอกซึ่งจะใช้เงินลงทุนน้อยกว่า และอาจจะทำให้เจ้าของเงินตัดสินใจได้ง่ายขึ้นด้วย

พอคิดแบบนี้ แวบแรกนึกไปถึง Dropbox แต่คิดได้ว่า Dropbox เองก็ใช้ Amazon S3 อีกต่อนึง และเคยมีข้อมูลผ่านตาอยู่บ่อยๆว่ามี library ในการจัดการไฟล์ใน S3 อยู่มากมายคิดแล้วก็เลย Google ดู และไปเจอว่า มีคนทำไว้แล้ว บทความนี้เลยขอลอก script เค้ามาทดสอบเอาดื้อๆ แต่ตอนใช้งานจริงข้อมูลที่ copy/paste จากในเว็บนั้นเพี้ยน เช่นอักขระบางตัว รวมไปถึง indent ของ Python ซึ่งทำให้ script ที่ลอกมานั้นทำงานไม่ได้ จึงต้องมีการแก้ไขนิดหน่อย ถ้าไม่อยากพิมพ์เอง ก็สามารถ download script mysql_to_s3.py ไปใช้งานได้

เรื่องของวิธีการใช้ Amazon S3 คงไม่ขออธิบายในบทความนี้เพราะบทความจะยาวเกินไป ลองศึกษาได้จาก Amazon S3 – The Beginner’s Guide

Database server ที่ใช้ทดสอบนี้เป็น Debian Linux ถ้าหากใช้ platform อื่นก็สามารถประยุกต์ไปใช้ได้ไม่ยาก และอาจต้องมีการแก้ไข script mysql_to_s3.py บ้างนิดหน่อยในบรรทัดที่ 10-14 โดยอาจจะ hard code username password และ hostname เข้าไปเลยก็ได้

สิ่งที่ต้องการจาก Amazon S3 คือ

  1. Access Key ID
  2. Secret Access Key
  3. ชื่อของ bucket ซึ่งเราต้องเข้าไปสร้างไว้ก่อน

สำหรับ Access Key ID และ Secret Access Key  ให้เข้าไปที่เมนู Security Credentials

001

เลื่อนลงไปในส่วนของ Access Credentials เพื่อไปลอกค่าทั้งสองมา

002

ใน database server สร้างไฟล์ชื่อ ~/.boto โดยใส่ข้อมูลของ Access Key ID และ Secret Access Key ที่ได้มาในข้างต้น

003

จากนั้นเข้าไปที่เมนู AWS Management Console แล้วเลือก S3

004

ใน S3 Management Console เลือก  Create Bucket

005

ใส่ชื่อที่ต้องการ แต่ชื่อนี้ต้องเป็น unique ภายในระบบของ S3 ทั้งหมด ไม่ใช่เฉพาะ account ของเราเอง คล้ายๆกับการจด domain name ถ้าตั้งชื่อซ้ำกับคนอื่นจะไม่สามารถใช้ได้ แนะนำว่าอาจจะใช้เป็นชื่อ email หรือ domain name ของเราซึ่งน่าจะ unique การตั้งชื่อทั่วๆไปมีแนวโน้มที่จะซ้ำกับคนอื่นค่อนข้างมาก ดังตัวอย่างด้านล่าง

007 006

เมื่อสร้างเสร็จแล้ว จะสามารถคลิกเข้าไปดูใน bucket ได้ ซึ่งในตอนแรกจะไม่พบไฟล์อะไร ตัว bucket เองก็จะคล้ายๆ folder ใน Windows แต่เราสามารถกำหนดในเรื่องของ Permissions Logging Notifications และอีกหลายความสามารถซึ่งจะไม่พูดถึงในบทความนี้

008  009

ทำการติดตั้ง boto ซึ่งเป็น Python library สำหรับใช้งาน Amazon AWS

$ sudo aptitude show python-boto
Package: python-boto
State: not installed
Version: 1.9b-1ubuntu3
Priority: optional
Section: python
Maintainer: Ubuntu Developers <ubuntu-devel@lists.ubuntu.com>
Uncompressed Size: 1,430k
Depends: python (>= 2.4), python-support (>= 0.90.0)
Provides: python2.6-boto
Description: Python interface to Amazon's Web Services
 Boto is a Python interface to the infrastructure services available from Amazon.

 Boto supports the following services:
 * Elastic Compute Cloud (EC2)
 * SimpleDB
 * Simple Storage Service (S3)
 * CloudFront
 * Simple Queue Service (SQS)
 * Elastic MapReduce
 * Relational Database Service (RDS)
Homepage: http://code.google.com/p/boto/

ติดตั้งโดยใช้คำสั่ง

$sudo aptitude install python-boto

จากนั้นสร้าง python script ชื่อ mysql_to_s3.py  และอย่าลืมแก้ชื่อ bucket ในบรรทัดที่ 8 ด้วย

#!/usr/bin/env python
import ConfigParser
import os
import time
import boto

s3 = boto.connect_s3()
bucket = s3.get_bucket('nontster.com')

config = ConfigParser.ConfigParser()
config.read("/etc/mysql/debian.cnf")
username = config.get('client', 'user')
password = config.get('client', 'password')
hostname = config.get('client', 'host')

filestamp = time.strftime('%Y-%m-%d')

database_list_command = "mysql -u %s -p%s -h %s -s -N -e 'show databases'" % (username, password, hostname)

for database in os.popen(database_list_command).readlines():
database = database.strip()
if database == 'information_schema':
continue
filename = "/backups/mysql/%s-%s.sql" % (database, filestamp)
print "Backing up %s database" % database
os.popen("mysqldump -u %s -p%s -h %s -e --opt -c %s | gzip -c > %s.gz" % (username, password, hostname, database, filename))
newdir = bucket.new_key(filestamp)
virtualpath = filestamp + "/" + filename + ".gz"
newfile = bucket.new_key(virtualpath)
hddpath =  filename + ".gz"
newfile.set_contents_from_filename(hddpath)

สร้าง directory สำหรับเก็บ backup file บน local server ถ้าหากต้องการเปลี่ยน ให้เปลี่ยนที่ script บรรทัด 24 ด้วย

$ sudo mkdir -p /backups/mysql/

ทดลอง run script โดยใช้คำสั่ง

$ sudo python mysql_to_s3.py
Backing up cloud database
Backing up cloud_usage database
Backing up mysql database

010

ถ้าหากต้องการตั้งให้ script  ทำงานอัตโนมัติ ทุกวันให้ copy script ไปไว้ใน /root/scripts และเปลี่ยน mode ของไฟล์เพื่อให้ execute ได้

$sudo chmod +x /root/scripts/mysql_to_s3.py

พิมพ์ sudo contrab -e แล้วใส่ข้อมูลดังนี้ เพื่อให้ script ทำงานตอนตีสี่ครึ่งของทุกๆวัน

30 4 * * * /root/scripts/mysql_to_s3.py > /dev/null 2>&1

คัดลอกไฟล์ ~/.boto ไปไว้ที่ /root/.boto

$sudo cp ~/.boto /root/.boto

ตรวจสอบว่า script ทำงานตามเวลาที่กำหนดจริงๆ

$ sudo grep mysql /var/log/syslog.1
Jan 29 04:30:01 cloud CRON[18742]: (root) CMD (/root/scripts/mysql_to_s3.py > /dev/null 2>&1)

หากกังวลเรื่องความปลอดภัย ก็สามารถทำการ เข้ารหัสไฟล์ ก่อนส่งไปที่ Amazon S3 ได้ โดยเพิ่ม pipe เข้าไปในบรรทัดที่ 26 ของ script mysql_to_s3.py แต่ควรระวังเรื่องการเก็บ key ไว้ในที่ปลอดภัย และหมั่นตรวจสอบว่ามัน decrypt ได้จริงหรือไม่ ไม่งั้นถึงเวลาจะใช้จริงๆไม่สามารถ decrypt ได้จะเหมือนกับหมาเห็นปลากระป๋อง

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out / เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out / เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out / เปลี่ยนแปลง )

Connecting to %s