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

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

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

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

المنصة

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

الدعم

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

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

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

Backup يومي لـ PostgreSQL على S3 في 40 سطر — استرجع DB في 4 دقايق

📅 ٨ مايو ٢٠٢٦⏱ 6 دقائق قراءة
Backup يومي لـ PostgreSQL على S3 في 40 سطر — استرجع DB في 4 دقايق

هذا المقال للمستوى المبتدئ. هتطلع منه بسكربت Backup يومي لـ PostgreSQL على S3 في 40 سطر، مع خطة استرجاع جاهزة تشتغل في أقل من 4 دقايق على DB حجمها 8GB.

Backup يومي لـ PostgreSQL على S3 — السكربت اللي بينقذك يوم ما السيرفر يقع

لو عندك DB إنتاج من غير backup أوتوماتيكي في موقع منفصل، أنت ماشي على حبل. يوم ما القرص يفسد أو حد ينفّذ DROP TABLE بالغلط، الخسارة مش بس بيانات، الخسارة وقت توقف وثقة عميل. الحل في 40 سطر bash و 5 دقايق إعداد.

سيرفرات في مركز بيانات مع أضواء زرقاء ترمز لتخزين النسخ الاحتياطية في موقع منفصل

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

كتير من الفرق الصغيرة بتعتمد على snapshot من مزوّد الاستضافة وبس. ده backup مش استراتيجية. Snapshot على نفس المزوّد بيموت لو الحساب اتقفل أو منطقة الـ availability zone وقعت ساعة كاملة. الطريقة دي بتفشل في الحالة اللي محتاج فيها الـ backup فعلًا — اللحظة اللي الكارثة فيها واصلة لكل حاجة في نفس الحساب.

تخيّل الموضوع كده — مثال للمبتدئ

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

الـ snapshot من مزوّد الاستضافة = الدُرج جنب الدفتر. الـ backup على S3 في حساب AWS مختلف = البنك في الحي التاني.

التعريف الدقيق — الفرق بين Logical و Physical Backup

Logical backup (زي اللي pg_dump بيعمله): بيقرا الجداول صف صف ويولّد ملف SQL فيه أوامر CREATE TABLE و INSERT. مرن جدًا، بيشتغل بين إصدارات مختلفة من PostgreSQL، وحجم الملف صغير بعد الضغط.

Physical backup (زي pg_basebackup): بيناخد نسخة بايت-بـ-بايت من ملفات الـ data directory. أسرع في الاسترجاع، لكنه مرتبط بإصدار PostgreSQL ومعمارية السيرفر.

الافتراض هنا: الـ DB بتاعتك أقل من 50GB، وبتستحمل قفل قراءة لمدة دقايق. فوق كده، اقرا قسم "متى لا تستخدم" في الآخر.

الأدوات اللي محتاجها

  • pg_dump: أداة رسمية شغّالة مع PostgreSQL منذ 1996، موثّقة في توثيق PostgreSQL الرسمي.
  • aws-cli v2: بترفع الملف على S3 بـ multipart upload أوتوماتيكي للملفات الكبيرة.
  • systemd timer: بديل أنظف من cron في الجدولة، logs مرتبة في journalctl.
  • bucket S3 في حساب AWS مختلف: ده الجزء المهم — مش نفس الحساب اللي السيرفر فيه.

السكربت في 40 سطر

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

DB_NAME="${DB_NAME:-app_production}"
DB_USER="${DB_USER:-postgres}"
S3_BUCKET="${S3_BUCKET:-my-db-backups}"
RETENTION_DAYS="${RETENTION_DAYS:-30}"

TIMESTAMP=$(date -u +%Y%m%d_%H%M%S)
DUMP_FILE="/tmp/${DB_NAME}_${TIMESTAMP}.sql.gz"
S3_KEY="postgres/${DB_NAME}/${TIMESTAMP}.sql.gz"

echo "[$(date -Iseconds)] Starting backup of ${DB_NAME}"

# 1) Dump مع ضغط مباشر
pg_dump --no-owner --no-acl \
  -U "${DB_USER}" -h localhost "${DB_NAME}" \
  | gzip -9 > "${DUMP_FILE}"

# 2) فحص حجم بسيط — لو طلع أقل من 1KB يبقى فشل صامت
SIZE=$(stat -c%s "${DUMP_FILE}")
if [ "${SIZE}" -lt 1024 ]; then
  echo "ERROR: dump too small (${SIZE} bytes)" >&2
  exit 1
fi

# 3) رفع على S3 بـ Standard-IA لتوفير 45% من تكلفة التخزين
aws s3 cp "${DUMP_FILE}" "s3://${S3_BUCKET}/${S3_KEY}" \
  --storage-class STANDARD_IA

rm -f "${DUMP_FILE}"

# 4) مسح أي backup أقدم من RETENTION_DAYS
CUTOFF=$(date -u -d "-${RETENTION_DAYS} days" +%Y%m%d)
aws s3 ls "s3://${S3_BUCKET}/postgres/${DB_NAME}/" \
  | awk -v d="${CUTOFF}" '$4 ~ /sql.gz$/ && substr($4,1,8) < d {print $4}' \
  | xargs -r -I{} aws s3 rm "s3://${S3_BUCKET}/postgres/${DB_NAME}/{}"

