التعافي من الكوارث وتعدد المناطق

معمارية النسخ الاحتياطي

18 دقيقة الدرس 3 من 27

معمارية النسخ الاحتياطي

أرست الدروس السابقة RTO وRPO بوصفهما عقدَين. معمارية النسخ الاحتياطي هي النظام الهندسي الذي يُنفّذ هذين العقدين. يعرف أغلب المهندسين كيف يُشغّلون pg_dump؛ لكن قلّةً منهم صمّموا نظام نسخ احتياطي يصمد في مواجهة: فشل المنطقة الأساسية، وهجوم فدية يُشفّر حاويات النسخ الاحتياطي، ومسؤول متمرد يملك صلاحيات DELETE — كل ذلك في الليلة ذاتها. هذا هو نموذج التهديد الذي يجب أن تُصمَّم بناءً عليه معمارية النسخ الاحتياطي الاحترافية. يتناول هذا الدرس ما يجب نسخه احتياطياً فعلاً، ولماذا الثبات متطلب صارم، وكيف تتسع قاعدة 3-2-1 لتناسب البيئات السحابية الحديثة، وكيف تُغلق النسخ المتماثلة متعددة المناطق والحسابات الثغرة الأخيرة.

النسخ الاحتياطي لا يُساوي DR. النسخة الاحتياطية هي نسخة في لحظة زمنية محددة. التعافي من الكوارث هو العملية والبنية التحتية اللازمة لاستعادة الخدمة من تلك النسخة ضمن RTO المحدد. نسخة احتياطية ممتازة بلا إجراء استعادة مُختبر ليست استراتيجية DR — إنها مجرد أمل. كل ما يُغطّيه هذا الدرس يُغذّي إجراء استعادة مُختبراً، لا مجرد مهمة نسخ احتياطي تُنتج بصمة خضراء.

ما الذي يجب نسخه احتياطياً (وما الذي يجب تجاهله)

يُنفق المهندسون المتمرسون طاقةً مساوية في تحديد ما لا يستحق النسخ الاحتياطي كما يُنفقون في تحديد ما يستحقه. نسخ كل شيء يُهدر المال ويُبطئ الاستعادة؛ التقصير في النسخ يُبقي ثغرات. النموذج الذهني الصحيح هو أن تتساءل: "لو فقدت هذا الأصل ولم أستطع إعادة بنائه من أصول أخرى، ما الأثر التجاري وما وقت التعافي؟" صنّف كل فئة بيانات على امتداد هذين المحورين.

  • قواعد البيانات (الأعلى أولوية). قواعد البيانات التحويلية — PostgreSQL، MySQL، Aurora — تحوي حالةً لا يمكن إعادة توليدها. انسخها احتياطياً بكلٍّ من التصدير المنطقي (pg_dump، mysqldump) ولقطات قادرة على الاسترداد في أي لحظة (PITR). تصمد التصديرات المنطقية أمام ترحيل الهيكل (schema)؛ أما PITR فيُغلق الفجوة بين اللقطات المجدولة بإعادة تشغيل WAL/binlog للأمام.
  • مخازن الكائنات والملفات. المحتوى المُحمَّل من المستخدمين (S3، GCS) لا يمكن استبداله في الغالب. فعّل التنسيخ والنسخ المتماثل متعدد المناطق على مستوى الحاوية. لا تخلط بين نسخ S3 المتماثل والنسخ الاحتياطي — النسخ المتماثل ينقل الحذف أيضاً. تحتاج نسخاً ثابتة ذات إصدارات، إضافةً إلى حاوية "خزينة مقفلة" منفصلة.
  • الأسرار والإعدادات. مفاتيح ختم Vault، ومفاتيح CMK في KMS، وحالة Terraform. فقدان مفاتيح الختم يعني أن خزينة الأسرار بأكملها أصبحت غير متاحة بصفة دائمة. صدّر لقطات Vault؛ صدّر حالة Terraform إلى حاوية مقفلة منفصلة؛ انسخ etcd احتياطياً لمجموعات Kubernetes المُدارة ذاتياً.
  • الكود واصطلاح البنية التحتية (IaC). Git مُنسَّخ بالفعل عبر أجهزة المطورين ومزود CI. من غير المرجح أن يُتلف حادث DR جميع مستودعات git في آنٍ واحد. اعتبر مستودعات الكود ذات أولوية منخفضة للنسخ الاحتياطي الإضافي — لكن انسخ احتياطياً إعداد CI/CD الخاص بك (تعريفات المسار، أسرار المشغّل، صور السجل في سجل مخصص للتعافي من الكوارث في حساب آخر).
  • البيانات المشتقة والتخزين المؤقت. فهارس Elasticsearch المبنية من قاعدة البيانات، وكاشات Redis، وكاشات CDN — يمكن إعادة بنائها من مصدر الحقيقة. لا تنسخها احتياطياً ما لم يتجاوز وقت إعادة البناء RTO المحدد. لفهرس Elasticsearch بحجم 100 TB يستغرق 18 ساعةً لإعادة الفهرسة، انسخه احتياطياً. لكاش Redis LRU بحجم 5 GB، دعه يسخن من قاعدة البيانات عند إعادة التشغيل.
  • السجلات وبيانات المراقبة. السجلات ضخمة وتكلفة تخزينها عالية، ونادراً ما تكون ضرورية لاستعادة التطبيق. انسخ احتياطياً آخر 30 يوماً من السجلات المنظمة فقط إن اشترط الامتثال ذلك (PCI، HIPAA)؛ وإلا اعتمد على الاحتفاظ بالسجلات في SIEM/S3.

