أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

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

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

أتمتة اختبار استعادة Postgres من S3 أسبوعيًا — backup مش بيتجرّب يبقى وهم

📅 ٢٠ أبريل ٢٠٢٦⏱ 5 دقائق قراءة
أتمتة اختبار استعادة Postgres من S3 أسبوعيًا — backup مش بيتجرّب يبقى وهم

أتمتة اختبار استعادة Postgres من النسخ الاحتياطي أسبوعيًا

لو عندك pg_dump شغّال من 8 شهور وما جرّبتش restore ولا مرة، احتمال كبير يوم الكارثة تكتشف إن آخر نسخة corrupted أو ناقصة schema. خطوة تحقّق أسبوعية واحدة بتفرق بين ساعتين ترجع فيهم الموقع، وبين 48 ساعة مفقودة وعملاء غاضبين.

المشكلة باختصار

النسخ الاحتياطي اللي ما بيتجرّبش بيعاني من 3 أنواع من الفشل الصامت:

  • الملف اتكتب على S3 لكن الـ stream اتقطع في النص والـ SHA256 ما اتحققش — الملف تالف وإنت مش عارف.
  • pg_dump نجح لكن بإصدار Postgres مختلف عن الإنتاج، فالـ restore بيعمل errors على functions أو extensions زي pgcrypto.
  • الـ DB كبرت وبقى الـ restore بياخد 6 ساعات، وإنت مفترض إنه بياخد 20 دقيقة لأنك قسته أول يوم نشرت المشروع.

كل النقط دي مش هتظهرلك إلا يوم الكارثة — أو يوم تتجرّب restore فعلًا بإرادتك في بيئة معزولة.

سيرفرات قواعد بيانات في Data Center تُشير إلى أهمية اختبار النسخ الاحتياطي قبل الكارثة

مثال بسيط قبل ما نروح للكود

تخيّل إن عندك مفتاح احتياطي للشقة مُخبّى تحت حجر في الجنينة. بتطمئن إنه موجود كل 3 شهور بـ "أكيد لسه تحته". لحد اليوم اللي تتقفل فيه بره وتروح تدوّر عليه — وتلاقي جاركك كان خد الحجر من أسبوعين علشان ترتيب. المفتاح الاحتياطي اللي ما بتتأكّدش إنه بيفتح الباب فعلًا، مش مفتاح احتياطي — ده مجرد افتراض.

نفس الكلام بالظبط على الـ database backup. Backup Restore Drill هو إنك فعليًا تاخد الملف، تحطّه في بيئة معزولة، تعمل منه قاعدة شغّالة، وتتحقّق إن البيانات صحيحة. مش بس تقرأ log كاتب "Backup completed successfully".

إزاي الحل بيشتغل على GitHub Actions

الفكرة بسيطة: workflow بيتشغّل كل أحد الساعة 3 الصبح UTC. بيعمل الخطوات دي بالترتيب:

  1. بيسحب آخر dump من S3 (أو Backblaze B2 / Cloudflare R2) من bucket الـ backup.
  2. بيشغّل Postgres في container معزول — نفس إصدار الإنتاج بالظبط.
  3. بينفّذ pg_restore من الـ dump على القاعدة المعزولة.
  4. بيشغّل استعلامات تحقّق: row count لجداول حرجة، آخر تاريخ في جدول orders، SELECT 1 على materialized views.
  5. بيبعت النتيجة على Slack مع وقت الاستعادة، حجم الملف، وأي warnings.

المثال التنفيذي — workflow كامل قابل للنسخ

YAML
name: backup-restore-test
on:
  schedule:
    - cron: '0 3 * * 0'  # Sunday 03:00 UTC
  workflow_dispatch:

