دليل عملي

نقل PostgreSQL من السحابة المُدارة إلى VPS

قواعد البيانات13 دقيقةً للقراءةعدد الخطوات: 6

‫فاتورة ‫RDS تجاوزت حداً مؤلماً، أو ‫Supabase عدّلت أسعارها للتو: الإشارة واضحة، حان وقت تقييم الاستضافة الذاتية. ‫PostgreSQL على ‫VPS مخصص يعيد تكلفة ثابتة وقابلة للتنبؤ، ويرفع القيود عن الامتدادات ويزيل التقييد بمزوّد واحد. يغطي هذا الدليل الهجرة من المصادر المُدارة الثلاثة الأكثر انتشاراً — ‫AWS RDS وGoogle Cloud SQL وSupabase — بأوامر دقيقة، وأفخاخ خاصة بكل مصدر، وإجراء تحويل تدريجي يحافظ على التوافر من البداية إلى النهاية.

المحتويات· ‫لماذا تترك قاعدة البيانات المُدارة1/10
  1. 01‫لماذا تترك قاعدة البيانات المُدارة
  2. 02‫ما الذي تحتفظ به وما الذي ستديره بنفسك
  3. 03‫قبل الهجرة — قائمة المتطلبات الأساسية
  4. 04‫الهجرة من AWS RDS
  5. 05‫الهجرة من Google Cloud SQL
  6. 06‫الهجرة من Supabase
  7. 07‫الأوامر حسب المصدر
  8. 08‫التحويل التدريجي بدون توقف
  9. 09‫التحقق بعد الهجرة
  10. 10‫للمزيد

‫لماذا تترك قاعدة البيانات المُدارة

‫تحلّ قواعد البيانات المُدارة مشكلة حقيقية: إنها تزيل عمليات اليوم الأول (التثبيت والنسخ المتماثل والنسخ الاحتياطية التلقائية). لكن نموذج أسعارها مصمم ليتصاعد بشكل غير خطي مع النمو. على ‫AWS RDS، يُفوتر كل مكوّن بشكل منفصل: حوسبة النسخة، والتخزين ‫gp3 لكل جيجابايت، و‫IOPS المُخصصة، وعقدة ‫Multi-AZ الثانوية، والنسخ الاحتياطية خارج النافذة المُضمّنة، وعمليات نقل البيانات الصادرة. نسخة db.r6g.xlarge بتوافر عالٍ مع 200 جيجابايت من تخزين ‫gp3 يمكن أن تتجاوز 800 دولار شهرياً بسهولة على ‫us-east-1؛ عند 500 جيجابايت، تتجاوز 3000 دولار شهرياً. تعمل نفس أعباء العمل على ‫VPS مخصص بجزء بسيط من هذه التكلفة.

‫التكلفة ليست المتغير الوحيد. قيود الامتدادات عائق تقني ملموس: ‫pgvector على ‫RDS متاح منذ 2023، لكن ‫pg_graphql أو بعض إصدارات ‫d_btree_gist ليست كذلك. على ‫Supabase، الكتالوج أوسع لكنه مرتبط بالمنصة. الامتثال للبيانات هو المحرك الثالث: تخزين قاعدة البيانات في مركز البيانات الذي تختاره، دون نقل بين مناطق مُفوتر، يغير المعادلة للبُنى الخاضعة للائحة ‫GDPR أو سياسات إقامة البيانات.

‫ما الذي تحتفظ به وما الذي ستديره بنفسك

  • ‫تحتفظ بـ: ‫PostgreSQL نفسه بالإصدار الذي تختاره، وجميع بياناتك، وامتداداتك، وأدوارك وامتيازاتك، وسلاسل الاتصال بمجرد تحديث متغير DATABASE_URL.
  • ‫تحتفظ بـ: الأداء — على ‫VPS NVMe مُحسَّن بشكل جيد، تعادل عمليات القراءة والكتابة العشوائية لـ ‫PostgreSQL على الأقل تلك الخاصة بنسخة مُدارة من نفس الفئة.
  • ‫تدير: النسخ الاحتياطية — pg_dump بجدول ‫cron، أو pg_basebackup لنسخة فيزيائية؛ يجب تخزين الملفات خارج الخادم (تخزين الكائنات، ‫VPS ثانٍ).
  • ‫تدير: التحديثات الصغيرة (تصحيحات الأمان) والترقيات الكبيرة (هجرة الإصدار) — التكرار منخفض والإجراء موثق، لكن لا أحد يطبقها نيابةً عنك.
  • ‫تدير: اتصالات ‫SSL — إنشاء شهادة، تهيئة ssl = on في postgresql.conf، فرض ‫TLS في pg_hba.conf؛ بدون هذا تنتقل البيانات بنص واضح.
  • ‫تدير: المراقبة — pg_stat_statements وpg_stat_activity وتنبيهات على مساحة القرص والاتصالات النشطة؛ تختفي لوحات التحكم عند المزوّد مع قاعدة البيانات المُدارة.

‫قبل الهجرة — قائمة المتطلبات الأساسية

‫قبل تشغيل أول pg_dump، أربع نقاط تحدد نجاح الهجرة.

‫إصدار PostgreSQL: المصدر مقابل الوجهة. يمكن استعادة تفريغ أنتجه pg_dump من الإصدار ‫N على الإصدار ‫N أو أعلى، وليس أدنى. تحقق من إصدار المصدر: psql -h <endpoint> -U <user> -c 'SELECT version();'. على ‫VPS، ثبّت نفس الإصدار الرئيسي أو أعلى من مستودع ‫PGDG.

‫الامتدادات النشطة. أدرج الامتدادات المثبتة على المصدر: SELECT extname, extversion FROM pg_extension ORDER BY extname;. بعضها متاح بشكل عام (uuid-ossp وhstore وpgcrypto). أخرى تتطلب حزمة نظام إضافية أو تجميعاً من المصدر. امتدادات ‫Supabase الخاصة (pg_graphql وpg_net وpgsodium) غير موجودة في ‫PostgreSQL الافتراضي.

‫حجم قاعدة البيانات. SELECT pg_size_pretty(pg_database_size('<base>')); يعطي الحجم المنطقي. على ‫VPS، خطط لمساحة القرص اللازمة للتفريغ نفسه، وقاعدة البيانات المستعادة، وهامش 20% لملفات ‫WAL ومؤشرات الاستعادة المؤقتة.

‫الاتصالات النشطة. قاعدة البيانات تحت حركة المرور لا يمكن تفريغها بشكل نظيف مع معاملات طويلة جارية. تحقق: SELECT count(*), state FROM pg_stat_activity GROUP BY state;. إذا استمرت اتصالات بحالة idle in transaction لعدة دقائق، حدد تلك الجلسات وأنهها قبل تشغيل تفريغ الهجرة.

‫الهجرة من AWS RDS

‫يفرض ‫RDS ‫TLS على الاتصالات الواردة (rds.force_ssl = 1 افتراضياً على النسخ الحديثة). لذا فإن الخيار --sslmode=require ضروري على pg_dump، وإلا فإن الاتصال يُرفض أو يُنشأ بدون تشفير حسب تهيئة النسخة.

‫استخدم نقطة نهاية القراءة (‫Read Replica) للتفريغ حيثما أمكن لتجنب إضافة حمل على النسخة الأساسية أثناء الهجرة.

export PGPASSWORD='كلمة-مرورك'
pg_dump \
  -h your-instance.xxxx.rds.amazonaws.com \
  -U your_user \
  --sslmode=require \
  -Fc \
  -f /tmp/dump-rds.pgc \
  your_database

‫ثم استعد على ‫VPS بشكل متوازٍ لتسريع الاستيراد:

pg_restore \
  --no-owner \
  --no-privileges \
  -h localhost \
  -U your_vps_user \
  -d your_database \
  -j 4 \
  /tmp/dump-rds.pgc

‫الخياران --no-owner و--no-privileges ضروريان: ينشئ ‫RDS أدواراً داخلية (rdsadmin وrds_superuser) غائبة عن أي ‫PostgreSQL خارج ‫AWS. المتغيرات غير القابلة للنقل من ‫RDS: rds.force_ssl وأي معلمة ذات بادئة rds. هي معلمات نظام AWS خاصة غير موجودة في postgresql.conf القياسي.

