العودة إلى المدونة

النسخ الاحتياطي لقاعدة بيانات MySQL واستعادتها: phpMyAdmin وmysqldump والملفات الكبيرة

فريق تحرير IM Host25 أكتوبر 20266 دقائق قراءة
النسخ الاحتياطي لقاعدة بيانات MySQL واستعادتها: phpMyAdmin وmysqldump والملفات الكبيرة

تحفظ معظم المواقع بياناتها المهمة في قاعدة بيانات MySQL أو MariaDB: الطلبات والمستخدمين والمقالات والإعدادات. يمكن غالبًا إعادة رفع الملفات، أما قاعدة البيانات المفقودة فلا يمكن عادةً إعادة بنائها. يشرح هذا الدليل الطريقتين الشائعتين للنسخ الاحتياطي والاستعادة، phpMyAdmin وmysqldump، ثم الأخطاء التي تواجهها مع الملفات الكبيرة، وكيف تجعل النسخ الاحتياطي تلقائيًا باستخدام cron.

أي أداة تستخدم؟

  • phpMyAdmin يعمل من المتصفح ولا يحتاج إلى SSH. وهو مناسب لقواعد البيانات الصغيرة والمتوسطة، وكقاعدة تقريبية حتى بضع عشرات من الميغابايت. وبعد ذلك تبدأ حدود الرفع ومهلة PHP في التسبب بالمشكلات.

  • mysqldump يعمل من سطر الأوامر، ويتعامل مع قواعد البيانات الكبيرة، ويمكنه الضغط أثناء التصدير، ويمكن جدولته. إذا كان لديك وصول SSH ففضّله.

كلاهما ينتج الشيء نفسه: ملف .sql يحتوي على أوامر SQL تعيد إنشاء الجداول والبيانات.

النسخ الاحتياطي باستخدام phpMyAdmin

  1. افتح phpMyAdmin واختر قاعدة البيانات من القائمة الجانبية.

  2. افتح تبويب Export.

  3. اختر Custom كطريقة للتصدير، واترك الصيغة SQL.

  4. في قسم Output اختر الضغط gzipped. نصوص SQL تُضغط بشكل ممتاز، فيصغر حجم الملف كثيرًا.

  5. في خيارات إنشاء الكائنات فعّل Add DROP TABLE إذا كنت تنوي الاستعادة فوق قاعدة بيانات موجودة.

  6. اضغط Export واحتفظ بالملف الذي تم تنزيله في مكان غير الخادم.

الاستعادة باستخدام phpMyAdmin

  1. اختر قاعدة البيانات الهدف (وأنشئ قاعدة فارغة أولًا إذا لزم الأمر).

  2. افتح تبويب Import واختر ملف .sql أو .sql.gz. يقرأ phpMyAdmin ملفات gzip مباشرة.

  3. أبقِ خيار "Allow the interruption of an import" مفعّلًا. إذا توقف الاستيراد بسبب مهلة زمنية يمكنك استيراد الملف نفسه مجددًا، ويكمل phpMyAdmin من حيث توقف.

  4. اضغط Import.

تعرض صفحة الاستيراد الحد الأقصى لحجم الرفع، مثل "Max: 50MiB". هذا الحد يأتي من PHP وليس من MySQL: الإعدادان upload_max_filesize وpost_max_size، إضافة إلى max_execution_time في عمليات الاستيراد الطويلة. في الاستضافة المشتركة قد تتمكن من رفع هذه القيم من إعدادات PHP في لوحة التحكم. وإذا بقي الملف أكبر من المسموح فاضغطه أو قسّمه أو انتقل إلى mysqldump عبر SSH.

النسخ الاحتياطي باستخدام mysqldump

هذا أمر افتراضي جيد:

mysqldump -u dbuser -p \
  --single-transaction --quick \
  --routines --triggers \
  --default-character-set=utf8mb4 \
  dbname > dbname.sql

