ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

Home สำรองและกู้คืนฐานข้อมูล MySQL/MariaDB ด้วย mysqldump

สำรองและกู้คืนฐานข้อมูล MySQL/MariaDB ด้วย mysqldump

mysqldump เป็นเครื่องมือมาตรฐานที่มากับ MySQL และ MariaDB ใช้ส่งออกฐานข้อมูลเป็นไฟล์ข้อความที่มีคำสั่ง SQL สำหรับสร้างตารางและใส่ข้อมูลกลับเข้าไป ไฟล์นี้นำไปกู้คืนบนเซิร์ฟเวอร์เดิมหรือเครื่องใหม่ได้ เหมาะกับฐานข้อมูลขนาดเล็กถึงกลาง (ระดับไม่กี่ GB) ซึ่งครอบคลุมเว็บไซต์ส่วนใหญ่

ควรสำรองก่อนทุกการเปลี่ยนแปลงสำคัญ เช่น อัปเดตปลั๊กอินหรือเวอร์ชันของแอป ย้ายเซิร์ฟเวอร์ หรือแก้ข้อมูลจำนวนมาก สำหรับผู้ใช้ Plesk ที่ต้องการสำรองทุกฐานข้อมูลในเซิร์ฟเวอร์ ดูเพิ่มที่ วิธี backup ฐานข้อมูล MySQL ทั้งหมดผ่าน command-line บน Plesk Linux

สิ่งที่ต้องเตรียม

  • เข้าเซิร์ฟเวอร์ผ่าน SSH ได้
  • ชื่อผู้ใช้และรหัสผ่านฐานข้อมูลที่มีสิทธิ์อย่างน้อย SELECT, SHOW VIEW, TRIGGER และ LOCK TABLES กับฐานข้อมูลที่จะสำรอง (ผู้ใช้ที่ได้ ALL PRIVILEGES ของฐานข้อมูลนั้นใช้ได้เลย)
  • พื้นที่ดิสก์ว่างมากพอ ตรวจด้วย df -h

บน MariaDB เวอร์ชันใหม่ คำสั่งมีชื่อใหม่ว่า mariadb-dump และ mariadb ส่วน mysqldump และ mysql ยังใช้ได้บน MariaDB 10.x ตัวอย่างในคู่มือใช้ชื่อเดิมเพื่อให้ใช้ได้กับทั้งสองระบบ

ขั้นตอนที่ 1: สำรองฐานข้อมูลเดียว

mysqldump -u shopuser -p --single-transaction --routines --triggers \
  --default-character-set=utf8mb4 shopdb > shopdb-2026-09-19.sql
  • --single-transaction สำรองตาราง InnoDB ในสภาพที่สอดคล้องกัน ณ เวลาเดียว โดยไม่ล็อกตาราง เว็บไซต์จึงทำงานต่อได้ระหว่างสำรอง
  • --routines และ --triggers รวม Stored Procedure, Function และ Trigger ไปด้วย
  • --default-character-set=utf8mb4 ป้องกันภาษาไทยเพี้ยน

ใส่รหัสผ่านเมื่อระบบถาม หากไม่มี Error แสดงว่าสำเร็จ ตรวจท้ายไฟล์ได้ด้วย

tail -n 1 shopdb-2026-09-19.sql

บรรทัดสุดท้ายต้องเป็น -- Dump completed on ... หากไม่มี แปลว่าการสำรองหยุดกลางคัน

สำหรับฐานข้อมูลขนาดใหญ่ ให้บีบอัดไปพร้อมกันเพื่อประหยัดพื้นที่

mysqldump -u shopuser -p --single-transaction --routines --triggers \
  --default-character-set=utf8mb4 shopdb | gzip > shopdb-2026-09-19.sql.gz

หากต้องการสำรองทุกฐานข้อมูลในเซิร์ฟเวอร์ ใช้สิทธิ์ root และ --all-databases แทนชื่อฐานข้อมูล เช่น sudo mysqldump --all-databases --single-transaction --routines --triggers --events | gzip > all-databases.sql.gz

ขั้นตอนที่ 2: กู้คืนฐานข้อมูล

หมายเหตุ: การกู้คืนจะเขียนทับตารางที่มีชื่อเดียวกันในฐานข้อมูลปลายทาง หากฐานข้อมูลนั้นมีข้อมูลที่ยังใช้อยู่ ให้สำรองข้อมูลปัจจุบันเก็บไว้ก่อนเสมอ หรือกู้คืนลงฐานข้อมูลชื่อใหม่เพื่อตรวจสอบก่อน

ไฟล์จาก mysqldump แบบฐานข้อมูลเดียวไม่มีคำสั่งสร้างฐานข้อมูล จึงต้องมีฐานข้อมูลปลายทางก่อน หากยังไม่มีให้สร้างตามคู่มือ สร้างฐานข้อมูลและผู้ใช้ MySQL/MariaDB พร้อมกำหนดสิทธิ์ แล้วกู้คืนด้วย

mysql -u shopuser -p --default-character-set=utf8mb4 shopdb < shopdb-2026-09-19.sql

สำหรับไฟล์ที่บีบอัดไว้

gunzip < shopdb-2026-09-19.sql.gz | mysql -u shopuser -p --default-character-set=utf8mb4 shopdb

