قواعد البيانات · الموثوقية

النسخ المنطقي في PostgreSQL: راقب الانحراف لا التأخر فقط

دليل تشغيل إنتاجي للنسخ المنطقي في PostgreSQL يشمل تعارضات التطبيق واحتجاز WAL وانحراف Schema والمطابقة وFailover للـSlots والاستعادة الآمنة.

المسار المرتبطالسحابة وDevOps وKubernetes
رسم تصوري أصلي لقاعدتي بيانات يربطهما تدفق مرتب، بينما تكشف بوابة تحقق كتلة مفقودة وتعارضًا؛ وليس واجهة حقيقية من PostgreSQL.
تصوّر بصري للفكرة — يتبعه شرح ومخطط تنفيذي داخل المقال.

قد تعرض لوحة النسخ المنطقي Worker متصلًا وفجوة LSN صغيرة بينما تكون بيانات المستقبِل منحرفة بالفعل. ربما جرى تخطي Update لأن الصف غير موجود، أو عدّل تطبيق محلي المفتاح نفسه، أو بقي Sequence عند قيمة قديمة، أو أضاف ترحيل في المصدر عمودًا لا يقبله المستقبِل. يجيب التأخر عن سؤال: «كم بقي على تطبيق التدفق؟» لكنه لا يجيب: «هل قاعدتا البيانات متكافئتان بما يكفي للمهمة؟»

تصف وثائق النسخ المنطقي الحالية نموذج Publish/Subscribe يعتمد على Replication Identity. يأخذ Snapshot أولي ثم يطبق تغييرات المصدر بالترتيب، مع اتساق المعاملات داخل Subscription واحدة. هذا ضمان قوي لمسار النقل والتطبيق، لكنه ليس وعدًا بأن كل كائن في قاعدة البيانات أو كتابة محلية أو خطأ تشغيلي سيبقى متطابقًا.

هذا شرح مبني على وثائق PostgreSQL 18 الحالية، وتم التحقق منها في 28 سبتمبر 2026؛ وليس خبرًا عن ميزة أطلقت اليوم. الهدف التشغيلي هو تحويل عبارة «النسخ يعمل» إلى نموذج صحة متعدد الطبقات بأربع إشارات مستقلة: النقل، واحتجاز الـSlot، وسلوك التطبيق، وصحة المحتوى.

ابدأ بالعقد لا بسلسلة الاتصال

حدّد وظيفة المستقبِل بدقة. نسخة التحليلات قد تقبل ثواني من التأخر وقد تحتوي عمدًا أعمدة أقل. ترحيل بلا توقف يحتاج توافق Schema أشد وضبط Sequences وخطة Cutover مختبرة. وقد تستخدم قاعدة خدمة أخرى Row Filters وColumn Lists، فلا يكون التطابق الكامل مع المصدر متوقعًا أو مفيدًا.

سجّل عقد كل Publication: الجداول، والفلاتر، والأعمدة، وعمليات DML المسموحة، وReplication Identity، وهل المستقبِل للقراءة فقط. يوضح مرجع CREATE PUBLICATION أن النشر الافتراضي يشمل Insert وUpdate وDelete وTruncate، وأن جداول Update/Delete تحتاج هوية نسخ، وأن Column Lists لا تغير سلوك `TRUNCATE`. كما يمكن للنشر على مستوى Schema ضم جداول وأقسام دائمة مستقبلية. عامل هذه الاختيارات كواجهة API تخضع لإدارة تغيير.

لا تطبق Publications المتداخلة داخل Subscription واحدة الصف نفسه مرتين، لكن تعدد Subscriptions المتداخلة يحتاج حذرًا. تحذر وثائق Subscription صراحة من تداخل الكائنات بين اشتراكات متعددة لنفس الزوج. احتفظ بخريطة من Publication إلى Subscription إلى Slot كي تظهر الملكية وقت العطل.

راقب أربع طبقات لا رقم تأخر واحدًا

الطبقة الأولى هي النقل. تعرض وثائق المراقبة في `pg_stat_subscription` صفًا لكل Subscription Worker. يوجد عادة Apply Worker واحد للاشتراك المفعل، وقد تضيف مزامنة الجداول والتطبيق المتوازي Workers أخرى. أنذر عند اختفاء صف التطبيق المتوقع، أو تجاوز عمر `last_msg_receipt_time` فترة السكون المعتادة، أو توقف `received_lsn` و`latest_end_lsn` مع استمرار الكتابة في المصدر.