jobs:
  restore:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16.2
        env:
          POSTGRES_PASSWORD: testpass
        ports: ['5432:5432']
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - name: Install tools
        run: |
          sudo apt-get update -y
          sudo apt-get install -y postgresql-client-16 awscli

      - name: Pull latest dump from S3
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET }}
        run: |
          LATEST=$(aws s3 ls s3://myapp-backups/ | sort | tail -n 1 | awk '{print $4}')
          aws s3 cp s3://myapp-backups/$LATEST ./backup.dump
          echo "SIZE=$(du -h backup.dump | cut -f1)" >> $GITHUB_ENV
          echo "FILENAME=$LATEST" >> $GITHUB_ENV

      - name: Restore dump
        run: |
          START=$(date +%s)
          PGPASSWORD=testpass pg_restore -h localhost -U postgres \
            -d postgres --clean --if-exists --no-owner ./backup.dump
          END=$(date +%s)
          echo "DURATION=$((END-START))s" >> $GITHUB_ENV

      - name: Verify integrity
        run: |
          PGPASSWORD=testpass psql -h localhost -U postgres -d postgres -c \
            "SELECT COUNT(*) AS users FROM users;" | tee result.txt
          PGPASSWORD=testpass psql -h localhost -U postgres -d postgres -c \
            "SELECT MAX(created_at) FROM orders;" | tee -a result.txt

      - name: Notify Slack
        if: always()
        run: |
          STATUS="${{ job.status }}"
          curl -X POST -H 'Content-type: application/json' \
            --data "{\"text\":\"Backup restore test: $STATUS\nFile: $FILENAME\nSize: $SIZE\nDuration: $DURATION\"}" \
            ${{ secrets.SLACK_WEBHOOK }}

ركز على نقطة واحدة مهمة: الـ image postgres:16.2 لازم تطابق إصدار الإنتاج بالظبط. لو الإنتاج على 15.6 وإنت بتختبر على 16.2، ممكن الـ restore ينجح في التجربة ويفشل في الكارثة بسبب اختلاف في تعريف generated columns أو indexes.

شاشة تعرض ملف GitHub Actions workflow مع خطوات restore و verify من Postgres dump

الأرقام الفعلية من تجربتي

على dump حجمه 2.4 GB (حوالي 18 مليون row في 34 جدول):

  • وقت السحب من S3 us-east-1: 38 ثانية.
  • وقت pg_restore: 6 دقايق 12 ثانية.
  • وقت verify queries: أقل من ثانية.
  • إجمالي الـ workflow: حوالي 8 دقايق.
  • تكلفة GitHub Actions: ضمن الـ 2000 دقيقة المجانية على plan Free. شهريًا ~32 دقيقة فقط لـ 4 تشغيلات.

المفهوم بدقة: Recovery Time Objective

الـ RTO (Recovery Time Objective) هو أقصى وقت تقدر تستحمّله إن السيستم يفضل down. لو RTO عندك ساعة، والـ restore قياس فعلي بياخد 6 دقايق، إنت في أمان. لو الـ DB كبرت والـ restore بقى ساعة و40 دقيقة، خرجت من الـ RTO وإنت مش واخد بالك. الـ workflow ده بيرصد الـ trend كل أسبوع، فلو الـ duration بدأ يزيد، تحرّك قبل ما يبقى مشكلة إنتاج.

trade-offs لازم تعرفها

بتكسب: ثقة فعلية إن الـ backup شغّال، ورصد تدهور زمن الاستعادة مبكرًا، ودوكيومنتاشن مستمر لأدوات الـ restore.

بتخسر: الـ workflow مش بيتحقق من الـ data integrity الكاملة، بس بيعمل sanity checks. لو عايز قياس أعمق، زوّد استعلامات checksum على جداول مالية. الافتراض إن حجم الـ dump ≤ 10 GB — فوق كده GitHub Actions runner (بـ 7 GB RAM و 14 GB disk) مش مناسب ومحتاج instance مخصص.

متى لا تستخدم هذه الطريقة

لو الـ DB بتاعتك أكبر من 30 GB، سيّب GitHub Actions واعمل الـ drill على EC2 spot instance مؤقت بـ Terraform. السبب: runner بـ 7 GB RAM، والـ restore لـ DB كبيرة بياخد أكتر من ساعتين، وده هيقطعّك من limits GitHub وهيكلّفك وقت debug مش مستاهل.

كمان لو عندك PITR (Point-in-Time Recovery) بـ WAL archiving، الـ drill محتاج شكل تاني: restore base backup + apply WAL segments، مش pg_restore ملف واحد. في الحالة دي استخدم أدوات زي pgBackRest أو wal-g بدل الـ workflow البسيط ده.

الخطوة التالية

افتح repo الـ infra بتاعك دلوقتي وضيف الـ workflow تحت .github/workflows/backup-restore-test.yml. اضبط secrets: AWS_KEY, AWS_SECRET, SLACK_WEBHOOK. شغّله يدويًا مرة بـ workflow_dispatch قبل ما تسيبه للـ schedule. لو نجح، إنت عندك حاجز أمان أسبوعي أغلب الشركات مش عاملاه.

مصادر

  • Postgres pg_restore official documentation
  • GitHub Actions scheduled workflows
  • GitHub Actions billing and free minutes
  • pgBackRest user guide for PITR
  • Amazon S3 pricing

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة