सामग्रीमा जानुहोस्

ब्याकअप, निश्चित समय पुनःप्राप्ति र पुनर्स्थापना अभ्यास

Quire ब्याकअप गर्नुहोस्, निश्चित समयमा पुनर्स्थापना गर्नुहोस्, र पुनर्स्थापना अभ्यासबाट प्रमाणित गर्नुहोस्।

Markdown का रूपमा हेर्नुहोस्

डिजाइन docs/architecture/23-ops.md खण्ड 8 हो। यो Docker Compose उत्पादनका लागि रनबुक हो। यसलाई नलेख्ने कसैले पछ्याउने गरी लेखिएको छ; चरण अस्पष्ट भए, यो दस्तावेजकै दोष हो।

के सुरक्षित छ, र कसरी

सम्पत्ति कसरी कहाँ
डेटाबेस पहिलो बुटबाट निरन्तर WAL अभिलेख, बढीमा हरेक 60 सेकेन्डमा pgwal भोल्युम
डेटाबेस pg_basebackup सँग आधार ब्याकअप, पूर्वनिर्धारित दैनिक (backup-scheduler) pgbackup भोल्युम
डेटाबेस आधार ब्याकअप र WAL का इन्क्रिप्टेड प्रतिलिपि, हरेक पाँच मिनेटमा (backup-offsite) तपाईंले नाम दिने छुट्टै भण्डार
फाइलहरू files भोल्युम। होस्टको ब्याकअप उपकरणबाट प्रतिलिपि गर्नुहोस्, वा संस्करणयुक्त वस्तु भण्डारण प्रयोग गर्नुहोस् files भोल्युम
गोप्यहरू docker/.env, सबैभन्दा माथि QUIRE_MASTER_KEY (र अझै प्रयोगमा रहेको कुनै QUIRE_MASTER_KEY_RETIRED), QUIRE_BACKUP_ENCRYPTION_KEY, र docker/secrets/audit-signing-key.pem यस होस्टबाहिर प्रतिलिपि राख्नुहोस्
खोज सूचकाङ्क, क्यास, संस्करण ब्याकअप हुँदैन; पुनर्निर्माण हुन्छ

लक्ष्य: असफलताको 60 सेकेन्डभित्र पुनःप्राप्ति बिन्दु, र 500 GB डेटाबेसका लागि 60 मिनेटभित्र पुनर्स्थापना।

दुई गल्ती सामान्य छन्। फाइलबिना पुनर्स्थापित डेटाबेसले टुटेका पृष्ठ दिन्छ। QUIRE_MASTER_KEY बिना पुनर्स्थापित डेटाबेसले राखेका SSO, webhook र एकीकरण प्रमाण डिक्रिप्ट गर्न सक्दैन; केही अनसुलझे नभई मास्टर कुञ्जी घुमाउने सकिएसम्म (key-rotation.md), यसमा सेवानिवृत्त कुञ्जी समावेश छन्। दुवै ब्याकअपकै भाग हुन्।

ब्याकअप लिने

सम्पूर्ण क्लस्टरको आधार ब्याकअप:

docker compose -f docker/compose.yaml --profile backup run --rm backup

यसले नवीनतम QUIRE_BACKUP_KEEP आधार ब्याकअप राख्छ (पूर्वनिर्धारित 5) र सबैभन्दा पुरानोलाई नचाहिने WAL छाँट्छ, त्यसैले अभिलेख सीमाबिना बढ्न सक्दैन। होस्टमा cron वा systemd टाइमरबाट दैनिक तालिका बनाउनुहोस्:

15 2 * * * cd /srv/quire && docker compose -f docker/compose.yaml --profile backup run --rm backup >> /var/log/quire-backup.log 2>&1

वा स्ट्याकलाई तालिका बनाउन दिनुहोस्: backup प्रोफाइलले backup-scheduler चलाउँछ, जसले हरेक QUIRE_BACKUP_INTERVAL_HOURS (पूर्वनिर्धारित 24) मा आधार ब्याकअप लिन्छ, र अर्को वर्णन गरिएको backup-offsite।

docker compose -f docker/compose.yaml --profile backup up -d

इन्क्रिप्टेड होस्टबाहिर प्रतिलिपि

