بلاگ/بکاپ‌گیری خودکار از MySQL به Object Storage: راهنمای عملی با mysqldump و s3cmd/rclone
به‌روز شده

بکاپ‌گیری خودکار از MySQL به Object Storage: راهنمای عملی با mysqldump و s3cmd/rclone

1405/08/080 بازدید
بکاپ‌گیری خودکار از MySQL به Object Storage: راهنمای عملی با mysqldump و s3cmd/rclone

بکاپ‌گیری خودکار از MySQL به Object Storage: راهنمای عملی با mysqldump و s3cmd/rclone

یک دیتابیس MySQL بدون بکاپ، دیر یا زود یک روز بد برایتان می‌سازد. راه‌حل آن هم پیچیده نیست: یک اسکریپت کوچک که هر شب دیتابیس را دامپ می‌کند، فایل را به یک Object Storage جدا از سرور اصلی می‌فرستد و بکاپ‌های قدیمی را پاک می‌کند. در این مقاله همین کار را با mysqldump و دو ابزار s3cmd و rclone قدم‌به‌قدم انجام می‌دهیم.

نمودار جریان بکاپ‌گیری خودکار از MySQL: دامپ با mysqldump، فشرده‌سازی و ارسال به Object Storage با rclone یا s3cmd

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

اگر بکاپ‌ها را کنار خود دیتابیس روی همان دیسک نگه دارید، یک خرابی دیسک یا یک حذف اشتباه هر دو را با هم از بین می‌برد. همین‌طور اگر سرور ابری که MySQL روی آن اجرا می‌شود هک یا قفل شود (مثلا با یک باج‌افزار)، فایل‌های بکاپ محلی هم قربانی می‌شوند.

به همین دلیل بکاپ باید جایی خارج از آن سرور ذخیره شود. Object Storage برای این کار مناسب است: هزینه‌اش پایین‌تر از یک دیسک اضافه است، از طریق پروتکل S3 با ابزارهای ساده در دسترس است و روی زیرساختی جدا از سرور اصلی شما نگه‌داری می‌شود.

ابزارهای لازم: mysqldump، s3cmd و rclone چه فرقی دارند

mysqldump برنامه‌ای است که همراه خود MySQL نصب می‌شود و کل دیتابیس (یا یک جدول خاص) را به یک فایل متنی SQL تبدیل می‌کند. برای بازگرداندن هم کافی است همان فایل را دوباره اجرا کنید.

برای ارسال فایل به Object Storage دو گزینهٔ رایج هست:

ویژگیs3cmdrclone
نصبیک پکیج ساده (apt install s3cmd)یک باینری تکی، بدون وابستگی
تنظیماتفایل .s3cfgفایل rclone.conf، چند remote هم‌زمان
پاک‌سازی خودکاربا اسکریپت جداگانهدستور rclone delete با فیلتر سن فایل
سرعت در فایل‌های بزرگمعمولیآپلود موازی (چند چانک هم‌زمان)
سازگاریفقط S3 و شبیه‌سازهای آنS3 و حدود ۴۰ سرویس دیگر (FTP، Google Drive و...)

اگر فقط یک Object Storage دارید و ابزار ساده می‌خواهید، s3cmd کافی است. اگر بکاپ‌های حجیم دارید یا احتمال دارد بعدا مقصد دیگری هم اضافه کنید، rclone را انتخاب کنید.

مرحله ۱: گرفتن بکاپ از دیتابیس با mysqldump

اول یک پوشهٔ موقت برای بکاپ‌ها بسازید:

mkdir -p /var/backups/mysql

سپس دامپ را بگیرید و مستقیم فشرده کنید تا هم فضا کمتر مصرف شود و هم آپلود سریع‌تر باشد:

DATE=$(date +%F_%H%M)
mysqldump --single-transaction --quick \
  -u backup_user -p"$MYSQL_BACKUP_PASS" mydatabase \

  | gzip > /var/backups/mysql/mydatabase_${DATE}.sql.gz

گزینهٔ --single-transaction باعث می‌شود دامپ در یک تراکنش ثابت گرفته شود و جداول InnoDB در حال نوشتن قفل نشوند. رمز عبور را در اسکریپت ننویسید؛ آن را در یک فایل جدا مثل /root/.mysql_backup_env با دسترسی chmod 600 نگه دارید و در ابتدای اسکریپت source کنید.

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

مرحله ۲: ارسال بکاپ به Object Storage

با s3cmd

اول پیکربندی را یک بار انجام دهید:

s3cmd --configure

آدرس endpoint، access key و secret key سرویس Object Storage را وارد می‌کنید. بعد ارسال فایل همین‌قدر ساده است:

s3cmd put /var/backups/mysql/mydatabase_${DATE}.sql.gz s3://my-backup-bucket/mysql/

یا با rclone

برای rclone هم اول یک remote تعریف کنید:

rclone config

و برای آپلود:

rclone copy /var/backups/mysql/mydatabase_${DATE}.sql.gz myremote:my-backup-bucket/mysql/

اگر چند فایل دارید و می‌خواهید فقط تفاوت‌ها منتقل شود، به‌جای copy از sync روی یک پوشهٔ کامل استفاده کنید؛ اما برای بکاپ تک‌فایل، copy همان کاری است که لازم دارید.

مرحله ۳: زمان‌بندی خودکار با cron

مراحل بالا را در یک فایل مثل /usr/local/bin/mysql_backup.sh کنار هم بگذارید:

#!/bin/bash
set -e
source /root/.mysql_backup_env

DATE=$(date +%F_%H%M)
FILE=mydatabase_${DATE}.sql.gz

mysqldump --single-transaction --quick -u backup_user -p"$MYSQL_BACKUP_PASS" mydatabase \

  | gzip > /var/backups/mysql/$FILE

