مهمّةُ نسخٍ تتوقّف عن العمل لا تُعلن ذلك أبدًا تقريبًا. فبريد cron يذهب إلى صندوق لا يقرؤه أحد، والسكربت يخرج برمزٍ غير صفر إلى الفراغ، ويُكتشَف الفشل في اليوم الوحيد الذي احتيج فيه إليها. والعلاج أن يكون النجاح هو ما يُراقَب لا الفشل.

اعرف ما الذي حدث

journalctl -u backup.service -n 100 --no-pager
tail -100 /var/log/backup.log
ls -la /srv/backup/ | tail          # has anything arrived recently

الأسباب الأربعة المعتادة

  • لا مساحة — امتلأت الوجهة. df -h. ومدّة الحفظ لا تُقلّم: انظر مدّة الحفظ.
  • وانتهاء الاعتمادات — مفتاحٌ دُوِّر أو رمز S3، فتُكتَب النسخة محليًّا ولا تغادر أبدًا.
  • وملفٌّ لا يمكن قراءته — تغيّرت الصلاحيات، فيخرج rsync أو tar برمزٍ غير صفر وقد أنجز أغلب العمل.
  • وفشلُ نسخة قاعدة البيانات — انتهاء مهلة قفلٍ أو صلاحية ناقصة، بينما نجح جزء الملفّات وبدت التشغيلة سليمة.

اجعل السكربت يفشل بصوتٍ عالٍ

#!/usr/bin/env bash
set -euo pipefail        # stop at the first error, and at an unset variable
trap 'echo "BACKUP FAILED at line $LINENO" | mail -s "backup failed" ops@example.com' ERR

بلا ‎set -o pipefail‎ يُبلّغ mysqldump | gzip بالنجاح كلّما نجح gzip — حتى إن مات mysqldump في منتصف الطريق. وذلك الخيار الغائب وحده أشيع سبب لأن تُحفَظ نسخةٌ مقطوعة على أنها سليمة.

ونبّه على الصمت لا على الأخطاء

اجعل المهمّة تنبض إلى مفتاح «رجل ميّت» عند النجاح. فإن انقطعت النبضة أُخبِرتَ، وهذا يغطّي أيضًا حالة أن يكون الخادم مُطفأً فلا يُنتَج خطأ أصلًا.

# last line of the backup script
curl -fsS -m 10 --retry 3 https://hc-ping.com/your-uuid > /dev/null
وافحص الحجم كما تفحص رمز الخروج. فنسخةٌ صارت فجأةً عُشر نسخة الأسبوع الماضي هي فشلٌ أبلغ بالنجاح — وهذا شكل كل كارثة نسخٍ صامتة.