initial script version, updated README

This commit is contained in:
Markus Ressel 2020-07-28 04:14:14 +02:00
parent b1f7976f7e
commit bc4306118d
2 changed files with 75 additions and 0 deletions

View File

@ -1,2 +1,46 @@
# zfs-inplace-rebalancing
Simple bash script to rebalance pool data between all mirrors when adding vdevs to a pool.
## How it works
This script simply copies all files, deletes the original and renames the copy back to the original name. The given root directory is traversed recursively (using `find`) and each file is processed individually. At no point in time are both versions of the original file deleted.
## Prerequisites
### Balance Status
To check the current balance of a pool use:
```
zpool list -v
```
### No Deduplication
Due to the working principle of this script, which essentially creates a duplicate file on purpose, deduplication will most definitely prevent it from working as intended. If you use deduplication you probably have to resort to a more expensive rebalancing method that involves additional drives.
### Data selection
Due to the working principle of this script, it is crucial that you **only run it on data that is not actively accessed**, since the original file will be deleted.
## Usage
**ALWAYS HAVE A BACKUP OF YOUR DATA!**
```
chmod +x ./zfs-in-place-mirror-rebalance.sh
./zfs-in-place-mirror-rebalance.sh /pool/path/to/rebalance
```
Note that this script does **not** have any kind of progress bar (yet), so it might be a good idea to try a small subfolder first, or process your pool folder layout in manually selected badges.
When aborting the script midway through, be sure to check the last lines of its output. When cancelling before or during the renaming process a ".rebalance" file might be left and you have to rename it manually.
## Attributions
This script was inspired by [zfs-balancer](https://github.com/programster/zfs-balancer).
## Disclaimer
This software is provided "as is" and "as available", without any warranty.
**ALWAYS HAVE A BACKUP OF YOUR DATA!**

View File

@ -0,0 +1,31 @@
#!/usr/bin/env bash
# exit script on error
set -e
# exit on undeclared variable
set -u
function rebalance () {
file_path=$1
tmp_extension=".balance"
echo "${file_path}"
echo "Copying '${file_path}' to '${file_path}${tmp_extension}'..."
# -a -- keep attributes
# -d -- keep symlinks (dont copy target)
# -x -- stay on one system
# -p -- preserve ACLs too
cp -adxp "${file_path}" "${file_path}${tmp_extension}"
echo "Removing original '${file_path}'..."
rm "${file_path}"
echo "Renaming temporary copy to original '${file_path}'..."
mv "${file_path}${tmp_extension}" "${file_path}"
}
root_path=$1
# recursively scan through files and execute "rebalance" procedure
find "$root_path" -type f -print0 | while IFS= read -r -d '' file; do rebalance "$file"; done
echo Done!