‫الهجرة من Google Cloud SQL

‫يقدم ‫Cloud SQL مسارَي تصدير: ‫Cloud SQL Auth Proxy (موصى به للاتصالات البرمجية) والتصدير إلى حاوية ‫GCS (موصى به للتفريغات الكبيرة أو الهجرات أحادية الاتجاه).

‫عبر Cloud SQL Auth Proxy (اتصال مباشر، مناسب للقواعد < 10 جيجابايت):

cloud_sql_proxy -instances=my-project:europe-west1:my-instance=tcp:5433 &

export PGPASSWORD='your-password'
pg_dump \
  -h 127.0.0.1 \
  -p 5433 \
  -U your_user \
  -Fc \
  -f /tmp/dump-cloudsql.pgc \
  your_database

‫عبر تصدير GCS (موصى به للقواعد الكبيرة):

gcloud sql export sql my-instance \
  gs://my-bucket/dump-cloudsql.sql \
  --database=your_database \
  --offload

gsutil cp gs://my-bucket/dump-cloudsql.sql /tmp/

psql -h localhost -U your_vps_user -d your_database \
  -f /tmp/dump-cloudsql.sql

‫الفخ الرئيسي لـ ‫Cloud SQL: الخيار --offload ينقل معالجة التفريغ إلى عامل ثانوي ويقلل التأثير على النسخة الأساسية. يُنشئ ‫Cloud SQL أيضاً مستخدم cloudsqladmin — طبّق --no-owner --no-privileges على الاستعادة كما هو الحال مع ‫RDS.

‫الهجرة من Supabase

‫يكشف ‫Supabase وصولاً مباشراً لـ ‫PostgreSQL عبر ‫URI اتصال متاح في إعدادات المشروع (Settings > Database > Connection string > URI).

export DATABASE_URL="postgresql://postgres:[email protected]:5432/postgres"

pg_dump \
  "$DATABASE_URL" \
  --sslmode=require \
  -Fc \
  --no-owner \
  --no-privileges \
  -f /tmp/dump-supabase.pgc

‫الامتدادات الموجودة على Supabase والغائبة عن VPS الافتراضي. هذا هو الفخ الرئيسي عند الهجرة من ‫Supabase:

- ‫pgvector: متاح على ‫Supabase، يجب تثبيته يدوياً على ‫VPS (sudo apt install postgresql-17-pgvector على ‫Debian/Ubuntu، ثم CREATE EXTENSION vector;).
- ‫pg_graphql: امتداد ‫Supabase الخاص الذي يكشف نقطة نهاية ‫GraphQL تلقائية. غير موجود في مستودعات ‫APT القياسية — يتطلب التجميع من المصدر (‫Rust + cargo-pgrx) أو إعادة كتابة طبقة الوصول ‫GraphQL خارج قاعدة البيانات.
- ‫pg_net: يسمح بطلبات ‫HTTP من دوال ‫SQL. غائب عن الحزم القياسية — أعد كتابة الاستخدامات خارج قاعدة البيانات.
- ‫pgsodium: تشفير على مستوى قاعدة البيانات. تكامله مع ‫Vault خاص بـ ‫Supabase.
- ‫http: امتداد مجتمعي متاح كـ postgresql-17-http على ‫Debian/Ubuntu.

‫قبل تشغيل التفريغ، أدرج الامتدادات النشطة بشكل شامل: SELECT extname FROM pg_extension WHERE extname NOT IN ('plpgsql');

‫الأوامر حسب المصدر

مرّر الجدول أفقيًا