لا تعتبر قاعدة هادئة قاعدة معطلة. اكتب معاملة Heartbeat صغيرة في جدول مراقبة مكرر، ثم قس ظهورها الفعلي في المستقبِل. بذلك تفرق بين «لا توجد كتابات أعمال» و«التدفق توقف». يجب أن يمر الـHeartbeat عبر المسار نفسه، لا عبر اختصار مراقبة يتجاوزه.

الطبقة الثانية هي WAL المحتجز. تعرض `pg_replication_slots` حقولًا مثل `active` و`inactive_since` و`restart_lsn` و`confirmed_flush_lsn` و`wal_status` و`safe_wal_size` وأسباب الإبطال. قد يحتجز مستهلك متوقف ملفات WAL حتى يمتلئ القرص. وإذا كان `max_slot_wal_keep_size` محدودًا، فقد ينتقل الـSlot من `unreserved` إلى `lost`. راقب مدة التوقف ونمو البايتات المحتجزة وحالة WAL وسرعة تناقص `safe_wal_size`، لا مساحة القرص وحدها.

الطبقة الثالثة هي التطبيق. يسجل PostgreSQL 18 في `pg_stat_subscription_stats` عدادات أخطاء التطبيق والمزامنة وأنواع التعارض. يتضمن مرجع الإحصاءات تعارضات القيود الفريدة واختلاف المصدر والصفوف المفقودة. ارسم تغير العداد، واحفظ وقت Reset. عودة المجموع إلى صفر بعد إعادة تشغيل أو مسح يدوي لا تثبت أن الماضي كان نظيفًا.

الطبقة الرابعة هي المحتوى. قارن ما تعتمد عليه الأعمال: عدد الصفوف حسب فترة أو Tenant ثابت، ومجاميع القيم المستقرة، وأدنى/أقصى مفاتيح، وبصمات حتمية لأعمدة Canonical. نفذ Buckets صغيرة باستمرار ومسحًا أوسع بوتيرة أقل. احفظ نتيجتي المصدر والمستقبِل تحت Comparison ID وحد زمني واحد؛ من دون حد مشترك ستنتج الكتابات المتزامنة اختلافات كاذبة.

افهم التعارضات التي لا توقف النسخ

تميز وثائق التعارضات بين الفشل والانحراف المتسامح معه. مخالفة Unique Constraint ترفع خطأ وتوقف التطبيق حتى الحل. أما Update أوDelete لا يجد صفه المستهدف، فيُحسب تعارضًا ويُتخطى. قد يستمر النسخ ويعود التأخر إلى صفر بينما يبقى الفرق في البيانات. لهذا يجب وضع عدادات التعارض والمطابقة إلى جانب التأخر.

الكتابة المحلية على المستقبِل خطر آخر. يعمل Logical Apply مثل DML عادي؛ قد يكتب التغيير القادم فوق صف عُدّل محليًا، ويتطلب كشف اختلاف المصدر تفعيل `track_commit_timestamp`. وحتى عند كشفه، تُطبق Updates وDeletes المختلفة المصدر. إذا كان المستقبِل للقراءة فقط، فافرض ذلك بالصلاحيات وسياسة الاتصال، لا بالعُرف.

عند توقف التطبيق، احفظ Subscription وRelation وLSN للمعاملة البعيدة وسجل الخادم والصفوف المرتبطة قبل أي تغيير. أصلح السبب ثم استأنف وطابق نطاق المفاتيح المتأثر. يدعم ALTER SUBSCRIPTION أمر `SKIP` بحسب Finish LSN، لكنه يتخطى كل تعديلات البيانات في المعاملة البعيدة. هو أداة طوارئ وليس زر «تجاهل الخطأ». كل Skip يحتاج خطة إصلاح وسجل تدقيق دائم.

يجمع نظام النسخ السليم بين موقع النقل وWAL المحتجز وعدادات تعارض التطبيق ومطابقة مستقلة للمحتوى؛ لا يثبت رقم تأخر واحد صحة البيانات.
يجمع نظام النسخ السليم بين موقع النقل وWAL المحتجز وعدادات تعارض التطبيق ومطابقة مستقلة للمحتوى؛ لا يثبت رقم تأخر واحد صحة البيانات. اضغط لعرض أكبر

ضع DDL وSequences في مسار ترحيل منفصل

قيود النسخ المنطقي مهمة تشغيليًا: أوامر DDL وتعريفات Schema لا تُنسخ، وحالة Sequences لا تُنسخ، وLarge Objects لا تُنسخ. تُطابق الجداول بالاسم الكامل والأعمدة بالاسم. إذا لم يعد الصف القادم يلائم Schema المستقبِل، يتوقف التطبيق حتى يصبح متوافقًا.

