पिछले सप्ताह मैंने अपना उत्पादन डेटाबेस मिटा दिया। मेरा कार्यशील [नियोटोमा](https://neotoma.io) उदाहरण एक कमांड में 6,174 अवलोकनों और 3,862 इकाइयों से 84 अवलोकनों और 67 इकाइयों तक चला गया। महीनों के संपर्क, कार्य, वार्तालाप, फीडबैक नोट्स, लेनदेन और स्थायी नियम: चले गए।

मुझे यह वापस मिल गया. अंतिम डेटाबेस में 6,296 अवलोकन और 3,951 इकाइयाँ हैं जो पाँच सप्ताह की गतिविधि में फैली हुई हैं। ठीक होने में लगभग एक घंटा लग गया। यह पोस्ट इस बारे में है कि यह कैसे हुआ, पुनर्प्राप्ति क्यों संभव थी, और एक मेमोरी सिस्टम बनाने के बारे में अनुभव से क्या पता चला जिस पर आप वास्तव में भरोसा कर सकते हैं।

## क्या हुआ

मैं नियोटोमा सीएलआई पर काम कर रहा था, एक विकास वर्कफ़्लो का परीक्षण कर रहा था। मैंने आदेशों का एक क्रम चलाया जो डेटाबेस स्थिति को रीसेट करता है और इसे पुन: प्रारंभ करता है। इरादा एक देव वातावरण से परीक्षण डेटा को साफ़ करना था। लक्ष्य उत्पादन डेटाबेस था.

गलती सांसारिक थी. मैंने `neotoma रीसेट` चलाया जबकि `NEOTOMA_ENV` को उत्पादन पर सेट किया गया था। मुझे लगा कि मैं देव को निशाना बना रहा हूं। जब तक मैंने देखा, सक्रिय डेटाबेस में पुन: आरंभीकरण प्रक्रिया से 84 ताज़ा अवलोकन थे और कुछ नहीं।

## बैकअप ढूंढना

पहला काम जो मैंने किया वह अपनी मशीन पर प्रत्येक नियोटोमा SQLite फ़ाइल की खोज करना था। मुझे मार्च की शुरुआत में पिछली क्लोज कॉल से बैकअप निर्देशिकाओं, डेटा फ़ोल्डरों और टाइमस्टैम्प्ड पुनर्प्राप्ति कलाकृतियों में बिखरी हुई दस प्रतियां मिलीं।

| स्रोत फ़ाइल | अवलोकन | संस्थाएं | नवीनतम गतिविधि |
|---|---|---|---|
| `neotoma.prod.db.db` | 6,174 | 3,862 | 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 फरवरी |

बैकअप प्रतियां मौजूद थीं क्योंकि मैं अनियमित अंतराल पर डेटाबेस फ़ाइल को मैन्युअल रूप से कॉपी कर रहा था। कोई औपचारिक बैकअप सिस्टम नहीं, बस कभी-कभार `सीपी` कमांड आता है जब मुझे याद आता है या घबराहट महसूस होती है। उन प्रतियों में से एक, `neotoma.prod.db.db` में 9 मार्च तक लगभग सब कुछ मौजूद था। दूसरी प्रति, `neotoma.prod 2.db` में 10 मार्च तक का डेटा था जो पहली प्रति से छूट गया था।

इन दो फ़ाइलों और लाइव डेटाबेस में बचे 84 अवलोकनों के बीच, मेरे पास पूरी टाइमलाइन को फिर से बनाने के लिए पर्याप्त सामग्री थी।

## मर्ज कैसे काम किया

नियोटोमा में SQLite डेटाबेस के संयोजन के लिए एक अंतर्निहित `मर्ज-डीबी` कमांड है। प्रक्रिया:

1. शामिल प्रत्येक फ़ाइल (स्रोत और लक्ष्य दोनों) का टाइमस्टैम्प्ड निर्देशिका में बैकअप लें। किसी भी पुनर्प्राप्ति प्रयास से मूल को जोखिम में नहीं डालना चाहिए।
2. समवर्ती लेखन को रोकने के लिए चल रहे नियोटोमा सर्वर को रोकें।
3. यह देखने के लिए कि क्या विरोध मौजूद है, मर्ज को ड्राई-रन करें।
4. मर्ज को `--मोड कीप-टारगेट` के साथ निष्पादित करें, जो उस स्रोत से पंक्तियों को सम्मिलित करता है जिसमें लक्ष्य गायब है और दोनों डेटाबेस द्वारा साझा की जाने वाली किसी भी पंक्ति के लक्ष्य के संस्करण को संरक्षित करता है।
5. दूसरे स्रोत के लिए दोहराएँ.
6. अवलोकन और इकाई गणना सत्यापित करें।
7. सर्वर को पुनरारंभ करें.

प्राथमिक मर्ज सबसे बड़े बैकअप से 6,174 अवलोकन लेकर आया। द्वितीयक मर्ज में 10 मार्च विंडो से लगभग 100 और जोड़े गए। अंतिम गणना: 6,296 अवलोकन, 3,951 इकाइयाँ, 9 फरवरी से 11 मार्च तक की गतिविधि।

पुनरारंभ करने के बाद, मैंने यह पुष्टि करने के लिए कि सब कुछ पहुंच योग्य था, नियोटोमा एमसीपी के माध्यम से इकाइयों का नमूना लिया। संपर्क, कार्य, वार्तालाप, फीडबैक रिकॉर्ड: सभी मौजूद और सही ढंग से संरचित।

## यह पुनर्प्राप्ति क्यों संभव हो सकी

नियोटोमा की वास्तुकला के तीन गुणों के कारण पुनर्प्राप्ति ने काम किया।

**टिप्पणियाँ सत्य का स्रोत हैं।** जब कुछ परिवर्तन होता है तो नियोटोमा किसी पंक्ति को अधिलेखित करके संस्थाओं को संग्रहीत नहीं करता है। प्रत्येक तथ्य एक अपरिवर्तनीय अवलोकन के रूप में सिस्टम में प्रवेश करता है: "ऐलिस का ईमेल alice@example.com है, जिसे 3 मार्च को जीमेल से देखा गया।" इकाई स्थिति की गणना अवलोकनों के पूर्ण सेट से की जाती है। अवलोकन लॉग केवल परिशिष्ट है।

इसका मतलब यह है कि डेटाबेस बैकअप सिस्टम द्वारा अब तक देखे गए हर तथ्य का एक संपूर्ण स्नैपशॉट है, न कि केवल नवीनतम स्थिति का। जब मैंने बैकअप को लाइव डेटाबेस में मर्ज किया, तो मैं "प्रत्येक इकाई की अंतिम ज्ञात स्थिति" को पुनर्स्थापित नहीं कर रहा था। मैं पूरा इतिहास दोहरा रहा था.

**इकाई स्नैपशॉट व्युत्पन्न होते हैं, प्राथमिक नहीं।** अवलोकनों को मर्ज करने के बाद, नियोटोमा अवलोकन लॉग से इकाई स्नैपशॉट की पुनः गणना करता है। प्रत्येक इकाई के लिए स्नैपशॉट नियतात्मक है: समान अवलोकनों को देखते हुए, आपको हमेशा एक ही इकाई स्थिति मिलती है। यही कारण है कि मर्ज कमांड में स्नैपशॉट पुनर्गणना चरण शामिल होता है। एक बार अवलोकन स्थापित हो जाने के बाद, संस्थाएँ स्वयं को सही ढंग से पुनर्निर्माण करती हैं।

**विरोध का पता लगाने के साथ प्राथमिक-कुंजी का विलय।** `मर्ज-डीबी` कमांड प्रत्येक तालिका पर चलता है, उन पंक्तियों को सम्मिलित करता है जो स्रोत में मौजूद हैं लेकिन लक्ष्य में नहीं, और प्राथमिक कुंजी द्वारा संघर्षों को संभालता है। `कीप-टार्गेट` मोड में, लक्ष्य का संस्करण किसी भी टकराव पर जीतता है। ड्राई-रन मोड सटीक रूप से पूर्वावलोकन करता है कि क्या डाला जाएगा और आपके प्रतिबद्ध होने से पहले क्या विरोध होगा। मैंने दोनों मर्जों के लिए ड्राई-रन चलाया और निष्पादित करने से पहले विरोध रिपोर्ट की समीक्षा की।

ये तीन गुण मिलकर डेटाबेस को इस तरह से सेल्फ-हीलिंग बनाते हैं जैसे कि पारंपरिक पंक्ति-स्तरीय बैकअप नहीं होते हैं। आपको इस बारे में चिंता करने की ज़रूरत नहीं है कि किस बैकअप में किसी इकाई का "सही संस्करण" है। आप अवलोकनों को मर्ज करते हैं, पुनः गणना करते हैं, और सही स्थिति सामने आ जाती है।

## मैंने क्या सीखा

अनुभव ने कुछ चीज़ों को पुष्ट किया।

**अनौपचारिक बैकअप बिना बैकअप के बेहतर हैं।** डेटाबेस फ़ाइल को कभी-कभार कॉपी करने की मेरी आदत ने महीनों के काम को बचा लिया। लेकिन कभी-कभार मैन्युअल प्रतिलिपियाँ एक प्रणाली नहीं हैं। वे अंतराल छोड़ देते हैं. यदि मैंने 11 मार्च के बजाय 7 मार्च को डेटाबेस मिटा दिया होता, तो मैं 28 फरवरी से 7 मार्च तक का डेटा खो देता क्योंकि किसी भी कॉपी ने उस विंडो को पूरी तरह से कवर नहीं किया होता। अब मैं अपने मैक पर टाइम मशीन के साथ स्वचालित दैनिक बैकअप सेट कर रहा हूं।

**एनवी फ़्लैग गलती एक क्लासिक है।** प्रत्येक प्रणाली जो विकास और उत्पाद परिवेश में संचालित होती है, वह यह जोखिम उठाती है। शमन विनाशकारी संचालन, रंग-कोडित टर्मिनल संकेतों, या प्रति वातावरण के लिए अलग क्रेडेंशियल्स के लिए पुष्टिकरण संकेत है। इस घटना के बाद जब भी यह उत्पादन वातावरण का पता लगाता है तो मैंने `नियोटोमा रीसेट` में एक जबरन पुष्टि जोड़ दी। उत्पाद के लिए `-y` ध्वज को नजरअंदाज कर दिया जाता है। आपको "नियोटोमा रीसेट (उत्पादन)" और कुछ भी होने से पहले एक चेतावनी दिखाई देती है।

**इवेंट-सोर्स्ड आर्किटेक्चर पुनर्प्राप्ति में लाभदायक होता है।** यदि नियोटोमा ने पंक्तियों को ओवरराइट करके इकाइयों को संग्रहीत किया है, तो डेटाबेस वाइप एक डेटा हानि घटना होगी जिसमें कोई साफ़ पुनर्प्राप्ति पथ नहीं होगा। चूँकि अवलोकन अपरिवर्तनीय हैं और इकाई स्थिति व्युत्पन्न होती है, पुनर्प्राप्ति एक मर्ज-एंड-रीकंप्यूट ऑपरेशन है। अवलोकन लॉग जमीनी सच्चाई है. बाकी सब कुछ इससे दोबारा बनाया जा सकता है।

**मैंने उन उपकरणों का परीक्षण किया जो मैं बना रहा था।** मैंने एक अलग उपयोग के मामले के लिए महीनों पहले `मर्ज-डीबी` कमांड लिखा था: कई नियोटोमा इंस्टेंसेस चलाने वाले उपयोगकर्ताओं के डेटा का संयोजन। मैंने कभी भी अपने उत्पादन डेटा पर इसका उपयोग करने की उम्मीद नहीं की थी। लेकिन क्योंकि उपकरण मौजूद था और उसने संघर्ष समाधान और स्नैपशॉट पुनर्गणना को संभाला था, पुनर्प्राप्ति तनावपूर्ण के बजाय यांत्रिक थी।

## आपका डेटा आपकी गलतियों से बचा रहना चाहिए

इस घटना ने उन कमियों को उजागर कर दिया है जिन्हें नियोटोमा को बंद करना चाहिए ताकि उपयोगकर्ताओं को वह काम कभी न करना पड़े जो मैंने मैन्युअल रूप से किया था।

**स्वचालित स्नैपशॉट।** नियोटोमा को एक शेड्यूल पर और किसी भी विनाशकारी ऑपरेशन से पहले डेटाबेस का स्नैपशॉट लेना चाहिए। टाइमस्टैम्प्ड प्रतियों का एक घूमने वाला सेट, 30 दिनों के लिए रखा जाता है। यदि आप गलती से उत्पाद पर रीसेट चलाते हैं, तो प्री-रीसेट स्नैपशॉट वहीं होता है। पुनर्प्राप्ति इस बात पर निर्भर नहीं होनी चाहिए कि आपको उस सप्ताह `सीपी` चलाना याद था या नहीं।

**विसंगति का पता लगाना।** हजारों अवलोकनों से अचानक लगभग शून्य तक गिरना सामान्य नहीं है। नियोटोमा इस पैटर्न का पता लगा सकता है और प्रतिबद्ध होने से पहले पुष्टि कर सकता है। एक सरल अनुमान, "यह ऑपरेशन 90% से अधिक अवलोकनों को हटा देगा, पुष्टि करें?" मेरे पोंछने को पूरी तरह से रोक देता।

**एजेंट-संचालित पुनर्प्राप्ति।** चूंकि एजेंट नियोटोमा के लिए प्राथमिक यूएक्स हैं, इसलिए पुनर्प्राप्ति को एजेंटों के माध्यम से भी काम करना चाहिए। आप अपने एजेंट को बताएं "मेरा डेटाबेस गलत लग रहा है, मुझे लगता है कि मैंने डेटा खो दिया है।" एजेंट अवलोकन संख्या की जांच करता है, उपलब्ध स्नैपशॉट ढूंढता है, दिनांक सीमाओं की तुलना करता है, और एमसीपी के माध्यम से आपको मर्ज के बारे में बताता है। कोई सीएलआई स्पेलुनकिंग की आवश्यकता नहीं है।

**रिमोट सिंक।** स्थानीय बैकअप आकस्मिक ओवरराइट से रक्षा करते हैं लेकिन डिस्क विफलता से नहीं। नियोटोमा को अवलोकन लॉग को किसी दूरस्थ स्थान पर समन्वयित करने का समर्थन करना चाहिए: एक क्लाउड बकेट, एक दूसरी मशीन, या एक स्व-होस्टेड सर्वर। क्योंकि अवलोकन केवल परिशिष्ट हैं, सिंक मॉडल सरल है। नए अवलोकनों को रिमोट पर भेजें। दोनों छोर पर इकाई स्थिति का पुनर्निर्माण करें।

वही आर्किटेक्चर जिसने इस पुनर्प्राप्ति को संभव बनाया, इन सुविधाओं को बनाना आसान बनाता है। केवल परिशिष्ट अवलोकन, व्युत्पन्न स्थिति और नियतात्मक पुनर्गणना केवल पुनर्प्राप्ति गुण नहीं हैं। वे प्रथम श्रेणी की गारंटी के रूप में बैकअप, सिंक और स्व-उपचार की नींव हैं।

## संख्याएँ

| मीट्रिक | पोंछने से पहले | पोंछने के बाद | ठीक होने के बाद |
|---|---|---|---|
| अवलोकन | 6,174 | 84 | 6,296 |
| संस्थाएं | 3,862 | 67 | 3,951 |
| तिथि सीमा | 9 फरवरी से 9 मार्च | 10 मार्च से 11 मार्च | 9 फरवरी से 11 मार्च |

अंतिम गणना प्री-वाइप गणना से अधिक है क्योंकि मर्ज ने सभी तीन स्रोतों से संयुक्त अवलोकन किया है: दो बैकअप फ़ाइलें और बचे हुए पोस्ट-वाइप डेटा। कुछ अवलोकन जो केवल 10 मार्च बैकअप में या केवल लाइव डेटाबेस में मौजूद थे, मूल सबसे बड़े बैकअप में नहीं थे।

यदि आपका मेमोरी सिस्टम परिवर्तनशील स्थिति का उपयोग करता है, तो वाइप स्थायी है। यदि यह व्युत्पन्न इकाई स्थिति के साथ केवल परिशिष्ट अवलोकन लॉग का उपयोग करता है, तो वाइप पूर्ण पुनर्प्राप्ति से एक मर्ज दूर है। यह अंतर तब मायने रखता है जब डेटा आपके संपर्क, आपकी प्रतिबद्धताएं, सैकड़ों सत्रों में एजेंटों के साथ आपका इतिहास हो।

नियोटोमा [GitHub पर खुला स्रोत](https://github.com/neotoma-app/neotoma) है। यदि आप एक मेमोरी परत चाहते हैं जहां आपका डेटा आपकी सबसे खराब गलतियों से बच सके, [इसे आज़माएं](https://neotoma.io/install)।