أنواع النسخ الاحتياطي ومعادلة الجدولة

جداول النسخ الاحتياطي الاحترافية نادراً ما تكون مجرد تفريغ ليلي بسيط. تُركّب ثلاثة أنواع من النسخ لتحقيق توازن بين تكلفة التخزين ووقت الاستعادة.

  • النسخة الاحتياطية الكاملة — لقطة شاملة لمجموعة البيانات. تُستعاد من أصل واحد. التكلفة: متناسبة مع حجم البيانات. قاعدة PostgreSQL بحجم 10 TB يستغرق تفريغها الكامل من 6 إلى 8 ساعات وتُنتج ملفاً مضغوطاً بحجم 2-3 TB.
  • النسخة الاحتياطية التزايدية — التغييرات منذ آخر نسخة احتياطية فحسب (كاملة أو تزايدية). رخيصة الإنتاج. تتطلب الاستعادة منها تشغيل الكاملة ثم كل تزايدية بالترتيب — سلسلة يمكن أن تطول وتُصبح هشّة.
  • النسخة الاحتياطية التفاضلية — التغييرات منذ آخر نسخة كاملة فقط. تتطلب الاستعادة الكاملة ثم تفاضلية واحدة — استعادة ثنائية الخطوات لا تمتد مدتها، لكن حجم التفاضلية يتزايد مع مرور الوقت.

الجدول الموحَّد لقواعد البيانات الكبيرة هو: كاملة أسبوعياً + تفاضلية يومية + دفق WAL/binlog مستمر. يمنحك هذا استعادةً في أي ثانية خلال الأسبوع. Aurora وRDS وCloud SQL تُنفّذ هذا بصورة أصلية؛ أما على PostgreSQL المُدار ذاتياً فاستخدم pgBackRest أو pg_basebackup مع أرشفة WAL إلى S3.

# إعداد pgBackRest: نسخة كاملة أسبوعية + تفاضلية يومية + أرشفة WAL مستمرة. # /etc/pgbackrest/pgbackrest.conf على مضيف قاعدة البيانات. [global] repo1-path=/var/lib/pgbackrest repo1-type=s3 repo1-s3-bucket=myco-db-backups-primary repo1-s3-region=us-east-1 repo1-s3-key=<IAM_ACCESS_KEY> repo1-s3-key-secret=<IAM_SECRET_KEY> repo1-cipher-type=aes-256-cbc repo1-cipher-pass=<STRONG_PASSPHRASE> # المستودع الثاني متعدد المناطق (S3 في us-west-2، حساب منفصل) repo2-path=/dr repo2-type=s3 repo2-s3-bucket=myco-db-backups-dr repo2-s3-region=us-west-2 repo2-s3-key=<DR_IAM_ACCESS_KEY> repo2-s3-key-secret=<DR_IAM_SECRET_KEY> [global:archive-push] compress-level=3 [mydb] pg1-path=/var/lib/postgresql/16/main # الجدول (crontab): # نسخة كاملة الأحد الساعة 01:00 0 1 * * 0 pgbackrest --stanza=mydb --type=full backup # نسخة تفاضلية الاثنين-السبت الساعة 01:00 0 1 * * 1-6 pgbackrest --stanza=mydb --type=diff backup # أرشفة WAL دائمة عبر archive_command في postgresql.conf

