Englishworlber.sa
علم المملكة العربية السعوديةشركة سعودية · الرياض

Operations

ترقية PostgreSQL لإصدار رئيسي دون توقف عبر النسخ المنطقي

انقل PostgreSQL من 14 إلى 16 أو 17 أو 18 بتوقف لا يتجاوز دقائق عبر النسخ المنطقي: التسلسلات، هوية النسخ، فتحات WAL، Patroni، والانتقال وخطة التراجع.

١ نوفمبر ٢٠٢٦ · 7 دقيقة قراءة

ترقية PostgreSQL لإصدار رئيسي دون توقف عبر النسخ المنطقي وPatroni وخطة تراجع

مدير قواعد البيانات يعرف هذا المشهد جيدًا. طلب تغيير يحجز ليلة الخميس كاملة. يُوقَف التطبيق الساعة الحادية عشرة، ثم pg_dump، ثم الاستعادة على الإصدار الجديد، وإعادة بناء الفهارس، واختبارات سريعة، والأمل أن يعود كل شيء قبل أن تفتح الفروع صباح الأحد. بعدها تُجرَّب الاستعادة على نسخة من بيانات الإنتاج، فتأخذ معظم الليل. لنفترض ثماني أو تسع ساعات على قاعدة كبيرة. فيتأجل المشروع ربعًا آخر.

من يدير PostgreSQL في بنك أو جهة حكومية أو منشأة خاضعة للتنظيم في المملكة مرّ بهذا غالبًا. وفي الأثناء خرج الإصدار 13 من دعم المجتمع، ويلحقه الإصدار 14 في نوفمبر 2026. أما ملاحظة التدقيق عن "برمجيات غير مدعومة" فتعود مع كل مراجعة.

يوجد طريق آخر من 14 إلى 16 أو 17 أو 18، والتوقف فيه بالثواني أو بدقائق قليلة. تبني العنقود (Cluster) الجديد بجانب القديم، وتبقيه متزامنًا عبر النسخ المنطقي (Logical Replication)، ثم تنقل الاتصالات متى كنت جاهزًا. في هذا المقال نشرح كيف يعمل هذا المسار، وأين يتعثر، وما شكل خطة التراجع التي تُنفَّذ فعلًا، لا التي تُكتب في شريحة عرض.

ثلاث طرق، ولكل منها ثمن

لعبور إصدار رئيسي ثلاث طرق معروفة.

التفريغ والاستعادة (pg_dump / pg_restore). بسيطة وآمنة جدًا. مشكلتها مدة التوقف، وهي تكبر مع حجم البيانات. الكتابة متوقفة طوال التفريغ والاستعادة وبناء الفهارس وتشغيل ANALYZE. وفي نظام أساسي بحجم عدة تيرابايت، الليلة طويلة في أحسن الأحوال.

الأداة pg_upgrade. أسرع بكثير، خصوصًا مع --link، لأنها تعيد كتابة جداول النظام وتستخدم ملفات البيانات نفسها. التوقف غالبًا دقائق. لكنها ترقية في المكان. العنقود القديم يتوقف، وبمجرد أن تشغّل الجديد بوضع الربط وتقبل الكتابة يصعب الرجوع إلى الإصدار القديم. ويجب أن تتوفر كل إضافة (Extension) بإصدار متوافق مع النسختين. وبعدها تحتاج إلى ANALYZE، لأن إحصاءات المخطِّط لا تنتقل (الإصدار 18 غيّر هذا جزئيًا)، وبدونها قد تكون الساعة الأولى في الإنتاج بطيئة.

النسخ المنطقي. العنقود الجديد قاعدة بيانات مستقلة تعمل على الإصدار الجديد. القديم يواصل خدمة الإنتاج والجديد يلحق به. أنت تختار لحظة الانتقال، ويبقى القديم جاهزًا للرجوع إليه. وهذا ما يتناوله المقال.

لا توجد طريقة خاطئة بينها. pg_upgrade --link على نظام جرى التدرّب عليه خيار ممتاز إن كانت نافذة من 10 إلى 30 دقيقة مقبولة. النسخ المنطقي يستحق تعقيده الإضافي حين تقترب النافذة المسموحة من الصفر، أو حين تريد الإدارة طريق رجوع لا يمرّ بالاستعادة من النسخ الاحتياطية.

