فصل ۷: مدیریت و امنیت — کاربران، بکاپ، Replication و کد سمت سرور

پشتیبان‌گیری: mysqldump --single-transaction و MySQL Shell dump

بکاپی که بازیابی‌اش را امتحان نکرده‌اید، بکاپ نیست

بیشتر حادثه‌های از دست رفتن داده به‌خاطر نبودن بکاپ نیست؛ به‌خاطر بکاپی است که ناقص، خراب یا غیرقابل بازیابی بوده و کسی تا روز حادثه امتحانش نکرده بود. دو خانواده‌ی اصلی بکاپ داریم:

منطقی (mysqldump، MySQL Shell)فیزیکی (XtraBackup، Clone، snapshot دیسک)
خروجیدستورهای SQL یا فایل‌های داده‌ی متنیکپی فایل‌های InnoDB
سرعت روی ۲۰۰ گیگکند، به‌ویژه بازیابیسریع
انتقال بین نسخه‌هاآسانمعمولاً فقط همان نسخه
بازیابی یک جدولآساندشوارتر

mysqldump درست

mysqldump --login-path=backup \
  --single-transaction --routines --events --triggers \
  --source-data=2 --set-gtid-purged=AUTO \
  --default-character-set=utf8mb4 --hex-blob \
  --databases carpet_factory \
  | gzip > /backup/carpet_factory_$(date +%F).sql.gz

# بازیابی
gunzip < /backup/carpet_factory_2026-10-01.sql.gz | mysql --login-path=admin

--single-transaction یک snapshot سازگار با REPEATABLE READ می‌گیرد و جدول‌های InnoDB را قفل نمی‌کند؛ سایت در طول بکاپ کار می‌کند. --source-data=2 (جایگزین --master-data از 8.0.26) مختصات binlog را به‌صورت کامنت در فایل می‌نویسد که در درس بعد برای بازیابی لحظه‌ای لازم است.

CREATE USER 'backup'@'localhost' IDENTIFIED BY 'Backup-Secret';
GRANT SELECT, SHOW VIEW, TRIGGER, EVENT, LOCK TABLES, RELOAD,
      PROCESS, REPLICATION CLIENT, BACKUP_ADMIN ON *.* TO 'backup'@'localhost';

MySQL Shell: بکاپ منطقی موازی

ابزار mysqlsh بکاپ را با چند thread و فشرده‌سازی zstd می‌گیرد و بازیابی‌اش چند برابر سریع‌تر از اجرای یک فایل SQL بزرگ است:

// mysqlsh backup@localhost --js
util.dumpSchemas(["carpet_factory"], "/backup/shell/2026-10-01",
                 {threads: 8, compression: "zstd"})
util.dumpInstance("/backup/shell/full-2026-10-01", {threads: 8})

// روی سرور مقصد (local_infile باید ON باشد)
util.loadDump("/backup/shell/2026-10-01", {threads: 8, dryRun: true})
util.loadDump("/backup/shell/2026-10-01", {threads: 8})

برنامه‌ی نگهداری

قاعده‌ی 3-2-1: سه نسخه، روی دو رسانه‌ی مختلف، یکی بیرون از سرور. بکاپ شبانه با cron، نگهداری ۱۴ روزه با find /backup -name '*.sql.gz' -mtime +14 -delete و هر ماه یک بازیابی آزمایشی روی سرور جداگانه که با یک کوئری شمارش ردیف‌ها تأیید شود.

نکته‌هایی که کمتر کسی می‌داند

  • mysqldump بدون --single-transaction به‌طور پیش‌فرض --lock-tables می‌زند؛ یعنی در طول بکاپ هیچ سفارشی ثبت نمی‌شود.
  • اگر وسط dump یک ALTER TABLE اجرا شود، snapshot شکسته می‌شود و خطای Table definition has changed یا جدول ناقص می‌گیرید؛ مایگریشن و بکاپ را هم‌زمان نگذارید.
  • خطای Access denied; you need the PROCESS privilege در نسخه‌های جدید با --no-tablespaces برطرف می‌شود اگر نمی‌خواهید PROCESS بدهید.
  • dumpی که DEFINER آن کاربری ناموجود است، بعد از بازیابی تریگر و View را با ERROR 1449 از کار می‌اندازد؛ در MySQL Shell گزینه‌ی compatibility: ["strip_definers"] این را حل می‌کند.
  • برای بارگذاری اولیه‌ی یک سرور تازه، ALTER INSTANCE DISABLE INNODB REDO_LOG; سرعت را چند برابر می‌کند؛ فقط برای همان لحظه و هرگز روی سرور در حال سرویس.
  • هنگام وارد کردن dump در سروری که GTID اجراشده دارد، --set-gtid-purged=OFF بگیرید وگرنه بازیابی با خطای GTID_PURGED متوقف می‌شود.

برای ذخیره‌ی پیشرفت و شرکت در آزمون، وارد شوید — رایگان است.