في الإضافات، حدّث Schema المستقبِل أولًا، وتأكد أن الصفوف القديمة ما زالت تُطبق، ثم انشر تغيير المصدر وكود التطبيق. في الإزالة، أوقف إنتاج الشكل القديم، وانتظر وصول التطبيق والمطابقة إلى Watermark محدد، ثم احذف كائن المستقبِل والمصدر وفق خطة التوافق المختبرة. لا تبنِ Migration واحدة تفترض أن DDL تسافر مع البيانات.

انحراف Sequence مهم إذا سيستقبل المستقبِل كتابات بعد Cutover. نسخ قيمة عمود Identity لا يرفع Sequence الداخلي في المستقبِل. قبل الترقية، احسب قيمًا آمنة من البيانات وحالة المصدر، واضبطها صراحة، وتحقق أن كتابة جديدة لن تصطدم. وإذا ظل المستقبِل للقراءة دائمًا، فسجّل هذا الافتراض وافرضه.

تغييرات Publication عمليات نشر أيضًا. قد تبدأ إضافة جدول ثم Refresh للـSubscription نسخة أولية وفق الخيارات. راقب حالات مزامنة الجداول، واحسب أثر النسخ على الشبكة وI/O واحتجاز WAL. لا تنفذ Refresh واسعًا في الذروة بلا تقدير.

اجعل جاهزية Failover قابلة للقياس

قد يعمل الاشتراك مع مصدر اليوم ثم يفشل بعد تبديل Primary. يشرح دليل Failover مزامنة Slots مفعلة بـ`failover = true` إلى Physical Standby. لكن المزامنة غير متزامنة؛ الإعداد وحده ليس جاهزية.

قبل Promotion مخطط، اجمع Slots الخاصة بالاشتراكات وعمليات مزامنة الجداول المكتملة التي يحتاجها جميع المستهلكين، ثم تحقق في Standby من وجود كل Slot، وأنه Synced وغير مؤقت ولا يحمل Invalidation Reason. وتأكد أن Standby متقدم على Subscriber كما تتطلب الوثائق. حوّل الاستعلام إلى Preflight Check إلزامي بدل خطوة في Wiki يتذكرها شخص أثناء العطل.

بعد Promotion، تحقق من توجيه الاتصال واستمرارية الـSlot ووجود Workers وظهور Heartbeat وصحة Buckets. لا تعلن النجاح عند إعادة اتصال التطبيق؛ أعلنه عندما يستأنف المستقبِل من الموقع المتوقع بلا إعادة نسخ أو فقد حد المقارنة.

ابنِ Runbook حول حالات قابلة للإصلاح

صنّف الشدة حسب الأثر. فجوة LSN متنامية مع Slot سليم غالبًا مشكلة سعة أو حجز. Slot متوقف مع تناقص سريع في `safe_wal_size` حادث احتجاز. تعارض Unique هو توقف تطبيق. ارتفاع Missing-row Conflict حادث صحة بيانات حتى لو استمر التطبيق. وفشل المطابقة حادث بيانات بنطاق هو Bucket الفاشل، لا كل القاعدة تلقائيًا.

اختبر كل حالة عمدًا: اقطع الاتصال، وأوقف المستقبِل، واقترب من حد WAL، وأنشئ صفًا مفقودًا مضبوطًا، ونفذ تغيير Schema غير متوافق في بيئة تجريبية، وأضف جدولًا ثم Refresh، وروّج Standby للمصدر، وتدرب على Cutover مع ضبط Sequences. أثبت أن الإنذارات تعمل وأن المشغل يحدد المفاتيح المتأثرة وأن الإصلاح يعيد العدادات والمطابقة إلى الحالة الطبيعية.

يصبح Logical Replication موثوقًا عندما تكون حدوده صريحة. يحفظ PostgreSQL تدفق التغييرات المرتب، وعلى تصميمك التشغيلي حفظ عقد Schema وسعة Slots ورؤية التعارضات وثوابت المحتوى ومسار Failover. التأخر إشارة واحدة؛ أما الصحة فهي منظومة أدلة.

المراجع الرسمية

تدعم هذه المراجع سلوك الأدوات المذكورة. الأمثلة وقرارات التصميم توضيحية، ويجب تكييفها مع متطلبات المشروع وإصداراته.

إعداد: Noor Yasser

من القرار إلى التنفيذ

تعمل على تحدٍ تقني مشابه؟

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

احجز لقاءً لمدة ٣٠ دقيقةالخدمة المرتبطةهندسة الأنظمة الخلفية وتكاملات APIمشروع من الأعمالمنصة اللوجستيات