افتراضيًا، عند التحقق من التفرد على صف لغرض فرض فهرس فريد، تعتبر PostgreSQL قيم NULL قيمًا مميزة. بسبب هذا، يمكن أن يكون لدينا بشكل غير صحيح إدخالات متعددة مع { identifier: "rails_env", target: nil } تم إنشاؤها بسبب ظروف السباق. سيؤدي هذا بعد ذلك إلى حدوث أخطاء في وقت التشغيل.
كيف يحل هذا المشكلة؟
إسقاط الفهرس الحالي وإعادة إنشائه بخيار NULLS NOT DISTINCT.
مشكلة
ومع ذلك، تم تقديمNULLS NOT DISTINCT في Postgres 15 beta2. الإصدار الحالي من Postgres في تثبيت قياسي هو Postgres 13 وهذا لا يدعم هذه الميزة.
عواقب
لن يكون لهذا التغيير أي تأثير على PG13 نظرًا لأنه سيتم تجاهل NULLS NOT DISTINCT (المصدر)
محاولة استعادة نسخة احتياطية من خادم PG15 إلى خادم PG13 ستفشل مع الخطأ التالي
ERROR: syntax error at or near "NULLS"
LINE 1: ...m_check_trackers USING btree (identifier, target) NULLS NOT ...
^
EXCEPTION: psql failed: ^
/var/www/discourse/lib/backup_restore/database_restorer.rb:92:in `restore_dump'
(السطر الكامل: CREATE UNIQUE INDEX index_problem_check_trackers_on_identifier_and_target ON public.problem_check_trackers USING btree (identifier, target) NULLS NOT DISTINCT;)
الآن بعد أن أصبح لدينا الحل البديل، والذي يجب أن يعمل على PG15 أيضًا، يجب أن نكون قادرين على إزالة NULLS NOT DISTINCT.
من باب الفضول، ما الذي كنت تفعله والذي استلزم استعادة نسخة احتياطية من PG15 على PG13؟ (لن يؤثر ذلك على المهمة أعلاه، فقط أحاول فهم ما يحدث “في البرية” قدر الإمكان.)
كان لدينا عميل واحد يحاول استعادة نسخة احتياطية (أعتقد أنهم كانوا يستضيفون بأنفسهم وكانوا يحاولون أشياء تتجاوز مستوى معرفتهم ) ، وكان لدينا عميل آخر طلب منا إعداد موقع مرحلي لأغراض تطوير الإضافات المخصصة وأخذنا نسخة احتياطية من استضافة CDCK.
بشكل عام ، تعمل آلية الإصدار المضمنة في بيانات النسخ الاحتياطي بشكل جيد للغاية في تحديد ما إذا كان شيء ما سينهار أم لا بشكل استباقي ، ولكن هذه الأنواع من المواقف * تشبه الألغام
\u003csmall\u003e(* في الواقع ، الشيء الوحيد الآخر الذي يمكنني التفكير فيه والذي لا تغطيه إصدارات الترحيل هو عندما يتم إدخال ترحيل بتاريخ أقدم في الملف الرئيسي ، ولكن هذا خارج الموضوع)
يمكنني رؤية أن المشكلة قد تم حلها بالفعل، ولكن لإضافة تجربة واقعية: واجهت هذه المشكلة أثناء محاولة استعادة نسخة احتياطية تم إنشاؤها على مثيل مستضاف من Discourse إلى حاوية تطوير قمت بإعدادها محليًا باستخدام Docker كجزء من إعداد بيئة تطوير. يبدو أن استضافة Discourse تعمل بنظام PG 15 ولكن بيئة التطوير تعمل بنظام 13؟