ریستور و انتقال دیتابیس MySQL به سرور جدید

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

دیتابیس و بکاپمتوسط10 دقیقه

۱گرفتن بکاپ از سرور قدیم

با گزینه‌هایی که برای انتقال مناسب‌اند بکاپ بگیرید. --set-gtid-purged=OFF از خطای GTID روی سرور مقصد جلوگیری می‌کند.

bash
mysqldump --single-transaction --routines --triggers --events \
  --set-gtid-purged=OFF appdb | gzip > appdb.sql.gz

۲انتقال فایل به سرور جدید

با scp یا rsync فایل را به سرور مقصد بفرستید. rsync اگر قطع شود ادامه می‌دهد.

bash
rsync -avP appdb.sql.gz root@203.0.113.30:/root/

۳ساخت دیتابیس و کاربر روی سرور جدید

دیتابیس را با همان charset بسازید و کاربر برنامه را با حداقل دسترسی تعریف کنید.

bash
mysql -e "CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql -e "CREATE USER 'app'@'localhost' IDENTIFIED BY 'STRONG_PASSWORD';"
mysql -e "GRANT ALL PRIVILEGES ON appdb.* TO 'app'@'localhost'; FLUSH PRIVILEGES;"

۴ریستور بکاپ

با zcat فایل فشرده را مستقیم به mysql بدهید. برای فایل‌های بزرگ pv پیشرفت را نشان می‌دهد (اختیاری).

bash
zcat appdb.sql.gz | mysql appdb

# با نمایش پیشرفت (نیاز به نصب pv)
pv appdb.sql.gz | zcat | mysql appdb

اگر دیتابیس مقصد از قبل داده دارد، جدول‌های همنام بازنویسی می‌شوند.

۵انتقال مستقیم بدون فایل میانی (اختیاری)

اگر سرور قدیم به سرور جدید SSH دارد، می‌توان خروجی mysqldump را مستقیم از طریق SSH به mysql مقصد داد و دیسک اضافه مصرف نکرد.

bash
mysqldump --single-transaction --routines --triggers --events appdb \
  | ssh root@203.0.113.30 "mysql appdb"

۶رفع خطای DEFINER

اگر خطای «The user specified as a definer does not exist» گرفتید، کاربری که view یا procedure با آن ساخته شده در سرور جدید نیست. یا کاربر را بسازید یا DEFINER را از فایل حذف کنید.

bash
zcat appdb.sql.gz \
  | sed -E 's/DEFINER=`[^`]+`@`[^`]+`//g' \
  | mysql appdb

۷بررسی نهایی

تعداد جدول‌ها و رکوردهای جدول‌های مهم را در دو سرور مقایسه کنید و اتصال برنامه را تست کنید.

bash
mysql -e "SELECT COUNT(*) AS tables_count FROM information_schema.tables WHERE table_schema='appdb'"
mysql -e "SELECT COUNT(*) FROM appdb.users"
mysqlcheck --check appdb

۸برای کاهش زمان قطعی سایت

روش عملی: (۱) سایت را در حالت تعمیر ببرید، (۲) بکاپ نهایی بگیرید و ریستور کنید، (۳) تنظیم دیتابیس برنامه را روی سرور جدید بگذارید، (۴) DNS را عوض کنید. قبل از تغییر DNS، TTL را چند ساعت جلوتر کم کنید تا تغییر سریع‌تر پخش شود.

پرسش‌های پرتکرار دربارهٔ ریستور و انتقال دیتابیس MySQL به سرور جدید

آیا نسخهٔ MySQL مقصد باید با مبدأ یکی باشد؟

بهتر است مقصد هم‌نسخه یا جدیدتر باشد. ریستور از نسخهٔ جدید به قدیمی ممکن است به‌خاطر قابلیت‌های ناسازگار (مثل collation جدید MySQL 8) خطا بدهد.

کاراکترهای فارسی بعد از ریستور خراب شده‌اند، چه کنم؟

احتمالاً charset دیتابیس یا اتصال متفاوت است. دیتابیس را با utf8mb4 بسازید و هنگام ریستور از mysql --default-character-set=utf8mb4 استفاده کنید.