الثبات (Immutability): المتطلب غير القابل للتفاوض

باتت هجمات الفدية على البنية التحتية للنسخ الاحتياطي الآن المتجه الرئيسي لتعظيم الرافعة في المفاوضات. إن استطاع المهاجم تشفير نسخك الاحتياطية أو حذفها، فلن يكون أمام الشركة خيار سوى الدفع. الثبات يُزيل هذه الرافعة كلياً. النسخة الاحتياطية الثابتة، بمجرد كتابتها، لا يمكن تعديلها أو حذفها طوال فترة الاحتجاز المُعدَّة — لا من قِبل تطبيق، ولا مشغّل، ولا حتى حساب root السحابي.

آليتان تُنفّذان الثبات على نطاق واسع:

  • قفل كائن S3 (WORM). يُفعَّل عند إنشاء الحاوية (لا يمكن تفعيله لاحقاً). وضعان: وضع Compliance — لا أحد، بمن فيهم root AWS، يستطيع حذف الكائن خلال فترة الاحتجاز؛ وضع Governance — أدوار IAM متميزة تمتلك s3:BypassGovernanceRetention يمكنها التجاوز. استخدم وضع Compliance لخزينة DR، ووضع Governance للحاوية الأساسية للسماح بالتصحيح.
  • تخزين Azure Blob الثابت / GCS Object Hold. آليات مكافئة على جميع السحب الكبرى. استخدمها.

يدافع الثبات أيضاً ضد الحذف العرضي. مطور يُشغّل aws s3 rm --recursive على الحاوية الخطأ هو نمط فشل أكثر شيوعاً من الفدية. كلاهما يُمنع بالقفل ذاته.

# تفعيل وضع Compliance لقفل كائن S3 على حاوية خزينة DR جديدة. # يجب تفعيل Object Lock عند إنشاء الحاوية؛ لا يمكن إضافته لاحقاً. aws s3api create-bucket \ --bucket myco-db-backups-dr-vault \ --region us-west-2 \ --create-bucket-configuration LocationConstraint=us-west-2 \ --object-lock-enabled-for-bucket # تعيين احتجاز Compliance افتراضي: 90 يوماً لجميع الكائنات الجديدة. aws s3api put-object-lock-configuration \ --bucket myco-db-backups-dr-vault \ --object-lock-configuration '{ "ObjectLockEnabled": "Enabled", "Rule": { "DefaultRetention": { "Mode": "COMPLIANCE", "Days": 90 } } }' # رفض جميع عمليات الحذف وتجاوزات القفل — حتى من الحساب المالك للحاوية. aws s3api put-bucket-policy \ --bucket myco-db-backups-dr-vault \ --policy '{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyDeleteAndBypass", "Effect": "Deny", "Principal": "*", "Action": [ "s3:DeleteObject", "s3:DeleteObjectVersion", "s3:PutObjectRetention", "s3:BypassGovernanceRetention" ], "Resource": "arn:aws:s3:::myco-db-backups-dr-vault/*" } ] }'

قاعدة 3-2-1 وامتدادها السحابي الحديث

تنصّ قاعدة 3-2-1 المُقنَّنة في تسعينيات القرن الماضي على: الاحتفاظ بـ3 نسخ من البيانات، على 2 وسيطَين مختلفَين من التخزين، مع وجود 1 نسخة خارج الموقع. صُمِّمت للأشرطة الممغنطة في غرف الخوادم. امتدادها السحابي الحديث هو قاعدة 3-2-1-1-0، التي تُضيف متطلبَين جوهريَّين لنموذج التهديد المعاصر.

