Problem
In packages/server/src/utils/backups/utils.ts, the getBackupCommand function generates a shell script that runs the database dump command (${backupCommand}) twice:
# First execution: "test" — output discarded
BACKUP_OUTPUT=$(${backupCommand} 2>&1 >/dev/null) || {
echo "[$(date)] ❌ Error: Backup failed"
exit 1;
}
# Second execution: actual upload — output piped to rclone
UPLOAD_OUTPUT=$(${backupCommand} | ${rcloneCommand} 2>&1 >/dev/null) || {
echo "[$(date)] ❌ Error: Upload to S3 failed"
exit 1;
}
This means every backup operation performs the database dump twice:
- The first run dumps the entire database but discards the output (just to check if the command succeeds)
- The second run dumps the database again and pipes it to rclone for upload
Impact
- Performance: Every backup takes double the time and puts double the load on the database server
- Inconsistency: The two dumps may capture different database states if writes occur between them (the uploaded backup may differ from the "verified" backup)
- Error handling gap: The success check (
BACKUP_OUTPUT) validates a dump that is never uploaded; the actual upload (UPLOAD_OUTPUT) runs a completely new dump without the pre-validation
- Large databases: For large databases, the doubled dump can cause significant timeout and memory pressure
Expected
The database dump should run exactly once, with its output piped directly into rclone for upload. Success/failure is determined by the combined exit code of the pipeline.
Fix
Remove the redundant first execution and pipe the single backup output directly to rclone:
# Remove the BACKUP_OUTPUT test block entirely
# Keep only the combined pipeline:
UPLOAD_OUTPUT=$(${backupCommand} | ${rcloneCommand} 2>&1) || {
echo "[$(date)] ❌ Error: Backup or upload failed" >> ${logPath};
echo "Error: $UPLOAD_OUTPUT" >> ${logPath};
exit 1;
}
This runs the dump exactly once, pipes it to rclone in a single streaming operation, and correctly captures any errors from either the dump or the upload step.
Problem
In
packages/server/src/utils/backups/utils.ts, thegetBackupCommandfunction generates a shell script that runs the database dump command (${backupCommand}) twice:This means every backup operation performs the database dump twice:
Impact
BACKUP_OUTPUT) validates a dump that is never uploaded; the actual upload (UPLOAD_OUTPUT) runs a completely new dump without the pre-validationExpected
The database dump should run exactly once, with its output piped directly into rclone for upload. Success/failure is determined by the combined exit code of the pipeline.
Fix
Remove the redundant first execution and pipe the single backup output directly to rclone:
This runs the dump exactly once, pipes it to rclone in a single streaming operation, and correctly captures any errors from either the dump or the upload step.