rclone copy /var/backups/mysql/$FILE myremote:my-backup-bucket/mysql/

اجرایی‌اش کنید و در crontab کاربر root اضافه کنید تا هر شب ساعت ۲ بامداد اجرا شود؛ اگر به زمان‌بندی دقیق‌تر یا لاگ بهتر نیاز دارید، جایگزینی Cron با Systemd Timer را هم ببینید:

chmod +x /usr/local/bin/mysql_backup.sh
crontab -e
# خط زیر را اضافه کنید:
0 2 * * * /usr/local/bin/mysql_backup.sh >> /var/log/mysql_backup.log 2>&1

خروجی را به یک فایل لاگ هدایت کنید؛ اگر یک شب بکاپ به هر دلیلی شکست بخورد، همین لاگ اولین جایی است که باید نگاه کنید.

پاک‌سازی بکاپ‌های قدیمی

نگه داشتن بکاپ بی‌نهایت، هم فضای دیسک محلی و هم هزینهٔ Object Storage را بالا می‌برد. دو جا باید پاک‌سازی انجام شود.

روی سرور، فایل‌های قدیمی‌تر از ۷ روز را حذف کنید:

find /var/backups/mysql -name "*.sql.gz" -mtime +7 -delete

روی Object Storage هم با rclone می‌توانید فایل‌های قدیمی‌تر از یک بازهٔ مشخص را حذف کنید:

rclone delete myremote:my-backup-bucket/mysql/ --min-age 30d

این دو خط را هم به همان اسکریپت cron اضافه کنید تا پاک‌سازی هم خودکار باشد. اگر سرویس Object Storage شما قابلیت lifecycle rule دارد (حذف خودکار بعد از N روز)، آن را هم به‌عنوان یک لایهٔ پشتیبان فعال کنید؛ حتی اگر اسکریپت پاک‌سازی یک بار اجرا نشود، فایل‌ها بی‌نهایت روی هم جمع نمی‌شوند.

نکات امنیتی و انتخاب محل سرور

کلیدهای دسترسی Object Storage را فقط در فایل‌هایی با دسترسی محدود (chmod 600) نگه دارید و در گیت یا جای عمومی کامیت نکنید؛ برای نکات بیشتر در این زمینه افزایش امنیت سرور لینوکس را هم بخوانید. برای کاربر دیتابیس هم یک کاربر جدا با فقط دسترسی SELECT, LOCK TABLES بسازید؛ کاربری که فقط بکاپ می‌گیرد نباید دسترسی نوشتن داشته باشد (نکات امنیت دیتابیس و پایگاه داده را هم ببینید).

یک نکتهٔ کمتر گفته‌شده: اگر سرور ابری که MySQL روی آن اجرا می‌شود در اروپا یا ترکیه است، باکت Object Storage را هم در همان منطقه بسازید. وقتی سرور ابری اروپا و باکت در یک منطقهٔ دیگر باشند، آپلود هر شب چند ثانیهٔ اضافه طول می‌کشد که برای چند گیگابایت دامپ قابل توجه می‌شود؛ وقتی سرور ابری ترکیه است هم همین قانون برقرار است.

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

تست بازیابی، نه فقط گرفتن بکاپ

بکاپی که هیچ‌وقت بازگردانی نشده، فقط یک فایل است، نه یک برنامهٔ بکاپ قابل اعتماد. هر چند هفته یک‌بار یک فایل را دانلود کنید و روی یک دیتابیس تست بازگردانی کنید:

gunzip -c mydatabase_2026-10-30_0200.sql.gz | mysql -u root -p test_restore_db

اگر این دستور بدون خطا تمام شود و جدول‌ها و رکوردها درست باشند، بکاپتان کار می‌کند.

برای اجرای این اسکریپت‌ها به یک سرور ابری با دسترسی root و کرون پایدار نیاز دارید؛ صفحهٔ سرور ابری آریانت پلن‌ها و قیمت هر منطقه را نشان می‌دهد.

جمع‌بندی

یک اسکریپت ساده با mysqldump، یک ابزار ارسال مثل s3cmd یا rclone، یک خط cron و یک قانون پاک‌سازی؛ همین چهار قطعه کافی است تا دیتابیستان دیگر وابسته به یک دیسک نباشد. کافی است یک بار بنشینید و این اسکریپت را بسازید، بعد از آن هر شب خودش کار می‌کند.

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

آیا mysqldump برای دیتابیس‌های خیلی بزرگ هم مناسب است؟ برای چند ده گیگابایت معمولا کافی است، به‌خصوص با --single-transaction. برای دیتابیس‌های بسیار بزرگ‌تر معمولا به ابزارهای فیزیکی مثل Percona XtraBackup هم نگاه می‌کنند.

فرق s3cmd و rclone در عمل چیست؟ s3cmd برای کار ساده با یک Object Storage کافی است. rclone علاوه بر S3 با ده‌ها سرویس دیگر هم کار می‌کند و آپلود فایل‌های بزرگ را موازی انجام می‌دهد.

چند روز بکاپ را نگه دارم؟ بستگی به نیاز کسب‌وکار دارد؛ یک الگوی رایج، نگه‌داشتن بکاپ روزانهٔ ۷ روز اخیر و حذف قدیمی‌تر از آن روی هر دو سمت (سرور و Object Storage) است.

اگر رمز اتصال به Object Storage لو برود چه خطری دارد؟ هر کسی که آن کلید را داشته باشد می‌تواند بکاپ‌ها را بخواند یا حذف کند. کلید را فقط در فایلی با دسترسی محدود نگه دارید و در صورت شک به افشا، فورا از پنل سرویس آن را باطل کنید.