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

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

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

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

المنصة

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

الدعم

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

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

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

أتمتة backup لـ PostgreSQL بـ restic وتنبيهات Telegram — السكربت الكامل

📅 ٢٠ أبريل ٢٠٢٦⏱ 5 دقائق قراءة
أتمتة backup لـ PostgreSQL بـ restic وتنبيهات Telegram — السكربت الكامل

أتمتة backup لـ PostgreSQL بـ restic وتنبيهات Telegram

لو الـ backup بتاع الـ production DB بتاعك مرّة في الأسبوع، يعني أسوأ يوم في السنة ممكن يكلّفك 6 أيام شغل مضيّع. الأسوأ من كده: سكربت cron شغّال من سنة وما حدش بيعرف إنه فاشل من تلات شهور، لأن مفيش تنبيه. المقال ده بيحل المشكلتين دول بسكربت واحد.

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

معظم الفرق الصغيرة بتعمل pg_dump جوا cron، بتحطه في فولدر على نفس السيرفر، وبتكتفي بده. في الحالة دي بتخسر حاجتين: مش بتعرف إن الـ backup فشل غير لما تحتاجه، والـ backup نفسه في نفس الـ blast radius بتاع السيرفر. لو الـ disk ضاع، الاتنين بيضيعوا مع بعض.

خوادم في غرفة بيانات ترمز لعملية النسخ الاحتياطي الآلي لقواعد بيانات PostgreSQL

ليه restic بدل pg_dump + tar؟

قبل ما ندخل في الكود، خلّينا نفهم restic بمثال بسيط: تخيّل إنك عندك دفتر فيه 200 صفحة، وكل يوم بتعدّل صفحة أو اتنين بس. pg_dump + tar بيصوّر الـ 200 صفحة من الأول كل يوم. restic بيصوّر أول مرة كامل، وبعدها بيصوّر الصفحات اللي اتغيّرت فقط ويربطها بالنسخة القديمة، فلو حبيت ترجع لأي يوم بيجمّعلك الصورة الكاملة من القطع.

بشكل دقيق: restic بيستخدم content-defined chunking لتقسيم البيانات لقطع صغيرة، وبيـ hash كل قطعة. لو الـ hash موجود قبل كده في الـ repository، القطعة ما تترفعش تاني. ده اللي بيخلّيه يدي 3 مزايا رئيسية:

  • Incremental فعلي: قاعدة حجمها 20GB وبتتغيّر 200MB يوميًا → بعد 30 يوم الـ repository هيكون حوالي 26GB بدل 600GB.
  • تشفير مدمج: AES-256 قبل ما البيانات تطلع من السيرفر. encryption-at-rest على الـ storage لوحده مش كفاية لما الـ dump نفسه plaintext.
  • Deduplication: لو نفس الجدول موجود في snapshot إمبارح والنهارده من غير تغيير، بيتخزن مرة واحدة.

الافتراض هنا: قاعدة البيانات أصغر من 500GB. فوق كده، pg_dump هيعمل lock طويل — محتاج WAL streaming بدل الـ dump، وهنرجعله في قسم "متى لا تستخدم".

السكربت الكامل

الفكرة: pg_dump بيكتب ستريم لـ restic مباشرة عبر stdin من غير ملف مؤقت على الـ disk. لو أي خطوة فشلت، trap بيلتقط الخطأ ويبعت آخر 20 سطر من الـ log على Telegram.

Bash
#!/usr/bin/env bash
set -euo pipefail

export RESTIC_REPOSITORY="s3:s3.amazonaws.com/my-haies-backups/postgres"
export RESTIC_PASSWORD_FILE="/etc/restic/pw"
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."

TG_TOKEN="123456:AA..."
TG_CHAT="-100123456789"
LOG=/var/log/pg-backup.log
STAMP=$(date +%F_%H-%M)

