fix: Solve space issues in VG→Borg backups

Problem: VG→Borg was creating temp files for all LVs simultaneously,
causing 'no space left' errors when LVs are large.

Solution: Process LVs sequentially instead of simultaneously:
1. Create snapshot for one LV
2. Stream it directly to Borg (no temp files)
3. Remove snapshot immediately
4. Move to next LV

Changes:
- VG→Borg now creates separate archives per LV instead of one big archive
- Each LV gets its own archive: vg_internal-vg_lv_root_20241009_123456
- No temporary files needed - direct streaming
- Space-efficient: only one snapshot exists at a time
- More robust: failure of one LV doesn't affect others

Benefits:
- No more space issues regardless of LV sizes
- Faster cleanup between LVs
- Individual LV recovery possible
- Better error isolation
- Still preserves block-level backup benefits
This commit is contained in:
root
2025-10-09 00:51:15 +02:00
parent aee3d5019c
commit c86fee78cb
4 changed files with 64 additions and 73 deletions

View File

@@ -392,50 +392,36 @@ case "$MODE" in
log "Found logical volumes: $(echo $LV_LIST | tr '\n' ' ')"
# Create base temp directory for block images
BASE_TEMP_DIR=$(mktemp -d -t borg_vg_backup_XXXXXX)
SNAPSHOTS_CREATED=""
# Create snapshots and copy them to temporary block files
# Process each LV one by one to avoid space issues
for LV_NAME in $LV_LIST; do
SNAPSHOT_NAME="${LV_NAME}_borg_snap"
SNAPSHOT_PATH="/dev/$SOURCE/$SNAPSHOT_NAME"
LV_PATH="/dev/$SOURCE/$LV_NAME"
TEMP_IMAGE="$BASE_TEMP_DIR/${LV_NAME}.img"
log "Processing LV: $LV_NAME"
log "Creating snapshot: $SNAPSHOT_NAME"
lvcreate -L500M -s -n "$SNAPSHOT_NAME" "$LV_PATH" || {
warn "Failed to create snapshot for $LV_NAME"
continue
}
SNAPSHOTS_CREATED="$SNAPSHOTS_CREATED $SNAPSHOT_PATH"
# Copy snapshot to temporary image file
log "Creating block image for $LV_NAME"
dd if="$SNAPSHOT_PATH" of="$TEMP_IMAGE" bs=4M || {
warn "Failed to create block image for $LV_NAME"
continue
# Create individual archive for this LV
ARCHIVE_NAME="vg_${SOURCE}_lv_${LV_NAME}_$(date +%Y%m%d_%H%M%S)"
log "Backing up $LV_NAME to archive: $ARCHIVE_NAME"
log "Streaming raw block device directly to Borg..."
dd if="$SNAPSHOT_PATH" bs=4M | borg create --stdin-name "${LV_NAME}.img" --progress --stats "$TARGET::$ARCHIVE_NAME" - || {
warn "Backup of $LV_NAME failed"
}
done
# Create Borg archive
ARCHIVE_NAME="vg_${SOURCE}_$(date +%Y%m%d_%H%M%S)"
log "Creating Borg archive (block-level): $ARCHIVE_NAME"
log "Backing up all LV snapshots as raw block devices..."
borg create --progress --stats "$TARGET::$ARCHIVE_NAME" "$BASE_TEMP_DIR" || error "Borg backup failed"
log "Block-level VG Borg backup completed successfully"
# Cleanup
log "Cleaning up temporary files and snapshots"
rm -rf "$BASE_TEMP_DIR"
for SNAPSHOT_PATH in $SNAPSHOTS_CREATED; do
# Clean up this snapshot immediately to save space
log "Removing snapshot $SNAPSHOT_PATH"
lvremove -f "$SNAPSHOT_PATH" || warn "Failed to remove snapshot $SNAPSHOT_PATH"
done
log "Block-level VG Borg backup completed successfully"
log "Created individual archives for each LV in VG $SOURCE"
log "VG to Borg backup completed successfully"
;;
esac