المسار باختصار

  1. جهّز الهدف. ثبّت الإصدار الجديد على خوادم (أو Pods) جديدة، بالإضافات والإعدادات والأدوار نفسها. ومع Patroni يعني هذا عنقود Patroni جديدًا له قائده ونسخه.

  2. انسخ المخطط (Schema). النسخ المنطقي لا ينقل أوامر DDL. شغّل pg_dump --schema-only على المصدر وطبّقه على الهدف. احتفظ بالسكربت، فستحتاجه مجددًا.

  3. النشر والاشتراك. على المصدر: CREATE PUBLICATION upgrade_pub FOR ALL TABLES; وعلى الهدف: CREATE SUBSCRIPTION upgrade_sub CONNECTION '...' PUBLICATION upgrade_pub; يأخذ الاشتراك نسخة أولية من كل جدول، ثم يتابع التغييرات من سجل WAL.

  4. انتظر اللحاق. راقب pg_stat_subscription على الهدف وpg_replication_slots على المصدر حتى يقترب التأخر من الصفر ويثبت عنده.

  5. الانتقال. أوقف الكتابة على المصدر لوقت قصير. تأكد أن الهدف طبّق كل شيء، واضبط التسلسلات (Sequences)، وانقل الاتصالات، وابدأ الكتابة على الإصدار الجديد.

  6. أبقِ طريق الرجوع مفتوحًا (التفاصيل لاحقًا)، ولا توقف العنقود القديم إلا حين تطمئن.

النسخة الأولية قد تأخذ ساعات على قاعدة مزدحمة. لا مشكلة في ذلك، فالإنتاج يعمل طوالها. الخطوة الخامسة وحدها تحتاج تجميد الكتابة.

التفاصيل التي تُفشل الانتقال

الخطوات تتسع في شاشة واحدة. العمل الحقيقي في النقاط التالية، وكل واحدة منها أفشلت انتقالًا حقيقيًا في مكان ما.

كل جدول يحتاج هوية نسخ (Replica Identity)

لكي تنتقل أوامر UPDATE وDELETE يجب أن يعرف المشترك أي صف هو المقصود. يتطلب ذلك مفتاحًا أساسيًا، أو فهرسًا فريدًا مضبوطًا عبر REPLICA IDENTITY USING INDEX، أو REPLICA IDENTITY FULL كحل أخير. الجدول الذي يخلو من ذلك تفشل عليه عمليات التحديث والحذف في المصدر نفسه بمجرد إضافته إلى النشر. وFULL يعمل، لكنه يجبر المشترك على البحث في الجدول عن كل صف تغيّر، وهذا قد يكون بطيئًا جدًا مع الجداول الكبيرة.

ابحث عن هذه الجداول قبل البدء:

SELECT c.oid::regclass
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
AND NOT EXISTS (SELECT 1 FROM pg_index i
WHERE i.indrelid = c.oid AND i.indisprimary);

في مخططات أنظمة ERP والأنظمة المصرفية الأساسية القديمة ستجد منها غالبًا أكثر مما تتوقع.

التسلسلات لا تُنسخ

في الإصدارات التي يعمل عليها معظمكم اليوم، ينقل النسخ المنطقي صفوف الجداول ولا ينقل قيم التسلسلات. بعد الانتقال، أول إدراج في جدول بعمود serial أو عمود هوية سيحاول استخدام قيمة موجودة أصلًا، فيفشل بخطأ تكرار المفتاح.

الحل بسيط، لكن مكانه دليل التشغيل. أثناء تجميد الكتابة اقرأ القيمة الحالية لكل تسلسل في المصدر، ونفّذ setval() على الهدف مع هامش إضافي. حوّله إلى سكربت، وجرّبه في التدريب، وتحقق من النتيجة قبل فتح الكتابة.

تغيير المخطط أثناء الترحيل يكسر النسخ

تغييرات المخطط لا تُنقل. فإذا أُضيف عمود في المصدر والاشتراك يعمل، يتوقف التطبيق على الهدف مع وصول أول صف يحمل هذا العمود. اتفق مع فرق التطوير على تجميد المخطط طوال فترة الترحيل. وإن كان تغيير ما لا يحتمل الانتظار، فطبّقه على الهدف أولًا ثم على المصدر.