दुवै भोल्युम डेटाबेसकै होस्टमा बस्छन्, र असफल भएको मेसिनको ब्याकअप ब्याकअप होइन। backup-offsite ले हरेक आधार ब्याकअप र हरेक अभिलेख WAL खण्ड भण्डारण पोर्टमार्फत छुट्टै भण्डारमा प्रतिलिपि गर्छ, इन्क्रिप्टेड, र अवधारणअन्तर्गत त्यहाँ राख्छ:

  • इन्क्रिप्सन। QUIRE_BACKUP_ENCRYPTION_KEY (वा QUIRE_BACKUP_ENCRYPTION_KEY_FILE ले नाम दिएको फाइल) सहित AES-256-GCM: 32 बाइट, openssl rand -hex 32 बाट। हरेक फाइलको आफ्नै nonce र प्रमाणीकरण ट्याग हुन्छ, त्यसैले प्रतिलिपि कुञ्जीबिना अपठनीय छ र यसमा कुनै परिवर्तन पत्ता लाग्छ। कुञ्जी QUIRE_MASTER_KEY सँग, यस होस्ट र ब्याकअप भण्डारबाट टाढा राख्नुहोस्। कुञ्जीबिना पुनर्स्थापना छैन।
  • कहाँ। QUIRE_BACKUP_STORAGE_DRIVER s3, azure वा local हो (QUIRE_BACKUP_STORAGE_ROOT मा माउन्ट गरिएको टाढाको डिस्क)। सेटिङ QUIRE_BACKUP_ उपसर्गसहित फाइल भण्डारणकै हुन्: QUIRE_BACKUP_S3_ENDPOINT, QUIRE_BACKUP_S3_BUCKET, QUIRE_BACKUP_S3_ACCESS_KEY_ID, आदि। फाइलबाट फरक बकेट र, आदर्श, फरक खाता प्रयोग गर्नुहोस्, प्रदायकले दिएमा लेख्न सक्ने तर मेट्न नसक्ने प्रमाणसहित।
  • अवधारण। नवीनतम QUIRE_BACKUP_OFFSITE_KEEP आधार ब्याकअप (पूर्वनिर्धारित QUIRE_BACKUP_KEEP, नत्र 7) र तिनमध्ये सबैभन्दा पुरानोलाई चाहिने WAL; पुराना सेट र खण्ड भण्डारबाट मेटिन्छन्।
  • कहिले। हरेक QUIRE_BACKUP_SHIP_INTERVAL_SECONDS (पूर्वनिर्धारित 300)। पठाउने आइडेम्पोटेन्ट छ: पहिल्यै भण्डारण गरिएको छोडिन्छ, र आधार ब्याकअप भण्डारण गणना हुन्छ यसको मेनिफेस्ट लेखिएपछि मात्र, अन्त्यमा।

उही आदेश हातले चल्छ:

docker compose -f docker/compose.yaml run --rm backup-offsite bun apps/worker/src/backups/main.ts ship
docker compose -f docker/compose.yaml run --rm backup-offsite bun apps/worker/src/backups/main.ts verify

नयाँ होस्टमा पुनर्स्थापना गर्न, पहिले सेट फिर्ता ल्याउनुहोस्, त्यसपछि pgbackup भोल्युमको ठाउँमा ल्याइएको डाइरेक्टरी र wal-archive लाई pgwal को ठाउँमा राखेर तलका चरण पछ्याउनुहोस्:

bun apps/worker/src/backups/main.ts fetch base-20260924T021500Z /srv/restore

निश्चित समयमा पुनर्स्थापना

