فهارس تالفة في PG12، كيف أصلحها؟

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

discourse=# REINDEX SCHEMA CONCURRENTLY public;
ERROR:  could not create unique index "index_tags_on_name_ccnew"
DETAIL:  Key (name)=(chronicillness) is duplicated.

أفترض أنه يمكن إصلاحها بالحل الذي اقترحه أعلاه @riking، لكنني غير قادر على معرفة كيفية تعديل الصيغة لتناسب حالتي. :frowning:

انظر:

https://twitter.com/petervgeoghegan/status/1264325695997538304?s=20

https://twitter.com/petervgeoghegan/status/1264404749899534338?s=20

لذلك، إذا واجهت هذا الخطأ، فإليك خياران يمكنك اتخاذهما:

  1. يمكنك العمل على تجاوز المشكلة… وفي هذه الحالة، تحتوي الجدول tags على صف مكرر يحمل الاسم chronicillness

    1. قم بتشغيل استعلام في مستكشف البيانات للبحث عن الصفوف: select * from tags where name = 'chronicillness

    2. احذف الصف المكرر:

      ./launcher enter app
      rails c
      Tag.find_by(id: ID_YOU_FOUND_IN_DATA_EXPLORER).destroy   
      
  2. إذا كان لديك نسخة احتياطية من قاعدة البيانات وتفاصيل ترغب في مشاركتها مع بيتر… فقم بمشاركتها مع بيتر إما بشكل خاص أو عبر قائمة البريد الإلكتروني الخاصة بـ PG.

لذا لدي نسخة احتياطية من discourse تم إنشاؤها لـ postgres 10. هل ستكون مفيدة؟ هل يمكنني ببساطة استخراج جزء postgres من الأرشيف وإرساله؟

لست متأكدًا… ما يحتاجه بيتر على الأرجح هو إيقاف قاعدة بياناتك ونسخ المحتويات الكاملة للمجلد الذي يحتوي على قاعدة البيانات.

أفضل طريقة لمعرفة ذلك هي مراسلته عبر البريد الإلكتروني.

بالتأكيد، سأرسل له بريدًا إلكترونيًا لحل هذه المسألة :slight_smile:

ملاحظة: حصلت على هذه النتيجة عند تشغيل استعلام SQL في مستكشف البيانات

id name topic_count created_at updated_at pm_topic_count target_tag
1710 chronicillness 2 2019-12-03T17:49:17.395Z 2019-12-03T17:49:17.395Z 0 NULL

هل سيعمل الأمر التالي؟

Tag.find_by(id: 1710).destroy

أوه… الفهرس مبني على LOWER(name)

قم بتشغيل الاستعلام على النحو التالي:

select * from tags where name ilike 'chronicillness'

يجب أن تحصل على صفين.

select * from tags where name ilike 'chronicillness'
id name topic_count created_at updated_at pm_topic_count target_tag
329 chronicillness 12 2017-08-22T00:17:38.824Z 2017-08-22T00:17:38.824Z 0 NULL
1710 chronicillness 2 2019-12-03T17:49:17.395Z 2019-12-03T17:49:17.395Z 0 NULL

هل يمكن أن يكون هناك - بين أسماء الوسوم؟
أرى وسومين: chronicillness و chronic-illness هنا.

حسناً، إذن هذه هي المشكلة… أعتقد أنك تحذف 1710. بعد ذلك، ستفتقر موضوعان إلى هذا الوسم.

#<Tag:0x00005607bb92cf48
 id: 1710,
 name: "chronicillness",
 topic_count: 0,
 created_at: Tue, 03 Dec 2019 17:49:17 UTC +00:00,
 updated_at: Tue, 03 Dec 2019 17:49:17 UTC +00:00,
 pm_topic_count: 0,
 target_tag_id: nil>

لماذا أشعر وكأنها قزمة لم تكن مرتبطة بأي شيء؟

حذف الوسم جلب المزيد من العناصر!

discourse=# REINDEX SCHEMA CONCURRENTLY public;
WARNING:  cannot reindex invalid index "public.tags_pkey_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_name_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_lower_name_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "pg_toast.pg_toast_309322_index_ccnew" concurrently, skipping
ERROR:  could not create unique index "index_tags_on_name_ccnew1"
DETAIL:  Key (name)=(time-management) is duplicated.

نفس الإصلاح :slight_smile: يتعيّن عليك تكرار العملية.

هذا ما كنت أفعله. لكن هل هذه التحذيرات مقبولة؟ لا داعي للقلق بشأنها، أليس كذلك؟

نعم، جميع التحذيرات صحيحة؛ لديك فهرس تالف، ويجب إصلاحه أولاً.

إذن، اختفت جميع النسخ المقلدة الآن، وأصبحت لدي فقط هذه التحذيرات أثناء إعادة الفهرسة:

discourse=# REINDEX SCHEMA CONCURRENTLY public;
WARNING:  cannot reindex invalid index "public.tags_pkey_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_name_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_lower_name_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.tags_pkey_ccnew1" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_name_ccnew1" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_lower_name_ccnew1" concurrently, skipping
WARNING:  cannot reindex invalid index "pg_toast.pg_toast_309322_index_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "pg_toast.pg_toast_309322_index_ccnew1" concurrently, skipping
REINDEX

هل هناك أي إجراء يجب اتخاذه للتخلص من هذه التحذيرات، أم أنه يتعيّن علينا التعايش معها؟

هذا محير لي… ليس لدينا أسماء فهارس تنتهي بـ ccnew… هل قمت بإنشائها يدويًا؟

أعتقد أن هذه تُستخدم أثناء الترحيل من PostgreSQL 10 إلى 12، إذ رأيتها لدى معظم المستخدمين الذين واجهت مؤشراتهم مشاكل. على سبيل المثال:
https://meta.discourse.org/t/postgresql-12-update/151236/208?u=itsbhanusharma

https://meta.discourse.org/t/postgresql-12-update/151236/237?u=itsbhanusharma

تعديل: مصدرها من PostgreSQL نفسه

الطريقة الموصى بها للتعافي في مثل هذه الحالات هي حذف المؤشر غير الصالح ومحاولة تنفيذ REINDEX CONCURRENTLY مرة أخرى. المؤشر المتزامن الذي يتم إنشاؤه أثناء المعالجة ينتهي اسمه باللاحقة ccnew، أو ccold إذا كان تعريفًا قديمًا للمؤشر لم نتمكن من حذفه. يمكن حذف المؤشرات غير الصالحة باستخدام DROP INDEX، بما في ذلك مؤشرات toast غير الصالحة.

أوتش… هل المؤشرات الصحيحة موجودة بالفعل على الجدول؟

أعتقد أنه يمكنك سرد المؤشرات على الجدول باستخدام مستكشف البيانات.

إذا كانت المؤشرات الصحيحة موجودة، فيمكنك ببساطة التخلص من هذه المؤشرات المشكلة.

دعني أتحقق. سأبلغك بالنتيجة

إذن، يبدو أن الفهارس موجودة

كما توجد فهارس مكررة للفهارس المشكلة مع إضافة ccnew أو ccnew1

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

تعديل: هل سيعمل الأمر DROP INDEX كما هو مقترح هنا؟

نعم، احذفهم جميعًا… لا أعرف كيف وصلوا إلى هناك… DROP INDEX هو ما تريد استخدامه.

./launcher enter app
rails c
DB.exec('drop index tags_pkey_ccnew1')