بکاپ گرفتن از دیتابیس MySQL و MariaDB

برای بکاپ گرفتن از دیتابیس MySQL یا MariaDB، ساده‌ترین راه دستور mysqldump است که از دیتابیس یک فایل SQL شامل ساختار جدول‌ها و داده‌ها می‌سازد. با گزینه --single-transaction این کار برای جدول‌های InnoDB بدون قفل کردن سایت انجام می‌شود. بازیابی هم با دستور mysql و همان فایل انجام می‌شود. برای دیتابیس‌های چند ده گیگابایتی، ابزارهای بکاپ فیزیکی مثل MariaDB Backup یا Percona XtraBackup سریع‌ترند. در هر دو حالت بکاپ باید خودکار باشد، نسخه‌ای بیرون از همان سرور داشته باشد و بازیابی‌اش آزمایش شده باشد.

بکاپ منطقی یا بکاپ فیزیکی؟

ویژگیبکاپ منطقی (mysqldump)بکاپ فیزیکی (MariaDB Backup، XtraBackup)
خروجیفایل متنی SQLکپی فایل‌های داده دیتابیس
سرعت بکاپ و بازیابیبرای دیتابیس‌های بزرگ کندسریع، حتی برای حجم زیاد
انتقال به نسخه یا سرور دیگرراحتبه نسخه‌های سازگار وابسته است
بازیابی یک جدولسادهپیچیده‌تر
مناسب برایسایت‌ها و دیتابیس‌های کوچک و متوسطدیتابیس‌های بزرگ و پرتراکنش

برای بیشتر سایت‌ها و فروشگاه‌ها تا چند گیگابایت، mysqldump کافی است.

بکاپ گرفتن از دیتابیس با mysqldump

این دستور از دیتابیس shopdb یک فایل SQL می‌سازد:

mysqldump --single-transaction --routines --triggers --events -u root -p shopdb > shopdb.sql

گزینه --single-transaction بکاپ را داخل یک تراکنش می‌گیرد، پس همه جدول‌های InnoDB از یک لحظه ثبت می‌شوند و نوشتن روی سایت متوقف نمی‌شود. جدول‌های قدیمی MyISAM از این گزینه بهره نمی‌برند؛ اگر دیتابیس هنوز چنین جدولی دارد، بهتر است آن را به InnoDB تبدیل کنید. تریگرها به‌طور پیش‌فرض در خروجی هستند، ولی رویه‌های ذخیره‌شده و رویدادهای زمان‌بندی‌شده فقط با --routines و --events گرفته می‌شوند. --triggers را برای روشن بودن دستور نگه داشته‌ایم.

فایل SQL خوب فشرده می‌شود. خروجی را مستقیم به gzip بدهید و تاریخ را در نام فایل بگذارید:

mysqldump --single-transaction --routines --triggers --events -u root -p shopdb | gzip > shopdb-$(date +%F).sql.gz

برای بکاپ همه دیتابیس‌های سرور در یک فایل، به‌جای نام دیتابیس از --all-databases استفاده کنید. در MariaDB نسخه‌های جدید، نام اصلی این دستور mariadb-dump است و mysqldump نام قدیمی آن است؛ گزینه‌ها یکی‌اند.

کاربر بکاپ و نگهداری امن رمز

نوشتن رمز root در اسکریپت یا خط فرمان کار خطرناکی است. یک کاربر جدا فقط با دسترسی‌های لازم برای بکاپ بسازید:

CREATE USER 'backup'@'localhost' IDENTIFIED BY 'STRONG_PASSWORD';
GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES, EVENT, PROCESS ON *.* TO 'backup'@'localhost';

دسترسی PROCESS در MySQL 8 لازم است، وگرنه mysqldump هنگام خواندن اطلاعات Tablespace خطای دسترسی می‌دهد. بعد اطلاعات ورود را در فایل .my.cnf در خانه کاربری که اسکریپت را اجرا می‌کند بگذارید و دسترسی فایل را محدود کنید:

[client]
user=backup
password=STRONG_PASSWORD
chmod 600 ~/.my.cnf

با این فایل، mysqldump و mysql بدون گزینه‌های -u و -p اجرا می‌شوند و رمز در فهرست پروسه‌ها یا تاریخچه دستورها دیده نمی‌شود.

بازیابی دیتابیس از بکاپ

تا بازیابی یک بکاپ را امتحان نکرده‌اید، نمی‌دانید سالم است یا نه. بکاپ را هر چند وقت یک بار در یک دیتابیس جدا بازیابی کنید تا مطمئن شوید سالم است:

mysql -e "CREATE DATABASE shopdb_restore"
gunzip < shopdb-2026-09-24.sql.gz | mysql shopdb_restore

بعد تعداد رکوردهای چند جدول مهم را در دیتابیس اصلی و نسخه بازیابی‌شده مقایسه کنید. وقتی بازیابی واقعی لازم شد، همین دستور را برای دیتابیس اصلی اجرا می‌کنید، ولی پیش از آن از وضعیت فعلی هم یک بکاپ بگیرید، حتی اگر خراب باشد.

بکاپ خودکار دیتابیس با Cron

این اسکریپت از همه دیتابیس‌ها به‌جز دیتابیس‌های سیستمی جداگانه بکاپ فشرده می‌گیرد و بکاپ‌های قدیمی‌تر از ۱۴ روز را پاک می‌کند. آن را در /usr/local/bin/mysql-backup.sh ذخیره کنید:

#!/bin/bash
set -euo pipefail
DIR=/var/backups/mysql
mkdir -p "$DIR"
for DB in $(mysql -N -e "SHOW DATABASES" | grep -Ev '^(information_schema|performance_schema|sys)$'); do
  mysqldump --single-transaction --routines --triggers --events "$DB" | gzip > "$DIR/$DB-$(date +%F).sql.gz"