‫المصدر‫أمر pg_dump‫الأفخاخ المعروفة‫المتغير الذي يجب إعادة تهيئته
‫AWS RDS`pg_dump -h <endpoint> -U <user> --sslmode=require -Fc -f dump.pgc <base>`‫`--no-owner --no-privileges` مطلوب؛ أدوار `rdsadmin`/`rds_superuser` غائبة عن ‫VPS‫`rds.force_ssl` → استبدله بـ `ssl = on` في `postgresql.conf`
‫Google Cloud SQL‫`pg_dump -h 127.0.0.1 -p 5433 -U <user> -Fc -f dump.pgc <base>` عبر ‫Auth Proxy، أو `gcloud sql export sql` → حاوية ‫GCS‫`--offload` لتقليل التأثير على الأساسي؛ `--no-owner --no-privileges` ضد `cloudsqladmin`‫Auth Proxy للإزالة؛ الاتصال المباشر بـ ‫VPS كبديل
‫Supabase`pg_dump "$DATABASE_URL" --sslmode=require -Fc --no-owner --no-privileges -f dump.pgc`‫`pg_graphql` و`pg_net` و`pgsodium` غائبة عن ‫VPS الافتراضي؛ `pgvector` للتثبيت يدوياً‫‫URL اتصال Supabase → `DATABASE_URL` مباشر لـ ‫VPS؛ ‫Supabase Auth للفصل

‫التحويل التدريجي بدون توقف

  1. ‫لقطة أولاً — حفظ المصدر في نقطة زمنية

    ‫قبل أي عملية، خذ لقطة يدوية لنسخة المصدر من وحدة تحكم المزوّد (‫RDS: Actions > Take snapshot؛ ‫Cloud SQL: Operations > Create backup؛ ‫Supabase: Settings > Backups > Trigger backup). هذه اللقطة شبكة أمانك: تتيح لك العودة إلى الحالة الدقيقة لقاعدة البيانات قبل الهجرة.

  2. ‫pg_dump إنتاج — تفريغ كامل لقاعدة البيانات الإنتاجية

    ‫شغّل التفريغ باستخدام الأمر المناسب لمصدرك (انظر القسم السابق). سجّل وقت البداية والنهاية للتفريغ — أي معاملات تُؤكَّد بعد بدء التفريغ لن تكون في الملف. على ‫RDS وCloud SQL، استخدم نقطة نهاية القراءة إن كانت متاحة. تحقق من أن ملف ‫dump.pgc غير فارغ وأكمل بدون أخطاء: ls -lh /tmp/dump-*.pgc.

  3. ‫pg_restore VPS — الاستعادة والتحقق الأولي

    ‫على ‫VPS، أنشئ قاعدة البيانات الهدف واستعد: createdb -U postgres your_database && pg_restore --no-owner --no-privileges -h localhost -U your_user -d your_database -j 4 /tmp/dump-source.pgc. بعد اكتمال الاستعادة، تحقق من أعداد الصفوف في الجداول الحيوية: SELECT relname, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC LIMIT 20; على كلا النسختين وقارن الأرقام.

  4. ‫قراءة فقط على المصدر — تجميد قاعدة البيانات الأصلية

    ‫اختر نافذة تحويل (ليل، عطلة نهاية الأسبوع، فترة انخفاض الحركة). في بداية هذه النافذة، ضع قاعدة البيانات المصدر في وضع القراءة فقط لإيقاف الفجوة بين المصدر والوجهة: ALTER DATABASE your_database SET default_transaction_read_only = on;. هذه الخطوة هي اللحظة الوحيدة التي يكون فيها توقف قصير للكتابة حتمياً — وعادةً ما يستغرق أقل من 30 ثانية.

  5. ‫التحقق من أعداد الصفوف — التناسق قبل التحويل

    ‫مع المصدر في وضع القراءة فقط، شغّل فحصاً نهائياً لعدد الصفوف جدولاً بجدول: psql -h <source> -U <user> -c 'SELECT count(*) FROM your_main_table;' وقارن مع psql -h localhost -U your_user -c 'SELECT count(*) FROM your_main_table;'. إذا استمرت فجوة، شغّل تفريغاً تدريجياً للسجلات المنشأة بعد وقت بدء التفريغ الأول وأدرجها حتى التقارب.

  6. ‫تبديل DATABASE_URL — التطبيق يشير إلى VPS

    ‫حدّث متغير البيئة DATABASE_URL للإشارة إلى ‫VPS: postgresql://your_user:your-password@<VPS-IP>:5432/your_database?sslmode=require. أعد تشغيل التطبيق. تحقق من نجاح أول الاستعلامات وخلو السجلات من أخطاء الاتصال وأن الكتابات تصل إلى ‫VPS. يبقى المصدر متاحاً في وضع القراءة فقط لـ 24 إلى 48 ساعة أخرى — لا تحذفه فوراً.