notify() {
  local status="$1"
  local body
  body=$(tail -n 20 "$LOG" | sed 's/&/%26/g; s/ /%20/g; s/$/%0A/g' | tr -d '\n')
  curl -s -X POST "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
    --data-urlencode "chat_id=${TG_CHAT}" \
    --data-urlencode "text=[${status}] pg-backup ${STAMP}

${body}"
}

trap 'notify FAILED; exit 1' ERR

{
  echo "== start ${STAMP} =="
  pg_dump -Fc -d haies_prod \
    | restic backup --stdin --stdin-filename "haies_prod_${STAMP}.dump" \
        --tag daily --tag pg
  restic forget --keep-daily 14 --keep-weekly 8 --keep-monthly 6 --prune
  echo "== done =="
} >> "$LOG" 2>&1

notify OK

ضيفه في crontab يشتغل 3 صباحًا بعد ما الـ traffic ينام:

Bash
0 3 * * * /usr/local/bin/pg-backup.sh

الأرقام الفعلية بعد أسبوع تشغيل

على قاعدة بيانات production حجمها 18GB مع ~300MB تغيير يومي:

  • الـ backup الأول: ~4 دقائق، حجمه 6.2GB بعد الضغط.
  • الـ backups اليومية بعد كده: 12–25 ثانية، إضافة 40–90MB في الـ repository.
  • التكلفة على S3 Standard بعد 30 يوم: ~0.65 دولار/شهر.
  • زمن restore لأي snapshot محدد: ~3 دقائق لسيرفر بـ SSD و 1Gbps.

الأرقام دي تقديرية وبتتفاوت حسب نسبة الضغط ونوع البيانات — جداول نصية بتتضغط أكتر بكتير من binary blobs زي صور مخزّنة داخل الـ DB.

مخطط توضيحي لتدفق البيانات من قاعدة PostgreSQL عبر restic إلى تخزين S3 مع تنبيهات Telegram

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

بتكسب: backup يومي مشفّر خارج السيرفر، استرجاع لحظي لأي يوم في آخر 14 يوم، وتنبيه فوري لو حاجة فشلت بدل ما تكتشف كل ده لما يكون فات الأوان.

بتخسر حاجتين: الـ restic index بيحتاج ذاكرة — repository 100GB ممكن يستهلك 500MB RAM وقت الـ prune. على سيرفر بـ 1GB RAM مش هتعمله وقت الـ peak. تانيًا: لو ضاع ملف الباسورد (/etc/restic/pw) الـ repository كله خردة ولا حد يقدر يفكه. احتفظ بنسخة من الباسورد في password manager منفصل — مش على نفس السيرفر.

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

قاعدة البيانات فوق 500GB أو بتتعدّل بمعدل ≥ 100 كتابة/ثانية باستمرار → pg_dump هيعمل lock طويل وقت التصوير وممكن يبطّئ الـ transactions. في الحالة دي استخدم Point-in-Time Recovery عبر wal-g أو pgBackRest مع WAL archiving مستمر.

كمان لو الـ RPO المطلوب (أقصى قدر من البيانات ممكن تخسره) أقل من ساعة، snapshot يومي مش كفاية أصلًا — محتاج WAL archiving كل دقيقة على الأقل.

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

شغّل السكربت يدويًا مرة واحدة: ./pg-backup.sh. بعد ما يخلّص، اعمل restic snapshots وتأكد إن الـ snapshot ظهر. بعدها الخطوة الأهم — اللي 80% من الناس بتنساها: ادّي سيرفر تاني فاضي، اعمل restic restore latest --target /tmp/pg، وحمّل الـ dump في PostgreSQL جديد. لو الاسترجاع اشتغل فعلًا، ساعتها بس تقدر تقول إن عندك backup شغّال.

مصادر

  • restic docs — Backing up
  • PostgreSQL — pg_dump reference
  • Telegram Bot API — sendMessage
  • wal-g — WAL archiving للقواعد الكبيرة
  • pgBackRest — Point-in-Time Recovery

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

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

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