3-2-1-1-0 Backup Rule — Cloud-Native Production us-east-1 Copy 1 S3 Bucket same region · Governance lock Copy 2 S3 Cross-Region us-west-2 · Compliance WORM Copy 3 Glacier Deep Archive separate AWS account · air-gap +1 Offline/Air-gap Copy 3 is unreachable from the production account +0 Verified Errors Every restore is tested; zero untested backups 3-2-1-1-0 Backup Architecture 3 copies · 2 regions · 1 air-gapped · 1 immutable/offline · 0 untested
معمارية النسخ الاحتياطي 3-2-1-1-0: النسخة 1 في المنطقة الأساسية (قفل Governance)؛ النسخة 2 متعددة المناطق بوضع WORM (قفل Compliance، حاوية منفصلة)؛ النسخة 3 في حساب AWS معزول مع Glacier Deep Archive — غير قابل للوصول من بيانات اعتماد الإنتاج. المتطلب +0 يُلزم بإجراء اختبارات استعادة آلية منتظمة لتأكيد قابلية استرداد جميع النسخ.
  • الرقم "1" الإضافي يُضيف نسخة غير متصلة أو معزولة هوائياً — نسخة في حساب AWS/GCP منفصل لا يمكن اختراق بياناته الاعتمادية عبر حساب الإنتاج. حتى لو حصل المهاجم على root في حساب الإنتاج، لا يستطيع الوصول إلى الحساب المعزول. تكلفة Glacier Deep Archive في حساب منظمة منفصل نحو 0.00099$ لكل GB شهرياً — مجانية فعلياً مقارنةً بالتأمين الذي توفره.
  • الصفر "0" يُضيف صفر نسخ غير مُتحقَّق منها — يجب أن تخضع كل نسخة احتياطية لاختبار استعادة منتظم. النسخة غير المُختبَرة ليست نسخةً احتياطية. إنها مجرد افتراض. في Google SRE، يُطبَّق هذا المبدأ عبر مسارات استعادة آلية تعمل أسبوعياً: تُشغّل بيئة جديدة، تستعيد النسخة، تُشغّل تأكيد الهيكل وعدد الصفوف، وتُرسل النتيجة إلى لوحة SLO.

النسخ المتماثل متعدد المناطق والحسابات

النسخ المتماثل والنسخ الاحتياطي يخدمان غرضَين مختلفَين لكنهما يحتاجان التنسيق. نسخ S3 المتماثل متعدد المناطق (CRR) ينسخ الكائنات إلى حاوية وجهة في منطقة أخرى، عادةً خلال ثوانٍ. إنه الأداة المثلى لـتقليل RPO على بيانات الكائنات — المحتوى المُحمَّل في us-east-1 يظهر في us-west-2 خلال 15 ثانية. لكن CRR ينقل الحذف أيضاً (ما لم تُعطّل DeleteMarkerReplication: Status: Disabled صراحةً)، مما يعني أن حذف الفدية للمصدر ينتقل إلى النسخة المتماثلة. يجب أن تكون خزينة DR (النسخة 3) في حساب منفصل مع Object Lock Compliance وبلا نقل للحذف عبر CRR.

يستخدم نمط النسخ المتماثل متعدد الحسابات دور IAM في حساب الوجهة تُسمح لخدمة نسخ S3 في حساب المصدر بافتراضه. تمنح سياسة حاوية حساب الوجهة s3:PutObject فحسب — ليس s3:DeleteObject أبداً. هذا يعني أن حساب المصدر يستطيع الكتابة لكن لا يستطيع الحذف من الخزينة.