डेटा हानिपछि यो प्रयोग गर्नुहोस्: खराब आयात, मेटिएको पाठ्यक्रम, उल्ट्याउनुपर्ने सम्झौता माइग्रेसन। यसले प्रत्यक्ष डेटाबेस प्रतिस्थापन गर्छ, त्यसैले पहिले तलको अभ्यासबाट यसको पूर्वाभ्यास गर्नुहोस्।

  1. लक्षित समय छान्नुहोस्, UTC मा, क्षतिअघि: 2026-09-24 09:30:00+00। अडिट लग (/admin/audit) ले सामान्यतया क्षण देखाउँछ।
  2. लेख्ने सबै रोक्नुहोस्: docker compose -f docker/compose.yaml stop web content worker scheduler collab
  3. क्षतिग्रस्त क्लस्टर राख्नुहोस् पुनर्स्थापना प्रमाणित नभएसम्म:
    docker compose -f docker/compose.yaml stop postgres
    docker run --rm -v quire_postgres18-data:/from -v quire_postgres-damaged:/to alpine cp -a /from/. /to/
  4. लक्ष्यभन्दा पुरानो नवीनतम आधार ब्याकअप डेटा भोल्युममा खोल्नुहोस्, र लक्षित पुनःप्राप्ति माग्नुहोस्:
    docker run --rm -v quire_pgbackup:/backups:ro -v quire_postgres18-data:/var/lib/postgresql postgres:18-alpine sh -euc '
      base="$(ls -1d /backups/base-* | sort | tail -n 1)"   # or the one before the target
      rm -rf /var/lib/postgresql/18/docker && mkdir -p /var/lib/postgresql/18/docker
      tar -xzf "$base/base.tar.gz" -C /var/lib/postgresql/18/docker
      touch /var/lib/postgresql/18/docker/recovery.signal
      chown -R postgres:postgres /var/lib/postgresql/18/docker && chmod 700 /var/lib/postgresql/18/docker'
  5. पुनःप्राप्ति: पुनःप्राप्ति सेटिङसहित Postgres एकपटक सुरु गर्नुहोस्, Compose ओभरराइडबाट ताकि सामान्य फाइल नछोइयोस्:
    # docker/compose.recover.yaml
    services:
      postgres:
        command: [postgres, -c, "restore_command=cp /var/lib/postgresql/wal-archive/%f %p",
                  -c, "recovery_target_time=2026-09-24 09:30:00+00",
                  -c, recovery_target_action=promote, -c, archive_mode=off,
                  -c, max_connections=200, -c, hba_file=/etc/postgresql/pg_hba.conf]
    ओभरराइडले सम्पूर्ण आदेश प्रतिस्थापन गर्छ, त्यसैले यसले पुनःप्राप्ति निर्भर गर्ने दुई सेटिङ दोहोर्‍याउँछ: प्राइमरीको भन्दा कम नहुने max_connections (नत्र पुनःप्राप्ति “insufficient parameter settings” सहित रोकिन्छ) र माउन्ट गरिएको pg_hba.conf।
    docker compose -f docker/compose.yaml -f docker/compose.recover.yaml up -d postgres
    docker compose -f docker/compose.yaml logs -f postgres   # wait for "database system is ready"
  6. जाँच्नुहोस् कसैलाई छिर्न दिनुअघि: अडिट शृङ्खला (docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts), र हराएको डेटा फर्किएको।
  7. सामान्यमा फर्कनुहोस्: docker compose -f docker/compose.yaml up -d। यसले Postgres लाई अभिलेख खोलिएकोसहित पुनः सुरु गर्छ, र नयाँ WAL टाइमलाइन सुरु हुन्छ। तुरुन्तै नयाँ आधार ब्याकअप लिनुहोस्।

परियोजना नाम quire ले हरेक भोल्युम उपसर्ग गर्छ; docker volume ls ले ठ्याक्कै नाम देखाउँछ।

तालिकाबद्ध प्रमाणीकरण अभ्यास

backup-offsite ले हरेक QUIRE_BACKUP_DRILL_INTERVAL_HOURS (पूर्वनिर्धारित 168, साप्ताहिक) मा अभ्यास पनि चलाउँछ, र असफल भएपछि अर्को पासमा फेरि। यसले नवीनतम होस्टबाहिर आधार ब्याकअप र त्यसपछिका हरेक WAL खण्ड ल्याउँछ, हरेक डिक्रिप्ट गर्छ (जसले कुञ्जीले अझै खोल्छ र केही परिवर्तन भएन प्रमाणित गर्छ), हरेक फाइल यसको मेनिफेस्टसँग तुलना गर्छ, अभिलेख Postgres डेटा डाइरेक्टरी हो जाँच्छ, र ब्याकअपदेखिको WAL मा खाडल छैन जाँच्छ। प्रतिवेदन भण्डारमा reports/drill-<time>.json का रूपमा र सेवाको लगमा लेखिन्छ; असफल अभ्यासले फाइल वा पहिलो छुटेको खण्ड नाम दिन्छ।

पुनर्स्थापना अभ्यास

कहिल्यै पुनर्स्थापना नगरिएको ब्याकअप ब्याकअप होइन। अभ्यासले लक्ष्यअघि लिइएको नवीनतम पूर्ण आधार ब्याकअप, साथै WAL अभिलेख, प्रत्यक्षसँग केही साझा नगर्ने स्क्र्याच Postgres मा पुनर्स्थापना गर्छ, र नतिजा प्रमाणित गर्छ:

