Blame
|
1 | # Migration Process and Incident Analysis |
||||||
| 2 | ||||||||
| 3 | 1. Objective of migration |
|||||||
| 4 | ||||||||
| 5 | The goal was to: |
|||||||
| 6 | ||||||||
| 7 | Replace existing RAID storage with larger disks |
|||||||
| 8 | Preserve all media data and permissions |
|||||||
| 9 | Minimize downtime for Jellyfin media services |
|||||||
| 10 | 2. Migration approach |
|||||||
| 11 | Step 1 — New RAID creation |
|||||||
| 12 | Two new disks were configured in PERC as RAID1 |
|||||||
| 13 | The system exposed them as /dev/sdd |
|||||||
| 14 | Step 2 — Filesystem creation |
|||||||
| 15 | A GPT partition table was created |
|||||||
| 16 | ext4 filesystem was applied to the new volume |
|||||||
| 17 | Step 3 — Initial data transfer |
|||||||
| 18 | ||||||||
| 19 | Data was copied using: |
|||||||
| 20 | ||||||||
| 21 | rsync -aHAX --numeric-ids --progress |
|||||||
| 22 | ||||||||
| 23 | From: |
|||||||
| 24 | ||||||||
| 25 | /mnt/Media |
|||||||
| 26 | ||||||||
| 27 | To: |
|||||||
| 28 | ||||||||
| 29 | /mnt/newMedia |
|||||||
| 30 | 3. Secondary migration |
|||||||
| 31 | ||||||||
| 32 | A separate dataset was migrated: |
|||||||
| 33 | ||||||||
| 34 | /mnt/BonusDisk/JellyfinMedia/Motorvakantie 2024 |
|||||||
| 35 | → /mnt/Media/JellyfinMedia/Motorvakantie 2024 |
|||||||
| 36 | ||||||||
| 37 | This was done using rsync with preservation flags to maintain: |
|||||||
| 38 | ||||||||
| 39 | Ownership |
|||||||
| 40 | Permissions |
|||||||
| 41 | ACLs |
|||||||
| 42 | Extended attributes |
|||||||
| 43 | 4. Issue encountered during migration |
|||||||
| 44 | Symptom |
|||||||
| 45 | ||||||||
| 46 | Two MP4 files became unreadable after migration. |
|||||||
| 47 | ||||||||
| 48 | Observed error |
|||||||
| 49 | moov atom not found |
|||||||
| 50 | Invalid data found when processing input |
|||||||
| 51 | 5. Investigation outcome |
|||||||
| 52 | Key findings |
|||||||
| 53 | Files existed in both source and destination |
|||||||
| 54 | File sizes were consistent in some cases |
|||||||
| 55 | ffprobe failed on both copies |
|||||||
| 56 | Original playback still worked in media players |
|||||||
| 57 | Root cause |
|||||||
| 58 | ||||||||
| 59 | The issue was not filesystem corruption but: |
|||||||
| 60 | ||||||||
| 61 | MP4 container metadata inconsistency |
|||||||
| 62 | Likely incomplete or non-finalized file state during copy |
|||||||
| 63 | rsync faithfully copied an already problematic file state |
|||||||
| 64 | 6. Technical explanation |
|||||||
| 65 | ||||||||
| 66 | MP4 files rely on a moov atom containing index metadata. |
|||||||
| 67 | ||||||||
| 68 | Possible scenarios: |
|||||||
| 69 | ||||||||
| 70 | moov located at end of file (camera-style encoding) |
|||||||
| 71 | file copied during incomplete write/finalization |
|||||||
| 72 | metadata not properly finalized before transfer |
|||||||
| 73 | ||||||||
| 74 | This causes: |
|||||||
| 75 | ||||||||
| 76 | ffprobe failure |
|||||||
| 77 | but partial playback may still succeed in tolerant players |
|||||||
| 78 | 7. Resolution approach |
|||||||
| 79 | ||||||||
| 80 | For affected files: |
|||||||
| 81 | ||||||||
| 82 | Attempt container rebuild using ffmpeg: |
|||||||
| 83 | ||||||||
| 84 | ffmpeg -i input.mp4 -c copy -movflags +faststart output.mp4 |
|||||||
| 85 | If unsuccessful: |
|||||||
| 86 | re-copy from true original source |
|||||||
| 87 | or re-ingest from camera/archive |
|||||||
| 88 | 8. Lessons learned |
|||||||
| 89 | 1. Rsync preserves problems |
|||||||
| 90 | ||||||||
| 91 | Rsync does not validate media integrity; it replicates file state exactly. |
|||||||
| 92 | ||||||||
| 93 | 2. Media must be “finalized” before migration |
|||||||
| 94 | ||||||||
| 95 | Files actively written or not fully closed can copy as corrupted artifacts. |
|||||||
| 96 | ||||||||
| 97 | 3. Verification requires more than size checks |
|||||||
| 98 | Tools like ffprobe or checksum validation are required for media integrity |
|||||||
| 99 | 4. Two-pass rsync is essential for live systems |
|||||||
| 100 | Initial sync during operation |
|||||||
| 101 | Final sync after stopping writes |
|||||||
| 102 | 9. Best-practice migration workflow (refined) |
|||||||
| 103 | Create destination RAID and filesystem |
|||||||
| 104 | Perform initial rsync pass |
|||||||
| 105 | Stop all write processes |
|||||||
| 106 | Perform final rsync pass |
|||||||
| 107 | Validate with: |
|||||||
| 108 | rsync --dry-run |
|||||||
| 109 | media probing (ffprobe) |
|||||||
| 110 | Switch mounts via UUID in /etc/fstab |
|||||||
| 111 | Monitor system before removing old storage |
|||||||
