Backups have two independent failure points: one is that it never runs, and the second is that it runs but cannot be restored. The second is more common and more fatal—because it only reveals itself when you truly need to restore.
Most sites that believe they “have backups” have only achieved the first point.
What to Back Up
| Content | Description | Frequency Recommendation |
|---|---|---|
| Website Files | Programs, themes/plugins, uploaded files | Daily |
| Database | Easiest to miss, yet most critical | Daily or more frequently |
| Configuration Files | Nginx config, crontab, environment variables | On change |
| Certificates | Avoid re-issuing after reinstall | On change |
Scripted Backup
#!/bin/bash
# /root/backup.sh
set -e
DATE=$(date +%F)
BKDIR="/data/backup/${DATE}"
mkdir -p "$BKDIR"
# ① Database (note character set to avoid garbled text)
mysqldump -u root -p'password' --default-character-set=utf8mb4
--single-transaction --routines --triggers dbname
| gzip > "${BKDIR}/db.sql.gz"
# ② Website files
tar -czf "${BKDIR}/www.tar.gz" -C /var/www html
# ③ Configuration
tar -czf "${BKDIR}/conf.tar.gz" /etc/nginx /var/spool/cron
# ④ Retain for 30 days
find /data/backup -maxdepth 1 -type d -mtime +30 -exec rm -rf {} ;
echo "Backup completed: ${BKDIR}"
ls -lh "$BKDIR"
chmod +x /root/backup.sh
/root/backup.sh # Run manually once first to confirm files are generated
Set Up Scheduled Tasks
# Edit crontab
crontab -e
# Execute at 3 AM daily, redirect output to log
0 3 * * * /root/backup.sh >> /var/log/backup.log 2>&1
# View and confirm
crontab -l
systemctl status crond
You must redirect output to a log file. If you don’t, you won’t see anything when the script fails—this is exactly the typical cause of “thinking it’s backing up, while it has actually failed long ago.”
Offsite Storage (The Most Critical Step)
Keeping backups on the same server is equivalent to having no backup. In the event of machine failure, accidental deletion, or ransomware encryption, the backup will perish along with the server.
# Method 1: Sync to another server
rsync -avz -e 'ssh -p 22' /data/backup/ root@BackupServerIP:/data/backup/
# Method 2: Upload to object storage (using CLI tool as example)
# All major cloud providers offer CLIs with similar usage
ossutil cp -r /data/backup/ oss://bucket-name/backup/
# Method 3: Package and download locally (usable for small scale)
# Add offsite sync to crontab, placed after the backup script
30 3 * * * rsync -avz /data/backup/ root@BackupServerIP:/data/backup/ >> /var/log/backup-sync.log 2>&1
Recovery Drill (Determines if the Backup is Truly Useful)
# ① Pick a backup, restore it on another machine. Do not practice on production.
scp root@BackupServerIP:/data/backup/2026-10-01/db.sql.gz /tmp/
# ② Import into test database
gunzip < /tmp/db.sql.gz | mysql -u root -p testdb
# ③ Verify data integrity (this step cannot be skipped)
mysql -e "USE testdb; SELECT COUNT(*) FROM wp_posts; SELECT MAX(post_date) FROM wp_posts;"
# ④ Unzip files, verify structure and permissions
tar -xzf www.tar.gz -C /tmp/restore-test/
ls -l /tmp/restore-test/html | head
The drill should verify “whether it can be restored” and “whether the restored data is complete”, not just whether the files exist. These two queries, COUNT(*) and the latest timestamp, can confirm in seconds that no data is missing.
Troubleshooting Commands
# Check if backup is actually running
cat /var/log/backup.log
ls -lh /data/backup/ | tail -10
# When was the last backup?
find /data/backup -maxdepth 1 -type d | sort | tail -3
# Is the backup file intact? (gzip integrity check)
gzip -t /data/backup/2026-10-01/db.sql.gz && echo OK
# How much disk space remains? (An out-of-control backup directory can drag down the site)
df -h /data
Decision Tree
Establish Backup System
├─ ① Write script, run manually first ← Do not directly throw into crontab
├─ ② Add crontab, redirect output to log ← Otherwise failures go unnoticed
├─ ③ Sync to offsite ← Same-machine backup equals no backup
├─ ④ Perform recovery drill quarterly ← Without drills, you won't know if it works
└─ ⑤ Regularly clean old backups ← Otherwise disk fills up
When Recovery is Needed
├─ Restore on test machine first, confirm data integrity
├─ Only then touch production
└─ Take a snapshot of current state before restoring (don't let restoration become irreversible)
Scenario Simulation: Backups run every day, but none can be restored when an incident occurs
Symptom: A server is configured with daily backups, and task logs show execution every day.
During a rollback due to accidental data deletion, it is discovered that although backup files exist, they are completely unusable for restoration.
- First, confirm if the backup files themselves are intact → Check the size and time of each backup file one by one,
and find that recent ones are significantly smaller. This step is more important than rushing to find a restoration method: first determine if there is a usable source for restoration. - Try to actually restore once → Import the backup into a temporary environment,
resulting in errors: content is incomplete. File existence does not equal usable content. - Find the reason for the small size → The backup command encountered permission changes or insufficient disk space during packaging and ended midway.
Since execution results were not checked, the task still recorded as “executed.” - Corrective action: Incorporate execution results into judgment → Add validation for immediate exit on failure in the command,
instead of relying on “the task scheduler thinks it ran.” - Add alerts for “whether it succeeded” → Backup failure is the only fault that doesn’t expose itself,
so separate detection must be configured, rather than assuming daily success. - Incorporate regular drills → Periodically perform real restorations and validate data,
turning “whether it can be restored” into a verifiable fact.
# Don't just look at whether files exist, look at whether sizes are reasonable
ls -lth /backup_directory | head -10
# When encountering "configured but not actually effective" situations, prioritize checking execution results
# Recommended writing in backup scripts:
# set -euo pipefail # Exit immediately on any step failure, leaving no half-finished products
# mysqldump ... | gzip > "$OUT" || { echo "Backup failed" >&2; exit 1; }
# Independent check: Did a valid backup occur in the last day?
find /backup_directory -name '*.sql.gz' -mtime -1 | wc -l
# Periodically perform a real restoration drill (restore to temp DB, do not affect production)
zcat backup_file.sql.gz | mysql -u user -p temp_db_name
Root Cause: The backup command failed midway but was not judged as a failure.
The task scheduler is only responsible for “execution,” not “successful execution.” Lack of result validation and no drill verification.
Two key points to remember:
- The definition of an effective backup is “can be restored,” not “file exists.”
The only action that proves its effectiveness is periodic real restoration; everything else is indirect evidence. - Backup failures do not expose themselves; separate failure alerts must be configured.
If a service goes down, users will complain. If a backup goes down, you’ll only know on the day you need to restore. The two cannot rely on the same discovery mechanism.
8 Common Pitfalls
- Backup stored on the same machine: When the machine fails, the backup fails too.
- No output redirection: Failures are completely invisible.
- Adding script to crontab without manual verification: Common result is daily failure without awareness.
- Password changed but script not updated: mysqldump fails, producing empty files.
- Backing up files but not the database: Content is all in the DB, equivalent to no backup.
- Never practicing restoration: Discovering backups are unusable only when an incident occurs.
- No retention policy: Backup directories accumulate over time, filling the disk and dragging down the site.
- Unencrypted backups with open permissions: Backups contain all data and are sensitive assets themselves.
Real Customer Feedback (From Cloud Market Reviews and Consultations for Similar Products)
The following excerpts are from real buyer reviews and consultations for similar O&M services on Alibaba Cloud / Tencent Cloud / Huawei Cloud Cloud Markets (service providers include our store and peers, provided for reference only, not fictitious tickets from this site):
s****x Rating: 5.0 Jun 26, 2021 10:30
10***47 Jun 05, 2021 5.0 On-time delivery | Skilled tech | Affordable price (User did not fill in comment content) 10***15 May 28, 2021 5.0 Secure & reliable | On-time delivery | Complete after-sales Good boss, detailed answers! 10***69 Apr 27, 2021 5.0 Secure & reliable | On-time delivery | Affordable price Excellent, will come again 10***45 Mar 22, 2021 5.0 Skilled tech | Affordable price | Patient & professional 1. The input box design for requiring customers to submit “Requirement Information” is inconvenient. The light-colored placeholder text inside the prompt box contains too much content; customers cannot possibly remember it all. As soon as a single character is typed, the placeholder disappears. Then they don’t know what to write next. Suggestion for improvement: Write prompt text outside the box; or directly make the requirement information a form. Much easier for customer operation. 2. Email is unattended, wasting time. Better to explicitly direct them to contact customer service. 51***82 Mar 11, 2021 5.0 On-time delivery | Affordable price | Patient & professional (User did not fill in comment content) 10***74 Jan 24, 2021 5.0 Comprehensive features | Affordable price | Skilled tech Good configuration 10***32 Nov 27, 2020 5.0 Affordable price (User did not fill in comment content)
10***22 Jul 25, 2024 5.0 Skilled tech | On-time delivery | Comprehensive features Good tech, deployment successful