‫التحقق بعد الهجرة

‫أربعة فحوصات تجريها في الساعة التالية للتحويل.

‫أعداد الصفوف. على أكثر عشرة جداول حجماً، قارن أعداد المصدر والوجهة. الفجوة الصفرية تؤكد التقاط جميع المعاملات؛ فجوة متبقية من عدة صفوف قد تشير إلى معاملات كانت جارية وقت التحويل.

‫المجاميع الاختبارية. على الجداول الحيوية، احسب مجموعاً اختبارياً للتحكم: SELECT md5(string_agg(id::text || amount::text, ',' ORDER BY id)) FROM orders; وقارن النتيجة على كلا النسختين. المجموع المتطابق يؤكد سلامة البيانات صفاً بصف.

‫اختبار الامتدادات. لكل امتداد يستخدمه التطبيق، شغّل استعلام اختبار بسيط: SELECT 'test'::vector(3) لـ ‫pgvector، SELECT gen_random_uuid() لـ pgcrypto. الامتداد المفقود أو المهيأ بشكل خاطئ يظهر فوراً.

‫اتصالات التطبيق. تحقق في سجلات التطبيق أن الاتصالات تُنشأ على ‫VPS لا على قاعدة البيانات القديمة. تحقق أيضاً من نشاط اتصالات ‫SSL: SELECT ssl, client_addr FROM pg_stat_ssl JOIN pg_stat_activity USING (pid) WHERE client_addr IS NOT NULL LIMIT 5;.

‫التراجع في أقل من 5 دقائق. لمدة 24 إلى 48 ساعة بعد التحويل، يبقى المصدر حياً في وضع القراءة فقط. إذا اكتُشفت مشكلة حاجبة، التراجع فوري: أعد DATABASE_URL القديم في متغير البيئة وأعد تشغيل التطبيق. لا فقدان بيانات — المصدر لم يُعدَّل منذ التحويل (هو في وضع القراءة فقط) و‫VPS سجّل الكتابات الجديدة منذ التحويل. لا تحذف المصدر أبداً قبل 48 ساعة من الاستقرار على ‫VPS.

‫للمزيد

‫يغطي هذا الدليل الهجرة أحادية الاتجاه — الإجراء الأكثر شيوعاً لمغادرة مزوّد مُدار. ثلاثة مواضيع تكميلية تستحق الاستكشاف حسب سياقك.

PostgreSQL المستضاف ذاتياً مقابل Amazon RDS — مقارنة ‫ROI مع أرقام بين النموذجين، مع عتبات حجم قاعدة البيانات وحركة المرور التي يصبح عندها الاستضافة الذاتية واضحة الأفضلية.

استضافة PostgreSQL على VPS — التهيئة التفصيلية بعد التثبيت: postgresql.conf وpg_hba.conf و‫pgBouncer والمراقبة والنسخ الاحتياطية والتصليب.

PostgreSQL بتوافر عالٍ مع Patroni على VPS — إذا كان اتفاقية مستوى الخدمة تتطلب ‫failover تلقائياً، فإن ‫Patroni على كتلة ثلاثة عقد يعيد إنتاج ضمانات ‫RDS Multi-AZ أو ‫Cloud SQL HA بدون علاوة المزوّد.

‫انشر قاعدة بيانات PostgreSQL على VPS مخصص

‫وصول root، تخزين SSD NVMe، IPv4 مضمّن، دون رسوم إضافية لكل جيجابايت. اختر إعدادك وهاجر بثقة.

بحاجة إلى مساعدة؟

تصفّح مركز المساعدة والأسئلة الشائعة، أو تواصل مع فريقنا — معاودة اتصال أو WhatsApp أو بريد إلكتروني. الدعم بـالعربية والفرنسية والإنجليزية.

راسلنا على WhatsAppيُفتح في علامة تبويب جديدة