بازیابی MySQL تا لحظهٔ دلخواه با binlog

بکاپ شبانه فقط وضعیت نیمه‌شب را نگه می‌دارد. اگر ساعت ۱۰ صبح جدولی حذف شود، همهٔ تغییرات صبح از بین می‌رود. با لاگ باینری (binlog) می‌توانید بکاپ کامل را ریستور کنید و سپس تغییرات را تا لحظهٔ قبل از خطا دوباره اجرا کنید.

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

۱فعال‌سازی لاگ باینری

در MySQL 8 لاگ باینری به‌صورت پیش‌فرض روشن است. در MariaDB و نسخه‌های قدیمی‌تر باید آن را در فایل تنظیمات فعال کنید و سرویس را ریستارت کنید.

ini
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
server-id        = 1
log_bin          = /var/log/mysql/mysql-bin.log
binlog_expire_logs_seconds = 1209600   # ۱۴ روز
max_binlog_size  = 100M
binlog_format    = ROW

۲بررسی فعال بودن

با دستور زیر باید log_bin برابر ON باشد.

bash
sudo systemctl restart mysql
mysql -e "SHOW VARIABLES LIKE 'log_bin'; SHOW BINARY LOGS;"

۳بکاپ کامل همراه با موقعیت binlog

گزینهٔ --source-data=2 (در نسخه‌های قدیمی --master-data=2) نام و موقعیت binlog را به‌صورت کامنت در ابتدای بکاپ می‌نویسد.

bash
mysqldump --single-transaction --routines --events --source-data=2 appdb \
  | gzip > appdb_full.sql.gz

zcat appdb_full.sql.gz | grep -m1 'CHANGE'

۴پیدا کردن لحظهٔ خطا

فرض کنید ساعت 10:32:15 جدولی حذف شد. باید موقعیت دقیق آن دستور را در binlog پیدا کنید.

bash
sudo mysqlbinlog --base64-output=decode-rows -v \
  --start-datetime="2026-09-29 10:30:00" \
  --stop-datetime="2026-09-29 10:35:00" \
  /var/log/mysql/mysql-bin.000012 | grep -n -i -B5 'DROP TABLE'

۵ریستور بکاپ کامل

ابتدا بکاپ شبانه را روی دیتابیس (ترجیحاً روی یک سرور موقت) ریستور کنید.

bash
mysql -e "CREATE DATABASE appdb_recovery"
zcat appdb_full.sql.gz | mysql appdb_recovery

برای دیتابیس اصلی این کار را بدون فکر انجام ندهید؛ ابتدا روی نسخهٔ موقت امتحان کنید.

۶بازپخش binlog تا قبل از خطا

از موقعیتی که در بکاپ ثبت شده تا درست قبل از دستور اشتباه، تغییرات را دوباره اجرا کنید.

bash
sudo mysqlbinlog \
  --start-position=157 \
  --stop-datetime="2026-09-29 10:32:14" \
  /var/log/mysql/mysql-bin.000012 | mysql appdb_recovery

start-position را از خط CHANGE ... MASTER_LOG_POS بکاپ بردارید و اگر چند فایل binlog دارید همهٔ آن‌ها را به‌ترتیب بدهید.

۷بررسی و انتقال داده‌های بازیابی‌شده

داده‌های دیتابیس بازیابی‌شده را بررسی کنید و جدول‌های لازم را به دیتابیس اصلی برگردانید (مثلاً با mysqldump یک جدول).

bash
mysqldump appdb_recovery orders | mysql appdb

پرسش‌های پرتکرار دربارهٔ بازیابی MySQL تا لحظهٔ دلخواه با binlog

لاگ باینری چقدر فضا می‌گیرد؟

به حجم تغییرات بستگی دارد. با binlog_expire_logs_seconds مدت نگه‌داری را محدود کنید (مثلاً ۷ تا ۱۴ روز) و فضای دیسک را پایش کنید.

آیا binlog جای بکاپ را می‌گیرد؟

خیر. binlog فقط تغییرات بین بکاپ‌هاست و بدون بکاپ کامل قابل استفاده نیست؛ هر دو را با هم نگه دارید.