ما الذي تفعله الخيارات:

  • --single-transaction يأخذ لقطة متسقة لجداول InnoDB دون قفلها، فيستمر الموقع في العمل أثناء النسخ. ولا يفيد مع جداول MyISAM التي ما زالت تحتاج إلى أقفال لتكون النسخة متسقة.

  • --quick يمرر الصفوف واحدًا تلو الآخر بدل تحميل الجداول كاملة في الذاكرة. وهو مفعّل افتراضيًا في الإصدارات الحديثة، لكن ذكره لا يضر.

  • --routines --triggers يضمّنان الإجراءات المخزنة والدوال والمشغلات (triggers). وبدونهما يتعطل التطبيق الذي يعتمد عليها بعد الاستعادة.

  • --default-character-set=utf8mb4 يمنع تلف الحروف. إذا عاد النص العربي على شكل رموز مثل ال فالسبب المعتاد هو عدم تطابق ترميز الحروف أثناء التصدير أو الاستيراد.

اضغط النسخة أثناء كتابتها:

mysqldump -u dbuser -p --single-transaction --quick --routines --triggers \
  --default-character-set=utf8mb4 dbname | gzip > dbname-$(date +%F).sql.gz

إذا كنت تصدّر بمستخدم لا يملك صلاحية PROCESS، وهذا شائع في الاستضافة المشتركة، فقد يتوقف MySQL 8 بهذه الرسالة:

mysqldump: Error: 'Access denied; you need (at least one of) the PROCESS privilege(s) for this operation' when trying to dump tablespaces

أضف الخيار --no-tablespaces إلى الأمر، فمعظم التطبيقات لا تحتاج إلى معلومات tablespaces في النسخة.

الاستعادة باستخدام mysql

# create an empty database first (skip if it already exists)
mysql -u root -p -e "CREATE DATABASE dbname CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

# plain .sql file
mysql -u dbuser -p --default-character-set=utf8mb4 dbname < dbname.sql

# compressed .sql.gz file
gunzip < dbname-2026-10-25.sql.gz | mysql -u dbuser -p --default-character-set=utf8mb4 dbname

تستبدل الاستعادة الجداول الموجودة في النسخة. والاستعادة إلى قاعدة بيانات خاطئة خطأ شائع ومؤلم، لذلك راجع اسم قاعدة البيانات قبل الضغط على Enter.

الملفات الكبيرة: ما الذي يتعطل وكيف تصلحه

الاستيراد الطويل وانقطاع جلسة SSH

قد يستغرق استيراد ملف بحجم عدة غيغابايت وقتًا طويلًا، وإذا انقطع اتصال SSH يتوقف الاستيراد. شغّله داخل tmux أو screen، واستخدم pv لمتابعة التقدم:

sudo apt install pv tmux
tmux new -s restore
pv dbname.sql.gz | gunzip | mysql -u dbuser -p --default-character-set=utf8mb4 dbname

إذا انقطع الاتصال، أعد الاتصال ثم نفّذ tmux attach -t restore.

رسالة "MySQL server has gone away"

ERROR 2006 (HY000) at line 1234: MySQL server has gone away
ERROR 1153 (08S01) at line 1234: Got a packet bigger than 'max_allowed_packet' bytes

يوجد في النسخة أمر واحد، غالبًا INSERT كبير متعدد الصفوف أو حقل BLOB كبير، حجمه أكبر مما يقبله الخادم. ارفع قيمة max_allowed_packet:

# client side, for this import only
mysql -u dbuser -p --max-allowed-packet=256M dbname < dbname.sql

# server side, in the [mysqld] section of my.cnf, then restart MySQL/MariaDB
max_allowed_packet = 256M

القيمة 256M قيمة عملية شائعة وليست رقمًا سحريًا. وفي الاستضافة المشتركة لا يمكنك تغيير إعداد الخادم، فاسأل الدعم أو استورد عبر phpMyAdmin على أجزاء أصغر.

رفض الوصول بسبب DEFINER

ERROR 1227 (42000) at line 87: Access denied; you need (at least one of) the SUPER or SET_USER_ID privilege(s) for this operation

تحمل العروض (views) والمشغلات والإجراءات في النسخة عبارة DEFINER باسم المستخدم الأصلي، مثل root. وحسابك على الخادم الجديد لا يستطيع إنشاء كائنات يملكها مستخدم آخر. احذف هذه العبارات قبل الاستيراد:

sed -E 's/DEFINER=[^ ]+ //g' dbname.sql > dbname-clean.sql

ترتيب حروف غير معروف عند النقل من MySQL 8 إلى MariaDB