ما لا ينتقل أصلًا

الكائنات الكبيرة (pg_largeobject) لا تُنسخ. ولا محتوى العروض المادية (Materialized Views)، ولا أي شيء خارج الجداول العادية، ولا الجداول غير المسجلة (Unlogged). إن كان تطبيقك يخزّن مستندات عبر دوال lo_*، فخطط لنقلها منفصلة أثناء التجميد.

المعاملات الطويلة وتضخم الـ Slot

يحتفظ المصدر بملفات WAL لفتحة النسخ (Replication Slot) حتى يؤكد المشترك استلامها. إن تأخر المشترك، أو أعاقت معاملة طويلة في المصدر تقدّم الفتحة، تتراكم الملفات في pg_wal. وفي نظام مزدحم قد يمتلئ القرص ويتوقف الإنتاج. أي أن الترقية تتسبب بالضبط فيما جاءت لتجنّبه.

قبل الترحيل وأثناءه:

  • ابحث في pg_stat_activity عن الجلسات الطويلة والجلسات العالقة في حالة idle in transaction، واتفق مع أصحاب التطبيقات على طريقة التعامل معها.

  • اضبط max_slot_wal_keep_size على المصدر حتى لا تملأ فتحة عالقة القرص. ستُبطَل الفتحة بدل ذلك. مزعج، لكنه قابل للمعالجة.

  • ضع تنبيهات على حجم pg_wal وعلى تأخر الفتحة، لا على مجرد أن "النسخ يعمل".

الإضافات واختلافات جداول النظام

كل إضافة تستخدمها تحتاج إصدارًا يُثبَّت على الإصدار الرئيسي الجديد. افحص مبكرًا PostGIS وpg_partman وpgaudit وأي إضافات C مطوّرة داخليًا. واقرأ ملاحظات كل إصدار تتخطاه. الانتقال من 14 إلى 17 يعني قراءة أقسام عدم التوافق في 15 و16 و17، لا في 17 وحده. الدوال المحذوفة، وتغيير الصلاحيات الافتراضية على المخطط public (في الإصدار 15)، واختلافات المخطِّط، كلها تظهر في الاختبار ولا تظهر في خطة الترحيل.

Patroni لا يُجري الترقية الرئيسية عنك

Patroni يحافظ على التوفر العالي داخل الإصدار الرئيسي الواحد. عبور إصدار رئيسي ليس عملية تبديل يستطيع تنفيذها. مع النسخ المنطقي تبني عنقود Patroni ثانيًا على الإصدار الجديد، وتنسخ إلى قائده، ثم تنقل التطبيق إليه. الميزة هنا أن التوفر العالي يبقى سليمًا في الجهتين طوال الوقت. القديم يحتفظ بنسخه وآلية التحويل التلقائي (Failover)، والجديد عالي التوفر بالكامل قبل أن يستقبل أي كتابة من الإنتاج.

وهناك تفصيل يجب حسابه. حتى الإصدارات الحديثة كانت فتحات النسخ المنطقي تعيش على الخادم الرئيسي فقط، وتضيع عند التحويل التلقائي فينكسر الاشتراك. الإصدار 17 أضاف فتحات يمكن مزامنتها مع الخوادم الاحتياطية. وإن كان المصدر أقدم، فقرّر من الآن ماذا ستفعل إن تعطّل الخادم الرئيسي القديم أثناء نافذة الترحيل. الجواب المعتاد: إعادة إنشاء الاشتراك والنسخ الأولي من جديد.

يوم الانتقال

