กลยุทธ์ Backup VPS ที่ได้ผลจริง ไม่ให้เสียใจทีหลัง
ไม่มีใครเสียข้อมูลแล้วคิดว่า "ฉันมี backup เยอะเกินไป" แต่มีคนจำนวนมากที่เสียใจว่าทำไมไม่เริ่ม backup ตั้งแต่แรก บทความนี้วางแผน backup ให้ครอบคลุมทุกชั้น
ทำไม Snapshot จาก Provider ไม่เพียงพอ
หลาย VPS provider มี snapshot feature แต่มีข้อจำกัดที่ควรรู้:
- Snapshot ส่วนใหญ่เก็บใน datacenter เดียวกัน — ถ้า datacenter มีปัญหา ทั้งเซิร์ฟเวอร์และ snapshot หายพร้อมกัน
- บาง provider คิดเงิน snapshot ตาม space ที่ใช้
- ไม่สามารถ restore บางไฟล์ได้ ต้อง restore ทั้ง disk เท่านั้น
จึงต้องมี backup strategy หลายชั้นแทน
ชั้นที่ 1: Database Backup ด้วย mysqldump
Database มักเปลี่ยนแปลงเร็วที่สุด ควร backup บ่อยที่สุด
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M)
BACKUP_DIR="/backup/mysql"
mkdir -p $BACKUP_DIR
mysqldump -u root -p"yourpassword" --all-databases \
| gzip > "$BACKUP_DIR/all-db-$DATE.sql.gz"
# เก็บแค่ 7 วันล่าสุด
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
เพิ่มใน crontab ให้รันทุกคืน:
0 2 * * * /usr/local/bin/backup-mysql.sh
ชั้นที่ 2: ไฟล์เว็บด้วย rsync
rsync -avz --delete /var/www/html/ \
backup-server:/backup/webfiles/$(hostname)/
rsync จะส่งแค่ไฟล์ที่เปลี่ยนแปลง ไม่ต้องส่งทั้งหมดทุกครั้ง ประหยัด bandwidth และเวลา
ชั้นที่ 3: Offsite Backup ไปยัง Object Storage
ไฟล์ backup ที่เก็บไว้ในเซิร์ฟเวอร์เดิมยังเสี่ยงอยู่ ควรส่งออกไปที่อื่นด้วย
ใช้ rclone sync ไปยัง S3-compatible storage เช่น Backblaze B2, Cloudflare R2 หรือ AWS S3:
# ติดตั้ง rclone
curl https://rclone.org/install.sh | bash
rclone config # ตั้งค่า remote
# sync backup folder ไปยัง cloud
rclone sync /backup/ remote:my-bucket/backup/
ทดสอบ Restore ด้วย
Backup ที่ไม่เคยทดสอบ restore คือ backup ที่ไม่มีประโยชน์ ควรทดสอบอย่างน้อยทุก 3 เดือน:
- หยิบ backup file ล่าสุด
- restore ลงใน environment แยก (local docker หรือ VPS test)
- ตรวจสอบว่า database เปิดได้ ไฟล์ครบ
Backup ด้วย Script อัตโนมัติรายวัน
Script ต่อไปนี้รวม database backup + file backup + upload ไป rclone ในขั้นตอนเดียว:
#!/bin/bash
# /usr/local/bin/daily-backup.sh
set -euo pipefail
DATE=$(date +%Y%m%d_%H%M)
BACKUP_DIR="/backup/${DATE}"
mkdir -p "$BACKUP_DIR"
# 1. Database backup
mysqldump -u root -p"${MYSQL_PASS}" --all-databases \
--single-transaction --quick \
| gzip > "${BACKUP_DIR}/all-db.sql.gz"
# 2. Web files
rsync -az --delete /var/www/html/ "${BACKUP_DIR}/webroot/"
# 3. Config files
tar -czf "${BACKUP_DIR}/configs.tar.gz" \
/etc/nginx/ /etc/php/ /etc/mysql/ /etc/letsencrypt/ 2>/dev/null || true
# 4. Upload ไป cloud
rclone sync "$BACKUP_DIR" "remote:backup/${DATE}/" --progress
# 5. ลบ backup เก่าเกิน 14 วัน
find /backup -maxdepth 1 -type d -mtime +14 -exec rm -rf {} \;
rclone delete "remote:backup/" --min-age 30d --rmdirs
echo "Backup ${DATE} completed" | mail -s "Backup OK: $(hostname)" [email protected]
เพิ่มใน crontab ให้รันตี 3 ทุกคืน:
0 3 * * * MYSQL_PASS="yourpass" /usr/local/bin/daily-backup.sh >> /var/log/backup.log 2>&1
ตรวจสอบ Backup ที่ส่งขึ้น Cloud
# ดู backup ทั้งหมดใน remote
rclone ls remote:backup/ --max-depth 2
# ดูขนาดรวม
rclone size remote:backup/
# ทดสอบ download backup ล่าสุด
rclone copy "remote:backup/$(date +%Y%m%d)_0300/" /tmp/restore-test/ --progress
ตรวจสอบสุขภาพเซิร์ฟเวอร์และโดเมนก่อน Backup
ก่อนวางแผน backup ควรรู้ก่อนว่าเว็บของคุณมีปัญหาอะไรบ้าง เช่น SSL ใกล้หมดอายุ, DNS ผิดพลาด หรือ Security Headers ไม่ครบ เครื่องมืออย่าง dnsxray.com ช่วยตรวจสอบสุขภาพโดเมนได้ฟรี ก่อนที่ปัญหาเล็ก ๆ จะกลายเป็นเรื่องใหญ่
สำหรับ VPS ในไทยที่มี uptime guarantee และ support ดี ลองเปรียบเทียบแพ็กเกจที่ asiagb.com ซึ่งมีตัวเลือกทั้ง VPS Linux และ Windows
แก้ปัญหาที่พบบ่อย
mysqldump ล้มเหลว: "mysqldump: Got error: 1045: Access denied"
# ตรวจสอบ user และ password
mysql -u root -p -e "SELECT user, host FROM mysql.user;"
# ถ้าใช้ .my.cnf แทน password ใน script
cat ~/.my.cnf
# [client]
# user=root
# password=yourpassword
rclone ส่ง backup ไม่ขึ้นเพราะ authentication หมดอาย
Token ของบาง provider หมดอายุ ให้ re-authenticate:
rclone config reconnect remote:
# หรือลบ config แล้ว setup ใหม่
rclone config
Backup ไฟล์ web ช้ามากเพราะไฟล์เยอะ
ใช้ --exclude ตัดไฟล์ที่ไม่จำเป็นออก:
rsync -az --delete \
--exclude="*.log" \
--exclude="cache/" \
--exclude="tmp/" \
/var/www/html/ "${BACKUP_DIR}/webroot/"
Restore แล้ว database ไม่ขึ้น charset เสีย
ระบุ charset ตอน restore:
gunzip -c all-db.sql.gz | mysql --default-character-set=utf8mb4 -u root -p
คำถามที่พบบ่อย
ควร backup บ่อยแค่ไหน?
ขึ้นกับว่าข้อมูลเปลี่ยนแปลงเร็วแค่ไหน สำหรับเว็บที่อัปเดตทุกวัน backup รายวันก็พอ แต่สำหรับ e-commerce ที่มี transaction ตลอดเวลาควร backup database ทุกชั่วโมงหรือทำ binary log replication ไปยัง server สำรอง
Backup ของ provider กับ backup ที่ทำเองต่างกันอย่างไร?
Backup ของ provider มักเป็น snapshot ทั้ง disk restore ได้เร็วแต่คืนทั้งหมดหรือไม่คืนเลย และมักอยู่ใน datacenter เดิม Backup ที่ทำเองสามารถ restore เฉพาะไฟล์ที่ต้องการและเก็บ offsite ได้ ควรมีทั้งสองแบบ
Backblaze B2 กับ Cloudflare R2 เลือกอะไรดี?
Cloudflare R2 ไม่คิดค่า egress (download) ดีมากถ้า restore บ่อย Backblaze B2 ค่า storage ถูกกว่าเล็กน้อยและมี free tier 10 GB ถ้าต้องการ restore ข้ามประเทศบ่อย R2 ประหยัดกว่า ถ้า store เป็นหลัก B2 อาจถูกกว่า
จะรู้ได้อย่างไรว่า backup ไม่เสียหาย?
ทดสอบ restore เป็นประจำ อย่างน้อยไตรมาสละครั้ง ตรวจสอบ checksum ของไฟล์: md5sum backup.sql.gz แล้วบันทึกค่าไว้ ตรวจสอบซ้ำก่อน restore จะได้รู้ว่าไฟล์ยังสมบูรณ์
สรุป
Backup ที่ดีต้องครอบคลุมหลายชั้น ทดสอบ restore ได้จริง และมีสำเนาอยู่ต่างสถานที่ ลงทุนเวลาสักชั่วโมงในการตั้งระบบ backup วันนี้อาจช่วยประหยัดเวลาเป็นวันหรือเป็นสัปดาห์ในอนาคต