done
find "$DIR" -name "*.sql.gz" -mtime +14 -delete

فایل را اجرایی کنید و با crontab کاربر root برای ساعت ۲ و نیم بامداد زمان‌بندی کنید. فایل .my.cnf باید در خانه همان کاربری باشد که Cron اسکریپت را با آن اجرا می‌کند:

sudo chmod 700 /usr/local/bin/mysql-backup.sh
30 2 * * * /usr/local/bin/mysql-backup.sh

خط دوم را با sudo crontab -e اضافه کنید. جزئیات زمان‌بندی و روش گرفتن خروجی و خطای کارهای Cron در آموزش Cron Job در لینوکس آمده است. اگر اسکریپت خطا بدهد و کسی متوجه نشود، ممکن است هفته‌ها بکاپ گرفته نشود؛ پس موفق بودن آن را هم پایش کنید، مثلاً با بررسی تاریخ آخرین فایل در سیستم مانیتورینگ.

بکاپ فیزیکی برای دیتابیس‌های بزرگ

وقتی حجم دیتابیس به ده‌ها گیگابایت می‌رسد، mysqldump و به‌خصوص بازیابی آن خیلی طول می‌کشد. ابزارهای بکاپ فیزیکی فایل‌های داده را در حالی که دیتابیس کار می‌کند کپی می‌کنند و بعد در مرحله‌ای به نام Prepare آن‌ها را یکدست می‌کنند. در MariaDB این ابزار MariaDB Backup است:

mariadb-backup --backup --target-dir=/var/backups/full
mariadb-backup --prepare --target-dir=/var/backups/full

این ابزار دسترسی‌هایی بیشتر از کاربر بکاپی که بالاتر ساختیم لازم دارد، مثل RELOAD؛ فهرست کامل در مستندات MariaDB آمده است. برای MySQL ابزار متن‌باز Percona XtraBackup همین کار را انجام می‌دهد. کپی کردن مستقیم پوشه /var/lib/mysql با cp یا rsync در حالی که سرویس روشن است بکاپ قابل اعتمادی نمی‌سازد، چون فایل‌ها در حین کپی تغییر می‌کنند.

اگر از دست رفتن حتی چند ساعت داده هم قابل قبول نیست، Binary Log را فعال کنید و آن را هم نگه دارید. با بکاپ کامل شبانه و Binary Logهای بعد از آن، دیتابیس را می‌توان تا یک لحظه مشخص، مثلاً درست پیش از یک حذف اشتباه، برگرداند.

بکاپ دیتابیس وردپرس و هاست اشتراکی

در هاست اشتراکی معمولاً SSH ندارید. در phpMyAdmin دیتابیس را انتخاب کنید، به زبانه Export بروید و خروجی SQL بگیرید. در cPanel بخش Backup هم برای هر دیتابیس لینک دانلود جداگانه دارد. اگر WP-CLI در دسترس است، wp db export همان خروجی mysqldump را با اطلاعات wp-config.php می‌سازد. برای جابه‌جایی سایت به هاست دیگر هم همین فایل را لازم دارید؛ مراحل کامل را در انتقال سایت وردپرس به هاست جدید نوشته‌ایم.

بکاپ روی همان سرور کافی نیست

فایل بکاپی که روی دیسک همان سرور مانده، با خرابی سرور، هک یا باج‌افزار همراه خود دیتابیس از دست می‌رود. دست‌کم یک نسخه را به‌صورت خودکار به سرور یا فضای ذخیره‌سازی دیگری منتقل کنید و اگر داده‌ها حساس‌اند، پیش از انتقال رمزگذاری‌شان کنید. قاعده رایج ۳-۲-۱ است: سه نسخه از داده، روی دو نوع رسانه، که یکی بیرون از محل سرور باشد. آرایه RAID هم جای این نسخه جدا را نمی‌گیرد؛ دلیلش را در RAID چیست توضیح داده‌ایم.

سوالات متداول

چطور در phpMyAdmin از دیتابیس بکاپ بگیرم؟

دیتابیس را از ستون سمت چپ انتخاب کنید، زبانه Export را باز کنید، روش Quick و قالب SQL را انتخاب کنید و فایل را دانلود کنید. برای دیتابیس‌های بزرگ ممکن است phpMyAdmin به محدودیت زمان یا حافظه بخورد و بهتر است از mysqldump استفاده کنید.

mysqldump سایت را کند می‌کند؟

mysqldump همه داده‌ها را می‌خواند و روی دیسک و پردازنده بار می‌گذارد، ولی با --single-transaction جدول‌های InnoDB را قفل نمی‌کند. بکاپ را برای ساعت‌های کم‌ترافیک زمان‌بندی کنید. اگر با این وجود سایت کند می‌شود، وقت رفتن به سراغ بکاپ فیزیکی یا گرفتن بکاپ از یک سرور Replica است.

فایل بکاپ خیلی بزرگ است؛ چه کنم؟

خروجی را با gzip فشرده کنید؛ فایل SQL معمولاً چند برابر کوچک‌تر می‌شود. جدول‌هایی مثل لاگ‌ها یا سشن‌ها را که به بکاپ نیاز ندارند با --ignore-table=db.table کنار بگذارید و اگر حجم هنوز زیاد است، به بکاپ فیزیکی فکر کنید.

از دیتابیس SQL Server هم همین‌طور بکاپ گرفته می‌شود؟

نه. SQL Server ابزار جداگانه خودش را دارد: دستور BACKUP DATABASE در T-SQL یا گزینه Back Up در SQL Server Management Studio. روش‌های این صفحه فقط برای MySQL و MariaDB است.

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *