في الأسبوع الماضي قمت بمسح قاعدة بيانات الإنتاج الخاصة بي. انتقل مثيل عملي [Neotoma](https://neotoma.io) من 6,174 ملاحظة و3,862 كيانًا إلى 84 ملاحظة و67 كيانًا في أمر واحد. لقد اختفت أشهر من الاتصالات والمهام والمحادثات وملاحظات التعليقات والمعاملات والقواعد الدائمة.

لقد استعدته. تحتوي قاعدة البيانات النهائية على 6,296 ملاحظة و3,951 كيانًا تمتد على خمسة أسابيع من النشاط. استغرق التعافي حوالي ساعة. تتناول هذه المقالة كيفية حدوث ذلك، ولماذا كان التعافي ممكنًا، وما كشفته التجربة حول بناء نظام ذاكرة يمكنك الوثوق به بالفعل.

##ماذا حدث

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

كان الخطأ عاديا. قمت بإجراء "إعادة ضبط الورم العصبي" بينما تم ضبط "NEOTOMA_ENV" على الإنتاج. اعتقدت أنني كنت أستهدف المطورين. بحلول الوقت الذي لاحظت فيه، كانت قاعدة البيانات النشطة تحتوي على 84 ملاحظة جديدة من عملية إعادة التهيئة ولا شيء غير ذلك.

## العثور على النسخ الاحتياطية

أول شيء قمت به هو البحث عن كل ملف Neotoma SQLite على جهازي. لقد عثرت على عشر نسخ متناثرة عبر أدلة النسخ الاحتياطي ومجلدات البيانات وأدوات الاسترداد ذات الطابع الزمني من مكالمة قريبة سابقة في أوائل شهر مارس.

| الملف المصدر | ملاحظات | الكيانات | آخر النشاط |
|---|---|---|---|
| `neotoma.prod.db.db` | 6,174 | 3,862 | Mar 9 |
| `neotoma.prod 2.db` | 4,406 | 3,073 | 10 مارس |
| الهدف المباشر (بعد المسح) | 84 | 67 | 11 مارس |
| `neotoma.prod.db.recovered-*` | 4,381 | 3,059 | 3 مارس |
| `النسخ الاحتياطي للبيانات/نسخ البيانات/` | 4,158 | 2,955 | مارس 2 |
| نسخ قديمة مختلفة | 3,100 إلى 3,931 | 2,558 إلى 2,806 | 17 فبراير إلى 27 فبراير |

النسخ الاحتياطية موجودة لأنني كنت أقوم بنسخ ملف قاعدة البيانات يدويًا على فترات غير منتظمة. ليس نظام نسخ احتياطي رسمي، فقط أوامر `cp` عرضية عندما أتذكرها أو أشعر بالتوتر. إحدى هذه النسخ، "neotoma.prod.db.db"، احتفظت بكل شيء تقريبًا حتى 9 مارس. أما النسخة الثانية، "neotoma.prod 2.db"، فقد احتوت على بيانات حتى 10 مارس، لكن النسخة الأولى فاتتها.

بين هذين الملفين والملاحظات الـ 84 الباقية في قاعدة البيانات المباشرة، كان لدي ما يكفي من المواد لإعادة بناء الجدول الزمني الكامل.

## كيفية عمل الدمج

يحتوي Neotoma على أمر merge-db مدمج لدمج قواعد بيانات SQLite. العملية:

1. قم بعمل نسخة احتياطية من كل ملف معني (كل من المصادر والهدف) في دليل ذو طابع زمني. لا ينبغي لأي محاولة استرداد المخاطرة بالأصول.
2. قم بإيقاف تشغيل خادم Neotoma لمنع عمليات الكتابة المتزامنة.
3. قم بتشغيل عملية الدمج الجافة لمعرفة التعارضات الموجودة.
4. قم بتنفيذ الدمج باستخدام `--mode keep-target`، الذي يقوم بإدراج صفوف من المصدر الذي يفتقده الهدف ويحافظ على إصدار الهدف من أي صف تشترك فيه قاعدتا البيانات.
5. كرر للمصدر الثاني.
6. التحقق من الملاحظة وأعداد الكيانات.
7. أعد تشغيل الخادم.

جلب الدمج الأساسي 6174 ملاحظة من أكبر نسخة احتياطية. أضاف الدمج الثانوي ما يقرب من 100 إضافية من نافذة 10 مارس. العدد النهائي: 6,296 ملاحظة، 3,951 كيانًا، نشاط يمتد من 9 فبراير إلى 11 مارس.

بعد إعادة التشغيل، قمت بأخذ عينات من الكيانات من خلال Neotoma MCP للتأكد من إمكانية الوصول إلى كل شيء. جهات الاتصال، والمهام، والمحادثات، وسجلات التعليقات: كلها موجودة ومصممة بشكل صحيح.

## لماذا كان هذا التعافي ممكنًا؟

نجح التعافي بسبب ثلاث خصائص لهندسة نيوتوما.

**الملاحظات هي مصدر الحقيقة.** لا يقوم Neotoma بتخزين الكيانات عن طريق الكتابة فوق صف عندما يتغير شيء ما. تدخل كل حقيقة إلى النظام كملاحظة ثابتة: "البريد الإلكتروني لأليس هو alice@example.com، تمت ملاحظته في 3 مارس من Gmail." يتم حساب حالة الكيان من المجموعة الكاملة للملاحظات. سجل المراقبة إلحاقي فقط.

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

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

**دمج المفتاح الأساسي مع اكتشاف التعارض.** يقوم الأمر `merge-db` بالتنقل في كل جدول، وإدراج الصفوف الموجودة في المصدر ولكن ليس الهدف، ويتعامل مع التعارضات بواسطة المفتاح الأساسي. في وضع "الاحتفاظ بالهدف"، تفوز نسخة الهدف عند أي تصادم. يقوم وضع التشغيل الجاف بمعاينة ما سيتم إدراجه بالضبط وما الذي سيتعارض قبل الالتزام. لقد أجريت تجارب تجريبية لكلا عمليتي الدمج وراجعت تقارير التعارض قبل التنفيذ.

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

## ما تعلمته

وقد عززت التجربة بعض الأشياء.

**النسخ الاحتياطي غير الرسمي أفضل من عدم وجود نسخ احتياطية.** عادتي في نسخ ملف قاعدة البيانات من حين لآخر وفرت شهورًا من العمل. لكن النسخ اليدوية العرضية ليست نظامًا. يتركون فجوات. إذا قمت بمسح قاعدة البيانات في 7 مارس بدلاً من 11 مارس، لكنت قد فقدت البيانات من 28 فبراير إلى 7 مارس لأنه لم تكن هناك نسخة تغطي تلك النافذة بالكامل. أقوم الآن بإعداد نسخ احتياطية يومية تلقائية باستخدام Time Machine على جهاز Mac الخاص بي.

**خطأ علامة البيئة هو خطأ كلاسيكي.** يحمل كل نظام يعمل عبر بيئات التطوير والإنتاج هذا الخطر. التخفيف هو مطالبات التأكيد للعمليات المدمرة، أو المطالبات الطرفية المرمزة بالألوان، أو بيانات الاعتماد المنفصلة لكل بيئة. بعد هذه الحادثة أضفت تأكيدًا قسريًا إلى "إعادة ضبط الورم العصبي" كلما اكتشف بيئة إنتاج. يتم تجاهل العلامة `-y` في المنتج. ترى "إعادة ضبط الورم العصبي (المنتج)" وتحذيرًا قبل حدوث أي شيء.

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

**لقد اختبرت الأدوات التي كنت أقوم بإنشائها.** كتبت الأمر `merge-db` منذ أشهر لحالة استخدام مختلفة: دمج البيانات من المستخدمين الذين يقومون بتشغيل مثيلات Neotoma المتعددة. لم أتوقع أبدًا استخدامه في بيانات الإنتاج الخاصة بي. ولكن نظرًا لوجود الأداة وتعاملها مع حل النزاعات وإعادة حساب اللقطات، كان التعافي ميكانيكيًا وليس مرهقًا.

## يجب أن تنجو بياناتك من أخطائك

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

**لقطات تلقائية.** يجب على Neotoma تصوير قاعدة البيانات وفقًا لجدول زمني وقبل أي عملية مدمرة. مجموعة دورية من النسخ ذات الطوابع الزمنية، يتم الاحتفاظ بها لمدة 30 يومًا. إذا قمت بإجراء إعادة تعيين على المنتج عن طريق الخطأ، فستكون لقطة إعادة التعيين المسبق موجودة هناك. لا ينبغي أن يعتمد الاسترداد على ما إذا كنت قد تذكرت تشغيل "cp" في ذلك الأسبوع.

**كشف الشذوذ.** الانخفاض المفاجئ من آلاف الملاحظات إلى ما يقرب من الصفر ليس أمرًا طبيعيًا. يمكن لـ Neotoma اكتشاف هذا النمط وتأكيده قبل الالتزام. إرشادي بسيط، "هذه العملية ستزيل أكثر من 90% من الملاحظات، هل تؤكد ذلك؟" كان سيمنع مسحي بالكامل.

**الاسترداد المعتمد على الوكيل.** نظرًا لأن الوكلاء هم تجربة المستخدم الأساسية لـ Neotoma، فيجب أن يعمل الاسترداد من خلال الوكلاء أيضًا. أخبر وكيلك "قاعدة البيانات الخاصة بي تبدو خاطئة، وأعتقد أنني فقدت البيانات". يتحقق الوكيل من أعداد المراقبة، ويبحث عن اللقطات المتاحة، ويقارن النطاقات الزمنية، ويرشدك خلال عملية الدمج عبر MCP. لا حاجة إلى اكتشاف الكهوف CLI.

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

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

##الارقام

| Metric | قبل أن يمسح | بعد مسح | بعد الشفاء |
|---|---|---|---|
| ملاحظات | 6,174 | 84 | 6,296 |
| الكيانات | 3,862 | 67 | 3,951 |
| النطاق الزمني | 9 فبراير إلى 9 مارس | 10 مارس إلى 11 مارس | 9 فبراير إلى 11 مارس |

العدد النهائي أعلى من عدد المسح المسبق لأن الدمج يجمع الملاحظات من المصادر الثلاثة: ملفي النسخ الاحتياطي وبيانات ما بعد المسح الباقية. بعض الملاحظات التي كانت موجودة فقط في النسخة الاحتياطية بتاريخ 10 مارس أو فقط في قاعدة البيانات المباشرة لم تكن موجودة في النسخة الاحتياطية الأكبر الأصلية.

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

Neotoma هو [مفتوح المصدر على GitHub](https://github.com/neotoma-app/neotoma). إذا كنت تريد طبقة ذاكرة حيث يمكن لبياناتك أن تنجو من أسوأ الأخطاء التي ارتكبتها، [جربها](https://neotoma.io/install).