# Terraform: نسخ S3 متماثل متعدد الحسابات من الإنتاج إلى خزينة DR. resource "aws_iam_role" "s3_replication" { name = "s3-backup-replication-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [{ Effect = "Allow" Principal = { Service = "s3.amazonaws.com" } Action = "sts:AssumeRole" }] }) } resource "aws_iam_role_policy" "replication_policy" { role = aws_iam_role.s3_replication.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = ["s3:GetObjectVersionForReplication", "s3:GetObjectVersionAcl", "s3:ListBucket"] Resource = [ "arn:aws:s3:::myco-db-backups-primary", "arn:aws:s3:::myco-db-backups-primary/*" ] }, { Effect = "Allow" Action = ["s3:ReplicateObject", "s3:ReplicateDelete", "s3:ReplicateTags"] Resource = "arn:aws:s3:::myco-db-backups-dr-vault/*" } ] }) } # سياسة حاوية خزينة DR (في حساب AWS للـDR) — تسمح بـPutObject فقط. resource "aws_s3_bucket_policy" "dr_vault_policy" { provider = aws.dr_account bucket = aws_s3_bucket.dr_vault.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Sid = "AllowCrossAccountReplicate" Effect = "Allow" Principal = { AWS = "arn:aws:iam::<PROD_ACCOUNT_ID>:role/s3-backup-replication-role" } Action = ["s3:ReplicateObject", "s3:ReplicateTags"] Resource = "arn:aws:s3:::myco-db-backups-dr-vault/*" } ] }) }

مراقبة النسخ الاحتياطي وSLO الاستعادة

مسار النسخ الاحتياطي هو نظام إنتاج ويجب مراقبته بالطريقة ذاتها. المقاييس الأساسية: معدل نجاح مهام النسخ الاحتياطي، مدة النسخ (أطلق تنبيهاً إن تجاوزت القاعدة بنسبة +50% — وهو في الغالب أول إشارة لاصطدام نمو البيانات بحدود الإدخال/الإخراج)، حجم النسخة مقارنةً بالسابقة (زيادة بمقدار 10x تعني خللاً أو انفجاراً في البيانات)، وعمر آخر استعادة ناجحة (أطلق تنبيهاً إن تجاوز 7 أيام).

ضع هدف الاستعادة بشكل صريح: إن كان RPO ساعةً واحدة، يجب أن يكتمل مسار الاستعادة ضمن RTO ناقصاً الوقت اللازم لإعادة إنتاج الفشل — مما يُترك عادةً 30-60 دقيقة لاستعادة البيانات الفعلية. اختبر أن عملية الاستعادة كاملةً، بما فيها تبديل DNS وبدء تشغيل التطبيق، تُلبّي هذه الميزانية الزمنية. الاكتشاف الأكثر شيوعاً في عمليات تدقيق DR هو أن مهام النسخ الاحتياطي تنجح لكن الاستعادة تستغرق 4 أضعاف الوقت المُفترض، لأن أحداً لم يُشغّلها تحت حمل إنتاجي فعلي خلال الاثني عشر شهراً الماضية.

أتمت التحقق من الاستعادة أسبوعياً. اكتب مهمة مسار (GitHub Actions أو Jenkins أو Lambda مُجدوَل) تستعيد أحدث نسخة احتياطية إلى نسخة RDS مؤقتة، تُشغّل SELECT COUNT(*) وفحوصات hash نقطية على 10 جداول حرجة، تُؤكّد أن عدد الصفوف يقع ضمن 0.1% من الإنتاج، ثم تحذف النسخة. المهمة كلها تستغرق 20 دقيقة. فشلها يُنبّه المناوب. هذا الأتمتة الواحدة تُغلق أكبر ثغرة في وضع DR لدى أغلب المنظمات — النسخ الاحتياطية غير المُختبَرة التي لا تُكتشف إلا أثناء كارثة حقيقية.
مصيدة إنتاجية — النسخ الاحتياطي في الحساب ذاته الذي يُشغّل الإنتاج. إن اختُرق حساب AWS الإنتاجي، وكانت حاوية النسخ الاحتياطي في الحساب ذاته، يستطيع المهاجم حذف النسخ الاحتياطية والإنتاج في آنٍ واحد. أنهى هذا النمط من الفشل عدة شركات ناشئة عام 2023 خلال موجة هجمات التصيد على بيانات اعتماد AWS. يجب أن تعيش حاوية خزينة DR في حساب AWS منفصل، ومثالياً في AWS Organization منفصلة تحت عنوان بريد إلكتروني مختلف مع جهاز MFA مادي محفوظ خارج الموقع.