docker/scripts/restore-drill.sh                                  # to ninety minutes ago
docker/scripts/restore-drill.sh --target "2026-09-24 09:30:00+00"

लक्ष्य ठ्याक्कै त्यो रूपमा UTC हो। यसलाई लक्ष्यभन्दा पुरानो आधार ब्याकअप र त्यसभन्दा पर अभिलेख WAL चाहिन्छ: नयाँ स्थापनामा, आधार ब्याकअप लिनुहोस् र अर्को अभिलेख खण्ड पर्खनुहोस् (लेखनसहित बढीमा एक मिनेट) ब्याकअपपछिको लक्ष्य छान्नुअघि। अभ्यासलाई होस्टमा Docker र bash चाहिन्छ, अरू केही होइन।

हरेक चरणले अभ्यास असफल गर्छ:

  1. पुनःप्राप्तियोग्यता: स्क्र्याच क्लस्टर लक्ष्यमा पुनः चल्छ र खुल्छ।
  2. पूर्णता: प्रत्यक्ष डेटाबेसविरुद्ध हरेक तालिकाको पङ्क्ति गणना (tooling/restore-drill)। प्रत्यक्ष डेटाबेस लक्ष्ययता अघि बढेको छ, त्यसैले तालिका 500 पङ्क्ति र यसको आकारको दशांशमध्ये ठूलोले फरक हुन सक्छ, कुनै दिशामा (लेखनले पछाडि पार्छ, मेट्नेले पुनर्स्थापनामा बढी राख्छ); लक्ष्यपछि बनाइएको विभाजन हराएको तालिका होइन। व्यस्त स्थापनामा QUIRE_DRILL_MAX_BEHIND र QUIRE_DRILL_MAX_DRIFT_RATIO बाट छूट फराकिलो बनाउनुहोस्। छुटेको वा खाली तालिका असफल हुन्छ।
  3. अखण्डता: पुनर्स्थापित प्रतिलिपिमा अडिट ह्यास शृङ्खला प्रमाणित हुन्छ।
  4. प्रयोगयोग्यता: अनुप्रयोग भूमिकाले पङ्क्ति-स्तर सुरक्षामार्फत पढ्छ।
  5. समय: सुरुदेखि हरियोसम्म, QUIRE_DRILL_RTO_SECONDS विरुद्ध (पूर्वनिर्धारित 3600)।

यसले प्रत्यक्ष डेटाबेस वा यसका भोल्युममा कहिल्यै लेख्दैन: ब्याकअप र WAL भोल्युम पठन-मात्र माउन्ट हुन्छन् र स्क्र्याच क्लस्टर अन्त्यमा हटाइन्छ, पास वा असफल।

JSON प्रतिवेदन लेख्न QUIRE_DRILL_REPORT लाई पथमा सेट गर्नुहोस्, पास वा असफल, र Docker होस्टबाट तालिकामा चलाउनुहोस्:

30 3 1 * * cd /srv/quire && QUIRE_DRILL_REPORT=/var/log/quire-drill.json docker/scripts/restore-drill.sh >> /var/log/quire-drill.log 2>&1

मासिक र हरेक स्तरोन्नतिअघि चलाउनुहोस्। असफल अभ्यासले स्तरोन्नति अवरुद्ध गर्छ। त्रैमासिकमा, यो रनबुक नलेख्ने कसैलाई यो दस्तावेज मात्र प्रयोग गरेर खाली होस्टमा वास्तविक निश्चित समय पुनर्स्थापना गर्न लगाउनुहोस्।

फाइलहरू

स्थानीय फाइल files भोल्युममा बस्छन्। डेटाबेससँग, उही समयमा ब्याकअप गर्नुहोस्, र दुवै सँगै पुनर्स्थापना गर्नुहोस्:

docker run --rm -v quire_files:/files:ro -v "$PWD":/out alpine tar -czf /out/files-$(date -u +%Y%m%d).tar.gz -C /files .

वस्तु भण्डारणसँग, बकेट संस्करण खोल्नुहोस् र 35 दिन गैरहालका संस्करण राख्नुहोस्; फाइलका लागि निश्चित समय पुनःप्राप्ति त्यसपछि बकेटकै हुन्छ।

नेभिगेसन

खोज्न टाइप गर्नुहोस्…

↑↓ नेभिगेट↵ छान्नुहोस्Esc बन्द गर्नुहोस्