- ما هي اللقطات وأين يمكن العثور عليها
- كيف تتجلى المشكلة
- استراتيجيات التعافي الممكنة وما الذي تعنيه كل منها
لمحة عامة عن لقطات Keeper
ما هي اللقطة؟
اللقطة هي حالة مُسلسلة لبيانات Keeper الداخلية (مثل البيانات الوصفية الخاصة بالمجموعات العنقودية، ومسارات تنسيق الجداول، والتهيئات) في نقطة زمنية محددة. وتُعد اللقطات بالغة الأهمية لإعادة مزامنة عُقد Keeper داخل المجموعة العنقودية، واستعادة البيانات الوصفية أثناء حالات الفشل، ولدعم عمليات بدء التشغيل أو إعادة التشغيل التي تعتمد على حالة سليمة ومعروفة لـ Keeper.أين يمكنني العثور على اللقطات؟
تُخزَّن اللقطات كملفات على نظام الملفات المحلي لعُقد Keeper. افتراضيًا، تُحفَظ في/var/lib/clickhouse/coordination/snapshots/، أو في المسار المخصّص الذي تحدّده snapshot_storage_path في ملف keeper_server.xml. وتُسمّى اللقطات بأرقام متزايدة (على سبيل المثال: snapshot.23)، بحيث تحمل اللقطات الأحدث أرقامًا أكبر.
في المجموعات متعددة العُقد، تكون لكل عقدة Keeper دليل لقطات خاص بها.
يُعدّ اتساق اللقطات بين العُقد أمرًا بالغ الأهمية للتعافي.
الأعراض والمظاهر الرئيسية لتلف لقطات Keeper
يوضح الجدول أدناه بعض الأعراض والمظاهر الشائعة لتلف لقطات Keeper:
مؤشرات السجل:
قبل تشخيص تلف اللقطة، تحقق من سجلات Keeper بحثًا عن أنماط أخطاء محددة:
التعافي من لقطات Keeper التالفة
قبل التعامل مع أي ملفات، احرص دائمًا على ما يلي:- أوقف جميع عُقد Keeper لمنع تفاقم التلف
- أنشئ نسخة احتياطية من كل شيء عبر نسخ دليل التنسيق بالكامل إلى موقع آمن
- تحقّق من نصاب العنقود للتأكد من أن عقدة واحدة على الأقل تحتوي على بيانات سليمة
- الاستعادة من نسخة احتياطية موجودة
ينبغي اتباع هذه العملية إذا:
- كان تلف البيانات الوصفية أو اللقطات في Keeper يجعل البيانات الحالية غير قابلة للاستعادة.
- كانت هناك نسخة احتياطية تتضمن حالة سليمة ومعروفة لـ Keeper.
- حدِّد أحدث نسخة احتياطية وتحقّق من اتساق البيانات الوصفية فيها.
- أوقف خدمتي ClickHouse وKeeper.
- استبدل اللقطات والسجلات التالفة بتلك الموجودة في دليل النسخة الاحتياطية.
- أعد تشغيل عنقود Keeper وتحقّق من مزامنة البيانات الوصفية.
- التراجع إلى لقطة أقدم
يجب اتباع هذه العملية في الحالات التالية:
- تكون اللقطات الحديثة تالفة، بينما تظل اللقطات الأقدم قابلة للاستخدام.
- تكون السجلات التزايدية سليمة، بما يتيح استردادًا متسقًا.
- حدِّد واختر لقطة أقدم صالحة (مثلًا، snapshot.19) من دليل Keeper.
- أزل اللقطات والسجلات الأحدث.
- أعد تشغيل Keeper لكي يعيد تطبيق السجلات ويُعيد بناء حالة البيانات الوصفية.
- استعادة البيانات الوصفية باستخدام
SYSTEM RESTORE REPLICA
يُوصى باتباع هذه العملية في الحالات التالية:
SYSTEM RESTORE REPLICA- عند فقدان البيانات الوصفية في Keeper أو تلفها، مع بقاء بيانات الجدول موجودة على القرص
- عند انتقال الجداول إلى وضع القراءة فقط بسبب فقدان البيانات الوصفية في ZooKeeper/Keeper
- عندما تحتاج إلى إعادة إنشاء البيانات الوصفية في Keeper استنادًا إلى أجزاء البيانات المتوفرة محليًا
-
تحقّق من وجود بيانات الجدول محليًا في مسار بيانات clickHouse-server، والمحدَّد بواسطة
<path>في config. (المسار الافتراضي هو/var/lib/clickhouse/data/) - لكل جدول متأثر، نفّذ:
- للتعافي على مستوى قاعدة البيانات (إذا كنت تستخدم محرك قاعدة البيانات Replicated):
- انتظر حتى يكتمل التزامن:
- تحقّق من نجاح التعافي عبر فحص
system.replicasللتأكد من أنis_readonly = 0، ومراقبةsystem.detached_parts
كيف يعمليقوم
SYSTEM RESTORE REPLICA بفصل جميع الأجزاء الحالية، وإعادة إنشاء البيانات الوصفية في Keeper (كما لو كان جدولًا فارغًا جديدًا)، ثم يعيد إرفاق جميع الأجزاء. وهذا يجنّب إعادة تنزيل البيانات عبر الشبكة.
- حذف بيانات تعريف النسخة المتماثلة في Keeper وإعادة إنشائها
يجب اتباع هذه العملية في الحالات التالية:
- إذا كان الخطأ يحدث في نسخة متماثلة واحدة من العنقود وكانت بيانات التعريف الخاصة بها في Keeper تالفة أو غير متسقة
- إذا واجهت أخطاء مثل “Part XXXXX intersects previous part YYYYY”
- إذا كنت بحاجة إلى إعادة تعيين بيانات تعريف النسخة المتماثلة في Keeper بالكامل مع الحفاظ على البيانات المحلية
- على النسخة المتماثلة المتأثرة، افصل الجدول:
- أزل البيانات الوصفية للنسخة المتماثلة من Keeper (نفّذ ذلك على أي نسخة متماثلة):
- أعِد إرفاق الجدول (سيكون في وضع القراءة فقط):
- استعِد البيانات الوصفية للنسخة المتماثلة:
- زامِن مع النسخ المتماثلة الأخرى:
- تحقّق من
system.detached_partsعلى جميع النسخ المتماثلة بعد الاستعادة
- أوقِف خادم ClickHouse
- أنشئ علامة الاستعادة:
- شغّل خادم ClickHouse
- سيحذف الخادم العلامة تلقائيًا ويستعيد جميع الجداول المُكرَّرة
- راقب السجلات لمتابعة تقدّم التعافي
- إعادة بناء عنقود Keeper
يجب اتباع هذه العملية في الحالات التالية:
- عدم توفر أي لقطات أو سجلات أو نسخ احتياطية صالحة للاسترداد.
- الحاجة إلى إعادة إنشاء عنقود Keeper بالكامل وبياناته الوصفية.
- أوقف عنقودَي ClickHouse وKeeper بالكامل.
- أعد ضبط كل عقدة في Keeper بتنظيف أدلة اللقطات والسجلات.
- هيّئ عقدة واحدة في Keeper لتكون قائدًا، ثم أضف العقد الأخرى بالتدريج.
- أعد استيراد البيانات الوصفية إذا كانت متاحة من سجلات خارجية.
- إزالة العُقد اليتيمة من اللقطة عند بدء التشغيل
العقدة اليتيمة هي عقدة لا توجد عقدتها الأصل في اللقطة. يرفض Keeper تحميل مثل هذه
اللقطة، ويسجّل الرسالة Failure to load from latest snapshot with index.
ينبغي اتباع هذا الإجراء في الحالتين التاليتين معًا:
- أن يكون تلف بنية اللقطة من هذا النوع تحديدًا،
- ألّا تتوفر نسخة احتياطية صالحة أو لقطة أقدم (ويُفضَّل اللجوء إلى الاستراتيجيتين 1 و2 كلما أمكن تطبيقهما).
<keeper_server> ثم أعد تشغيل العقدة:
يتطلب تخزين العقد في الذاكرةلا تتوفر عملية التنظيف إلا في تخزين العقد في الذاكرة. إذا كان
use_lsmt_storage مفعّلًا ضمن
<coordination_settings>، فسيرفض Keeper بدء التشغيل عند ضبط remove_orphaned_nodes_on_startup: عطّل
use_lsmt_storage عند إعادة التشغيل بغرض الاسترداد، ثم أعد تفعيله بعد نجاح بدء التشغيل.WARNING
في سطرين: يتضمن الأول العدد الإجمالي للعقد المحذوفة وجذور الأشجار الفرعية اليتيمة المحذوفة،
ويتضمن الثاني المسارات المفقودة من اللقطة التي تحدّ المنطقة التالفة. وتُحذف كذلك العقد المتفرعة
أسفل تلك الجذور، لكنها لا تُدرج كلٌّ على حدة.
بعد فحص ذيل السجل المحلي، يكتب Keeper الشجرة المُصلَحة في ملف لقطة جديد عند فهرس السجل
نفسه قبل بدء تشغيل Raft. وتحظى عمليات الإصلاح المكتملة بالأولوية على النسخ الأقدم عند ذلك الفهرس،
بحيث يمكن استئناف عملية استرداد متوقفة دون اختيار اللقطة التالفة. ويتلقى الـ followers الجدد
اللقطة المُصلَحة، ولا تعود عمليات إعادة التشغيل اللاحقة
بحاجة إلى تفعيل إزالة العقد اليتيمة. وتُحفَظ اللقطة الأصلية وأي نسخ عند الفهرس نفسه
بإضافة البادئة orphaned_ إلى اسم الملف؛ وتُستثنى هذه الملفات من تحميل اللقطات ومن الاحتفاظ
التلقائي. احتفظ بها لأغراض التشخيص، ثم احذفها يدويًا عندما لا تعود بحاجة إليها. وتتطلب
إعادة التشغيل بغرض الاسترداد مساحة قرص إضافية للقطة المُصلَحة وللنسخة الاحتياطية من اللقطة الأصلية.
وإذا فشلت كتابة اللقطة المُصلَحة، أو مزامنة تغييرات الدليل المحلي، أو حفظ النسخ الأصلية،
فسيرفض Keeper بدء التشغيل. ويُكمل بدء التشغيل التالي أي عملية أرشفة متوقفة.
يرفض Keeper عمدًا بدء التشغيل إذا كان أحد إدخالات السجل المحلية اللاحقة للقطة يشير إلى المنطقة
التالفة: عقدة محذوفة، أو أي شيء أسفلها، أو الأصل المباشر لشجرة فرعية محذوفة. ويُعدّ الأصل المباشر
تعارضًا لأن مجموعة أبنائه لم تعد تطابق الشجرة التي كُتب السجل وفقًا لها،
لذا فإن أي إدخال يمسّه وحده — بما في ذلك إنشاء عقدة شقيقة أسفله أو حذفها، وهو ما
يحدّث عدّادات أبنائه المُصلَحة — قد يُعاد تنفيذه بنتيجة مختلفة. أما الإدخالات التي تكتفي بفحص وجود الأصل
أو معرّفات إصداره أو تعديله، مثل Check أو CheckNotExists أو CheckStat الذي لا يقارن numChildren ولا cversion،
أو Set أو SetACL الذي يعيد كتابة بيانات الأصل نفسه أو ACL الخاص به فقط، أو
مراقبات البيانات والأبناء والوجود التي يعيد العميل تسجيلها بعد إعادة الاتصال، فلا تتأثر ولا
تعيق الاسترداد؛ أما المراقبات الدائمة التي يعيد العميل تسجيلها فلا ترجع إلى الشجرة إطلاقًا ولا تعيقه مطلقًا.
ولا تتأثر العقد الأعلى في السلسلة:
إذ تحتفظ بالبيانات والإصدار والأبناء ذاتها الموجودة لدى أي نظير سليم، لذا فإن الإدخال الذي
يمسّ مثل هذه العقدة وحدها يُعاد تنفيذه بالنتيجة نفسها ولا يعيق الاسترداد. ويُستثنى من ذلك الإدخال الذي
يجتاز الشجرة الفرعية بأكملها أسفل مساره، مثل الحذف التعاودي أو الاستعراض التعاودي: إذ ترصد هذه الإدخالات
العقد المحذوفة وتُعدّ تعارضًا على أي مستوى، ما لم يرفض Keeper الطلب قبل فحص
الشجرة (مثل الحذف التعاودي لـ /). وينطبق الأمر نفسه على إغلاق session
(Close) في ذيل السجل إذا كانت تلك الـ session تملك عقدة مؤقتة محذوفة، أو تملك عقدة مؤقتة
باقية أسفل أصل كهذا مباشرةً: إذ يؤدي إغلاق الـ session إلى حذف عقدها المؤقتة وتحديث عدّادات
آبائها. وإعادة تنفيذ أي إدخال من هذا النوع على
الشجرة المُصلَحة ستُنتج حالة مختلفة دون أي تنبيه. في هذه الحالة، استرد العقدة من نظير
سليم بدلًا من ذلك: أوقفها، وامسح دليل التنسيق الخاص بها، ودعها تعيد المزامنة من القائد، أو استخدم
الاستراتيجية 1 أو 2.