Simple (but possibly incomplete) answer: store files you don't want to delete on a ZFS filesystem with snapshots.
Still, this would have been a non-issue on a ZFS system:
/var/recordings $ ll .zfs/snapshot/
total 72
drwxr-x---+ 7 root root 7 Apr 9 2019 0003/
drwxr-x---+ 7 root root 7 Apr 9 2019 auto-2020-11-26_00-00/
drwxr-x---+ 7 root root 7 Apr 9 2019 auto-2020-11-27_00-00/
drwxr-x---+ 7 root root 7 Apr 9 2019 auto-2020-11-28_00-00/
drwxr-x---+ 7 root root 7 Apr 9 2019 auto-2020-11-29_00-00/
drwxr-x---+ 7 root root 7 Apr 9 2019 manual-2020-10-05/
/var/recordings $ cp .zfs/snapshot/auto-2020-11-28_00-00/recording-16679.flv recording-16679.flv
(every directory/dataset contains an invisible .zfs directory "mounting" the snapshots of the dataset)>Given that we already consider it to just be a backup, we currently don’t make any further backups of this data.
Then the OP could have done:
zfs-restore-file recording-16679.flv
With `zfs-restore-file` as the following script (for example only, I hacked it up in a few minutes) : #!/bin/bash
FILE="$1"
FULL_PATH=$(realpath "$FILE")
DATASET=$(findmnt --target="${FULL_PATH}" --output=SOURCE --noheadings)
MOUNT_POINT=$(findmnt --source="${DATASET}" --output=TARGET --noheadings | head -n1)
CURRENT_INODE="$(stat -c %i "${FULL_PATH}")"
RELATIVE_PATH="$(echo "$FULL_PATH" | sed "s|^${MOUNT_POINT}/||")"
# iterate all snapshots of the dataset containing the file, most recent first
for SNAPSHOT in $( \
zfs list -t snapshot -H -p -o creation,name "${DATASET}" \
| sort -rn | awk '{print $2}' | cut -d@ -f2 \
) ; do
echo "snapshot $DATASET @ $SNAPSHOT"
SNAPSHOT_FILE="${MOUNT_POINT}/.zfs/snapshot/${SNAPSHOT}/${RELATIVE_PATH}"
SNAPSHOT_FILE_INODE="$(stat -c %i "${SNAPSHOT_FILE}")"
if [ "${SNAPSHOT_FILE_INODE}" == "" ] || [ "${SNAPSHOT_FILE_INODE}" == "${CURRENT_INODE}" ] ; then
continue
fi
echo "found the same named file with a different inode:"
ls -l "${SNAPSHOT_FILE}"
cp -i "${SNAPSHOT_FILE}" "${FILE}"
break
done
If OP didn't change the inode (overwritten with new content) then you could make another script that compares size/hash of the file, or manually specify a time of a snapshot to restore.