echo "[$(date -Iseconds)] Backup OK: ${S3_KEY} (${SIZE} bytes)"

السكربت ده بيعمل 4 حاجات بالظبط: dump مضغوط، فحص حجم بسيط (لو طلع 50 بايت معناه pg_dump فشل بصمت)، رفع على S3 بـ class أرخص، ومسح أي ملف أقدم من 30 يوم.

جدوله بـ systemd timer

cron شغّال لكن بيخفي الأخطاء بصمت. systemd بيكتب logs مرتبة في journalctl وبيعطيك RandomizedDelaySec علشان متبقاش كل السيرفرات بتاعتك بتعمل backup في نفس اللحظة وتكسر حدود AWS API.

# /etc/systemd/system/pg-backup.service
[Unit]
Description=PostgreSQL daily backup to S3

[Service]
Type=oneshot
EnvironmentFile=/etc/pg-backup.env
ExecStart=/usr/local/bin/pg_backup.sh
User=postgres

# /etc/systemd/system/pg-backup.timer
[Unit]
Description=Run pg-backup daily at 03:15 UTC

[Timer]
OnCalendar=*-*-* 03:15:00
RandomizedDelaySec=15min
Persistent=true

[Install]
WantedBy=timers.target

فعّله بأمرين:

Bash
sudo systemctl daemon-reload
sudo systemctl enable --now pg-backup.timer
شاشة terminal تعرض أوامر bash لتشغيل سكربت backup يدويًا قبل الجدولة

الجزء اللي 70% من الفرق بتنساه — استرجاع مُختبر

Backup من غير اختبار استرجاع = تخمين. كل أول الشهر، شغّل السكربت ده على سيرفر staging وقيس الزمن:

Bash
aws s3 cp \
  s3://my-db-backups/postgres/app_production/20260507_031500.sql.gz - \
  | gunzip \
  | psql -U postgres -d staging_restore

على DB حجمها 8GB، استرجاع كامل بياخد حوالي 3 دقايق و 40 ثانية على شبكة 100 Mbps في AWS نفسها. لو طلعلك أكتر من 10 دقايق، فيه مشكلة في إعادة بناء الـ indexes أو bandwidth — لازم تعرفها قبل ما تحتاجها وقت الكارثة، مش وقتها.

الأرقام الفعلية على workload صغير

  • DB حجمها 8GB → ملف .sql.gz بحجم 1.2GB (نسبة ضغط 85% بسبب تكرار النصوص في الجداول).
  • زمن pg_dump + رفع S3: 4 دقايق و 12 ثانية على سيرفر t3.medium.
  • تكلفة شهرية على S3 Standard-IA: 30 ملف × 1.2GB × $0.0125/GB = $0.45 شهريًا.
  • تكلفة استرجاع كامل (لو احتجته): $0.01/GB × 1.2GB = $0.012، يعني تقريبًا مجاني.

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

بتكسب: نسخة آمنة في موقع مختلف، استرجاع متوقّع زمنه معروف، تكلفة بسيطة جدًا، وملف SQL إنساني تقدر تفتحه وتشوف بياناتك.

بتخسر: pg_dump بياخد قفل قراءة طويل (ACCESS SHARE) على الجداول الكبيرة، ممكن يأثر على query latency لمدة 2-5 دقايق وقت تشغيله. كمان وقت الاسترجاع طويل بالمقارنة مع physical backup. الافتراض إنك مرتاح إن RPO = 24 ساعة (يعني ممكن تخسر بيانات يوم كامل في أسوأ سيناريو).

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

الطريقة دي بتفشل في 3 حالات بالظبط:

  1. DB حجمها فوق 100GB: pg_dump هياخد ساعتين والاسترجاع ساعة. هنا انتقل لـ WAL archiving + pg_basebackup أو حل managed زي AWS RDS automated backups.
  2. RPO المطلوب أقل من 24 ساعة: لو الخسارة المسموح بيها أقل من يوم بيانات، daily backup مش كافي — محتاج continuous archiving بـ WAL.
  3. محتاج Point-In-Time Recovery: لو محتاج ترجع للحظة محددة (مثلاً قبل الـ DROP TABLE الغلط بـ 10 دقايق)، dump يومي مش هيخدمك. محتاج WAL archiving.

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

افتح terminal، انسخ السكربت، شغّله مرة يدويًا (./pg_backup.sh) وأكّد إن الملف ظهر في S3 وحجمه منطقي مقارنة بحجم الـ DB. لو طلعت الأرقام مظبوطة، فعّل الـ timer. وحط alert على CloudWatch (أو Healthchecks.io المجاني) لو الـ object الجديد ما ظهرش لمدة 25 ساعة — ده الـ "dead man's switch" اللي بيمنعك تكتشف إن الـ backup واقف بعد شهرين.

المصادر

  • توثيق pg_dump الرسمي — postgresql.org/docs/current/app-pgdump.html
  • PostgreSQL Backup and Restore — postgresql.org/docs/current/backup.html
  • AWS S3 Storage Classes Pricing — aws.amazon.com/s3/storage-classes
  • systemd.timer manpage — freedesktop.org/software/systemd/man/systemd.timer
  • AWS CLI S3 Reference — docs.aws.amazon.com/cli/latest/reference/s3

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

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

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