ERROR 1273 (HY000) at line 25: Unknown collation: 'utf8mb4_0900_ai_ci'

يستخدم MySQL 8 أنواع collation لا يعرفها MariaDB، فاستبدلها في النسخة:

sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' dbname.sql

النسخ الاحتياطي التلقائي باستخدام cron

لا تضع كلمة المرور في سطر الأوامر، فقد تظهر في قائمة العمليات وفي سجل الأوامر. احفظها في الملف ~/.my.cnf للمستخدم الذي يشغّل النسخ الاحتياطي (وللمستخدم root يكون /root/.my.cnf):

[client]
user=dbuser
password=change-this-password
chmod 600 ~/.my.cnf

يقرأ mysqldump وmysql قسم [client] تلقائيًا. بعد ذلك أنشئ الملف /usr/local/bin/mysql-backup.sh:

#!/bin/bash
set -euo pipefail

BACKUP_DIR=/var/backups/mysql
DB=dbname
KEEP_DAYS=14

mkdir -p "$BACKUP_DIR"
mysqldump --single-transaction --quick --routines --triggers \
  --default-character-set=utf8mb4 "$DB" \
  | gzip > "$BACKUP_DIR/$DB-$(date +%F-%H%M).sql.gz"

find "$BACKUP_DIR" -name "$DB-*.sql.gz" -mtime +"$KEEP_DAYS" -delete

يجعل set -o pipefail السكربت يفشل عندما يفشل mysqldump، رغم أن gzip هو آخر أمر في السلسلة. ويحتفظ سطر find بآخر 14 يومًا حتى لا يمتلئ القرص. اجعل السكربت قابلًا للتنفيذ ثم جدوله:

sudo chmod 700 /usr/local/bin/mysql-backup.sh
sudo crontab -e
30 2 * * * /usr/local/bin/mysql-backup.sh >> /var/log/mysql-backup.log 2>&1

سيعمل هذا كل ليلة في الساعة 02:30. وملاحظة صغيرة: إذا وضعت date +%F مباشرة داخل سطر crontab فيجب تهريب كل علامة نسبة مئوية بكتابتها \%، أما في سكربت منفصل كما هنا فلا حاجة لذلك.

احتفظ بنسخة خارج الخادم واختبرها

النسخة الاحتياطية الموجودة على الخادم نفسه تضيع مع الخادم. انسخ الملفات بشكل مجدول إلى جهاز آخر أو خدمة تخزين أخرى، مثلًا باستخدام rsync عبر SSH.

ثم اختبر الاستعادة إلى قاعدة بيانات منفصلة من حين لآخر:

mysql -e "CREATE DATABASE restore_test;"
gunzip < /var/backups/mysql/dbname-2026-10-25-0230.sql.gz | mysql restore_test
mysql -e "SELECT COUNT(*) FROM restore_test.orders;"
mysql -e "DROP DATABASE restore_test;"

استبدل orders بجدول تعرفه. إذا بدا العدد صحيحًا فالنسخة تعمل. والنسخة التي لم تُستعَد أبدًا نسخة غير مُختبَرة.

وكقاعدة تقريبية، عندما تصل قاعدة البيانات إلى عشرات الغيغابايت يصبح التصدير والاستعادة بطيئين، وعندها تستحق أدوات النسخ الفعلي مثل mariadb-backup أو Percona XtraBackup أن تنظر فيها.

شغّلها على IM HOST

تعمل الاستضافة المشتركة من IM HOST على تخزين NVMe مع شهادة SSL مجانية ونسخ احتياطي يومي مجاني طوال مدة الاشتراك، فتكون لديك نسخة تعود إليها إلى جانب ملفات التصدير الخاصة بك. وعلى Linux VPS تحصل على صلاحيات root كاملة لضبط max_allowed_packet وجدولة نسخك بنفسك، والنسخ الاحتياطي اليومي متاح كإضافة اختيارية. هل تنتقل من مزود آخر؟ تنقل خدمة النقل المجانية الملفات وقواعد البيانات والبريد دون توقف، وفريق المهندسين متاح على مدار الساعة.

المزيد من مدونتنا

اكتشف المزيد من الأدلة العملية ورؤى الخدمات من فريق IM Host.

عرض كل المقالات