คำสั่งจะไม่แสดงอะไรหากสำเร็จ ฐานข้อมูลขนาดใหญ่อาจใช้เวลาหลายนาที ห้ามปิดหน้าต่าง SSH ระหว่างนั้น หากกังวลเรื่องการเชื่อมต่อหลุด ให้รันใน tmux หรือ screen

ขั้นตอนที่ 3: สำรองอัตโนมัติทุกวัน

การใส่รหัสผ่านในคำสั่งตรง ๆ ทำให้ผู้ใช้อื่นบนเครื่องเห็นได้จากรายการโปรเซส ให้เก็บรหัสผ่านในไฟล์ตั้งค่าที่มีเพียงเจ้าของอ่านได้แทน

nano ~/.my.cnf
[mysqldump]
user=shopuser
password=รหัสผ่านของ shopuser
chmod 600 ~/.my.cnf
mkdir -p ~/db-backup

สร้างสคริปต์สำรองที่ลบไฟล์เก่ากว่า 14 วันให้อัตโนมัติ

nano ~/db-backup/backup.sh
#!/bin/bash
set -euo pipefail
DIR="$HOME/db-backup"
FILE="$DIR/shopdb-$(date +%F-%H%M).sql.gz"
mysqldump --single-transaction --routines --triggers \
  --default-character-set=utf8mb4 shopdb | gzip > "$FILE"
find "$DIR" -name 'shopdb-*.sql.gz' -mtime +14 -delete
chmod 700 ~/db-backup/backup.sh
~/db-backup/backup.sh && ls -lh ~/db-backup/

เมื่อทดสอบแล้วได้ไฟล์ใหม่ ให้เพิ่มลง Crontab ของผู้ใช้เดียวกันด้วย crontab -e ตัวอย่างรันทุกวันเวลา 03:00

0 3 * * * $HOME/db-backup/backup.sh >> $HOME/db-backup/backup.log 2>&1

ไฟล์สำรองที่อยู่บนเครื่องเดียวกับฐานข้อมูลยังไม่ปลอดภัยพอ ควรส่งออกไปเก็บที่อื่นด้วย ตามคู่มือ สำรองข้อมูลไปยังเซิร์ฟเวอร์อื่นด้วย rsync และ Cronjob

ตรวจสอบผลลัพธ์

  • ตรวจว่าไฟล์บีบอัดไม่เสียด้วย gzip -t shopdb-*.sql.gz ถ้าไม่มีข้อความใดแสดงว่าไฟล์สมบูรณ์
  • ดูว่าไฟล์ครบถึงท้ายด้วย zcat ไฟล์.sql.gz | tail -n 1 ต้องเห็น Dump completed
  • ทดลองกู้คืนลงฐานข้อมูลทดสอบ เช่น shopdb_test แล้วนับจำนวนแถวของตารางสำคัญเทียบกับของจริงด้วย SELECT COUNT(*) FROM ชื่อตาราง; การสำรองที่ไม่เคยทดสอบกู้คืน ไม่สามารถมั่นใจได้ว่าใช้ได้จริง

ปัญหาที่พบบ่อย

Access denied; you need the PROCESS privilege

MySQL 8.0.21 ขึ้นไปต้องการสิทธิ์ PROCESS เพื่อสำรองข้อมูล Tablespace ซึ่งเว็บไซต์ทั่วไปไม่จำเป็นต้องใช้ ให้เพิ่มตัวเลือก --no-tablespaces ในคำสั่ง mysqldump

กู้คืนไฟล์จาก MariaDB ลง MySQL แล้วเจอ ERROR at line 1: Unknown command '\-'

mysqldump ของ MariaDB รุ่นที่ออกตั้งแต่กลางปี 2024 เพิ่มบรรทัดแรกเป็น /*M!999999\- enable the sandbox mode */ ซึ่ง MySQL อ่านไม่ได้ ให้ลบบรรทัดแรกออกก่อนกู้คืนด้วย sed -i '1{/999999/d}' shopdb-2026-09-19.sql

Got a packet bigger than 'max_allowed_packet' bytes

มีแถวข้อมูลขนาดใหญ่เกินค่าที่อนุญาต ให้เพิ่มตัวเลือก --max-allowed-packet=512M ทั้งตอนสำรองและในคำสั่ง mysql ตอนกู้คืน หากยังไม่หายต้องเพิ่มค่า max_allowed_packet ในไฟล์ตั้งค่าของเซิร์ฟเวอร์ปลายทางแล้วรีสตาร์ตบริการ

ภาษาไทยกลายเป็นเครื่องหมาย ? หลังกู้คืน

ตารางปลายทางหรือการเชื่อมต่อไม่ได้ใช้ utf8mb4 ตรวจว่าฐานข้อมูลปลายทางสร้างด้วย CHARACTER SET utf8mb4 และใส่ --default-character-set=utf8mb4 ทั้งตอนสำรองและตอนกู้คืน แล้วกู้คืนใหม่จากไฟล์เดิม

หากทำตามขั้นตอนแล้วยังติดปัญหา สามารถติดต่อทีมงาน Support ของ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/ โดยแจ้งชื่อเซิร์ฟเวอร์ ระบบปฏิบัติการ ขั้นตอนที่ทำไปแล้ว และข้อความ Error ที่พบ เพื่อให้ตรวจสอบได้รวดเร็วขึ้น

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security