حين يقترب التأخر من الصفر، يسير الانتقال عادةً هكذا:

  1. جمّد الكتابة في المصدر. أوقف التطبيق مؤقتًا، أو اسحب صلاحيات الكتابة من أدوار التطبيق، أو نفّذ PAUSE في PgBouncer. الإيقاف عند مجمّع الاتصالات غالبًا الأنظف، لأن العملاء ينتظرون بدل أن يفشلوا.

  2. تأكد أن الهدف لحق. قارن pg_current_wal_lsn() في المصدر مع latest_end_lsn في pg_stat_subscription على الهدف.

  3. زامن التسلسلات بالسكربت المُعدّ.

  4. نفّذ الفحوصات التي تدربت عليها. عدد الصفوف في الجداول الرئيسية، وبعض المجاميع المالية التي يجب أن تتطابق.

  5. انقل الاتصالات. وجّه PgBouncer أو اسم DNS أو عنوان IP الافتراضي إلى العنقود الجديد. إن كانت التطبيقات تتصل بأسماء الخوادم مباشرة فهذه أطول خطوة، فعالج ذلك قبل يوم الترحيل.

  6. استأنف. الكتابة الآن على الإصدار الجديد.

مع مجمّع اتصالات في الواجهة وسكربت جرى التدرب عليه، يستمر التجميد عادةً من ثوانٍ إلى دقائق قليلة. معظم هذا الوقت للتحقق، فلا تختصره.

خطة تراجع تعمل فعلًا

"سنستعيد من النسخة الاحتياطية" ليست خطة تراجع لنظام أساسي. ستخسر كل معاملة جرت بعد تلك النسخة.

النسخ المنطقي يسمح بأفضل من ذلك. قبل استئناف الكتابة على العنقود الجديد، أنشئ عليه نشرًا معاكسًا، وأنشئ اشتراكًا في العنقود القديم مع copy_data = false لأن البيانات موجودة أصلًا. بهذا يستقبل القديم كل تغيير يجري على الإصدار الجديد. لو ظهرت مشكلة جدية في الأيام الأولى، كخطة استعلام انهارت أو إضافة تتصرف بشكل مختلف، تجمّد الكتابة مجددًا، وتزامن التسلسلات في الاتجاه المعاكس، وتعيد الاتصالات دون خسارة بيانات.

النسخ المنطقي من إصدار رئيسي أحدث إلى أقدم مدعوم. ومع ذلك اختبر هذا الاتجاه في التدريب. وحدّد مسبقًا كم ستُبقي طريق الرجوع والعنقود القديم، ومن يملك صلاحية إعلان التراجع.

التدريب على بيانات حقيقية

كل ما سبق سيظهر في التدريب، وهذا بالضبط المكان الذي تريد أن تكتشفه فيه. نفّذ الإجراء كاملًا مرة واحدة على الأقل على نسخة حديثة من بيانات الإنتاج، في بيئة تشبه الإنتاج:

  • قِس مدة النسخة الأولية، وراقب نمو WAL في المصدر خلالها.

  • شغّل تطبيقك الفعلي على الإصدار الجديد، أو على الأقل مهام الدُفعات والتقارير الحرجة، وقارن خطط الاستعلامات البطيئة.

  • نفّذ سكربت الانتقال من أوله إلى آخره، بما فيه التسلسلات ونقل الاتصالات، ثم سكربت التراجع.

  • دوّن الأزمنة. عليها يُبنى طلب التغيير.

وفي البيئات الخاضعة للتنظيم، تقرير التدريب هو ما ستطلبه لجنة التغيير والمدققون.

دور ورلبر

ورلبر موزّع معتمد لـ CYBERTEC في المملكة العربية السعودية، ولديها فريق في الرياض. تشغّل CYBERTEC قواعد PostgreSQL في بيئات إنتاج المؤسسات منذ سنوات، وتوزيعتها المؤسسية PGEE مبنية على PostgreSQL مع التوفر العالي عبر Patroni. إن كنت تخطط لترقية رئيسية، أو للانتقال إلى PGEE في الوقت نفسه، نساعدك في فحص المخطط بحثًا عن جداول بلا هوية نسخ، وتخطيط مسار الإضافات، وتصميم الانتقال والتراجع، والتدرّب عليهما مع فريقك.

أخبرنا بالإصدار الذي تعمل عليه، وحجم قاعدة البيانات، ونافذة الصيانة المتاحة لك: خطّط لترقية PostgreSQL مع ورلبر.

الخطوة التالية

تحدث مع مهندسي Worlber

أرسل لنا بيئتك وهدفك. سنوضح لك ما يصلح، وما لا يصلح، والخطوة الآمنة التالية.

contactus@worlber.com

ترقية PostgreSQL لإصدار رئيسي دون توقف عبر النسخ المنطقي | Worlber Insights