نقل موقع، أو استعادة نسخة احتياطية، أو استنساخ بيئة اختبار، كلها تعود إلى عمليتين: تفريغ قاعدة البيانات إلى ملف ثم تحميلها من جديد. على VPS Linux Infrawire تتم العمليتان بأوامر قليلة ومن دون أي واجهة ويب. يغطي هذا الدليل التفريغ المتّسق، والضغط، والملفات الكبيرة، وترميز الأحرف، والنقل المباشر بين الخوادم.
📋 المتطلبات المسبقة
- خادم VPS بنظام لينكس (Ubuntu 24.04 أو Debian 12) مع وصول SSH بصلاحيات root (عنوان IP وكلمة مرور root متاحان في منطقة العميل)
- MySQL أو MariaDB مثبّتة، أو على الأقل العميل (
apt install mariadb-client) - مستخدم قاعدة بيانات يملك الصلاحيات
SELECTوSHOW VIEWوTRIGGERوLOCK TABLESوEVENTعلى القاعدة المراد تفريغها - مساحة قرص حرة كافية: تحقق بالأمر
df -h
1. تصدير قاعدة البيانات باستخدام mysqldump
مع جداول InnoDB (المحرّك الافتراضي) ينشئ الخيار --single-transaction لقطة متّسقة دون قفل الجداول، فيستمر موقعك في العمل أثناء التفريغ.
Bashmysqldump -u USER -p --single-transaction --quick DBNAME > DBNAME.sql
في إصدارات MariaDB الحديثة تتوفر الأداة أيضًا باسم mariadb-dump بالخيارات نفسها.
2. تضمين الإجراءات والمشغّلات والأحداث
تُفرَّغ المشغّلات (triggers) افتراضيًا، أما الإجراءات المخزّنة والدوال والأحداث المجدولة فيجب طلبها صراحةً. تحديد مجموعة الأحرف يتجنّب مشاكل الحروف العربية والرموز التعبيرية.
Bashmysqldump -u USER -p --single-transaction --routines --triggers --events \ --default-character-set=utf8mb4 DBNAME > DBNAME.sql
صيغ مفيدة:
Bash# البنية فقط بلا صفوف mysqldump -u USER -p --no-data DBNAME > schema.sql # عدة قواعد مع عبارات CREATE DATABASE mysqldump -u USER -p --single-transaction --databases DB1 DB2 > two-dbs.sql # كل قواعد الخادم mysqldump -u root -p --single-transaction --routines --events --all-databases > all.sql
3. ضغط التفريغ باستخدام gzip
نص SQL يُضغط جيدًا. مرّر المخرجات مباشرة إلى gzip حتى لا يُكتب الملف غير المضغوط على القرص أبدًا.
Bashmysqldump -u USER -p --single-transaction --routines --events DBNAME | gzip > DBNAME_$(date +%F).sql.gz
لتجنّب كتابة كلمة المرور في كل مرة (وإبعادها عن مخرجات ps)، احفظها في ~/.my.cnf:
INI[client] user=USER password=YOUR_PASSWORD
Bashchmod 600 ~/.my.cnf
4. استيراد التفريغ
أنشئ أولًا قاعدة الوجهة بمجموعة أحرف حديثة ثم حمّل الملف.
Bashmysql -u USER -p -e 'CREATE DATABASE IF NOT EXISTS DBNAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;' mysql -u USER -p --default-character-set=utf8mb4 DBNAME < DBNAME.sql # من ملف مضغوط gunzip -c DBNAME.sql.gz | mysql -u USER -p --default-character-set=utf8mb4 DBNAME
تحذير: يحتوي التفريغ افتراضيًا على DROP TABLE IF EXISTS، لذا فإن الاستيراد إلى قاعدة موجودة يستبدل الجداول ذات الأسماء نفسها. خذ نسخة احتياطية من الوجهة أولًا.
5. التعامل مع الملفات الكبيرة
مع التفريغات التي تبلغ عدة جيجابايت، شغّل الاستيراد داخل tmux حتى لا يقطعه انقطاع اتصال SSH، واستخدم pv لمتابعة التقدم.
Bashapt install -y tmux pv tmux new -s import pv DBNAME.sql.gz | gunzip | mysql -u USER -p --max-allowed-packet=512M DBNAME
افصل الجلسة بالضغط على Ctrl+B ثم D، وعُد إليها لاحقًا بالأمر tmux attach -t import.
6. النقل المباشر إلى خادم آخر عبر SSH
لا حاجة إلى ملف وسيط: ينتقل التفريغ عبر أنبوب SSH مشفّر ويُحمَّل عند الوصول. تُقرأ بيانات الاعتماد من ~/.my.cnf (أو من المقبس المحلي للمستخدم root) على الطرفين.
Bashmysqldump --single-transaction --routines --events DBNAME | gzip \ | ssh root@NEW_VPS_IP 'gunzip | mysql DBNAME'
يجب أن تكون القاعدة DBNAME موجودة مسبقًا على الخادم الوجهة.
✅ التحقق من النتيجة
Bashgzip -t DBNAME.sql.gz && echo 'archive OK' mysql -e 'SHOW TABLES;' DBNAME mysql -e 'SELECT COUNT(*) FROM TABLENAME;' DBNAME mysql -e "SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name='DBNAME';"
قارن عدد الصفوف في بضعة جداول أساسية بين المصدر والوجهة.
🔧 استكشاف الأخطاء وإصلاحها
ERROR 1045 Access denied : اسم المستخدم أو كلمة المرور غير صحيحة، أو أن المستخدم غير مسموح له بالاتصال من هذا المضيف. جرّب أولًا mysql -u USER -p.
ERROR 2006 MySQL server has gone away : صف أو استعلام يتجاوز max_allowed_packet. ارفع القيمة على الخادم في قسم [mysqld] من الإعدادات وأعد تشغيل الخدمة، أو مرّر --max-allowed-packet=512M إلى العميل.
حروف مشوّهة بعد الاستيراد : قُرئ الملف بمجموعة أحرف خاطئة. صدّر باستخدام --default-character-set=utf8mb4 واستورد بالخيار نفسه.
ERROR 1227 أو أخطاء DEFINER : يشير التفريغ إلى مستخدم غير موجود في الوجهة. احذف هذه العبارة أثناء الاستيراد:
Bashsed -E 's/DEFINER=`[^`]+`@`[^`]+`//g' DBNAME.sql | mysql -u USER -p DBNAME
🎉 أصبح من السهل الآن نسخ قواعد بياناتك احتياطيًا واستعادتها ونقلها بين الخوادم!