diff --git a/bash/sync-conf-example.sh b/bash/sync-conf-example.sh index c4199d4..5f6fdd9 100644 --- a/bash/sync-conf-example.sh +++ b/bash/sync-conf-example.sh @@ -48,28 +48,41 @@ RSYNCOPTS+=("$FILTER") # example below will create a mysql/mariadb dump. At same time we create # a FILTERNAME file in database data directory to exclude databases directories # themselves. -function beforesync() { +beforesync() { + local -a databases + local datadir + # log is a sync.sh function. log -s -t "calling user beforesync: mysql databases dumps..." - datadir="$(mysql -sN -u root -e 'select @@datadir')" + if ! datadir="$(mysql -sN -u root -e 'select @@datadir')"; then + log -s "cannot get maria databases directory" + exit 1 + fi rm -f "$datadir/$FILTERNAME" - readarray databases <<< "$(mysql -sN -u root -e "SHOW DATABASES;")" + if ! databases=( "$(mysql -sN -u root -e "SHOW DATABASES;")" ); then + log -s "cannot get maria databases list" + exit 1 + fi for db in "${databases[@]}"; do - # exclude database directory itself - printf "- /%s/*\n " "$db" >> "$datadir/$FILTERNAME" + # do not backup database contents itself + printf -- "- /%s/*\n" "$db" >> "$datadir/$FILTERNAME" - log -n "${db}... " + log -n "$db... " case "$db" in information_schema|performance_schema) log "skipped." ;; *) - log -n "dumping to ${datadir}${db}.sql... " - mysqldump --user=root --routines "$db" > "$datadir/$db.sql" + log -n "dumping to $datadir$db.sql... " + if ! mysqldump --user=root --single-transaction --routines \ + "$db" > "$datadir/$db.sql"; then + log -s "mysqldump error" + exit 1 + fi log -n "compressing... " - gzip "$datadir/$db.sql" + gzip -f "$datadir/$db.sql" log "done." esac done @@ -77,7 +90,12 @@ function beforesync() { # cat ${datadir}/${FILTERNAME} } -function aftersync() { +aftersync() { # we may remove the dump here... log -s -t "calling user aftersync" } + +# For Emacs, shell-mode: +# Local Variables: +# mode: shell-script +# End: diff --git a/bash/sync.sh b/bash/sync.sh index 70e336c..f6cf85a 100755 --- a/bash/sync.sh +++ b/bash/sync.sh @@ -206,8 +206,11 @@ declare -A ERROR_STR=( # error strings [8]="invalid command line" [9]="missing configuration file" [10]="missing destination directory" - [11]="cannot aquire lock" + [11]="cannot acquire lock" [12]="cannot determine PID of locked directory" + [13]="error in rotation" + [14]="could not set modification time on target" + [15]="error on non-daily tree copy" ) ############################################################################### @@ -217,7 +220,7 @@ man() { sed -n '/^#%MAN_BEGIN%/,/^#%MAN_END%$/{//!s/^#[ ]\{0,1\}//p}' "$SCRIPT" | more } -usage () { +usage() { printf "usage: %s [-a PERIOD][-DflmnruvzZ] config-file\n" "$CMDNAME" exit 8 } @@ -504,6 +507,9 @@ adjust_targets trap 'error_handler $LINENO $?' ERR SIGHUP SIGINT SIGTERM trap 'exit_handler' EXIT +# activate exit on error +# set -o errexit errtrace nounset pipefail + # standard descriptors redirection. # if not DEBUG, save stdout as fd 3, and redirect stdout to temp file. # in case of DEBUG, we could close stdin, but there could be side effects, @@ -606,13 +612,11 @@ TOUCH="$DOIT touch" # $2=3. # we first build a list from $2 to zero, with 2 padded digits: 03 02 01 00 # then we remove $1-03, and move $1-02 to $1-03, $1-01 to $1-02, etc... -rotate-files () { +rotate-files() { # shellcheck disable=SC2207 - files=( $(seq -f "$DESTDIR/$1-%02g" "$2" -1 0) ) - log -s -t -n "%s deletion... " "${files[0]##*/}" - status=0 - $REMOVE "${files[0]}" || status=$? - if (( status != 0 )); then + local -a files=( $(seq -f "$DESTDIR/$1-%02g" "$2" -1 0) ) + log -s -t -n "deleting %s... " "${files[0]##*/}" + if ! $REMOVE "${files[0]}"; then # this should never happen. # But I saw this event in case of a file system corruption. Better # is to stop immediately instead of accepting strange side effects. @@ -623,12 +627,15 @@ rotate-files () { fi log "done." - log -s -t -n "%s rotation... " "$1" - while (( ${#files[@]} > 1 )) - do + log -s -t -n "rotating " "$1" + while (( ${#files[@]} > 1 )); do if $EXIST "${files[1]}" ; then - [[ $DEBUG = y ]] && log -n "%s " "${files[1]:(-2)} " - $MOVE "${files[1]}" "${files[0]}" + log -n "%s... " "${files[1]##*/}" + if ! $MOVE "${files[1]}" "${files[0]}"; then + log "error" + exit 13 + fi + fi unset "files[0]" # shift and pack array files=( "${files[@]}" ) @@ -700,14 +707,20 @@ while [[ ${TODO[0]} != "" ]]; do log -s "rsync error %d" "$status" exit 7 fi - $TOUCH "$tdest" + if ! $TOUCH "$tdest"; then + log -s "cannot change %s modification time (error %d)" \ + "$DEST/daily-00" "$status" + exit 14 + fi aftersync # script to run after the sync - else # non-daily case. - status=0 - $EXIST "$ldest" || status=$? - if ((status == 0 )); then + else # non-daily case + if $EXIST "$ldest"; then + # if ((status == 0 )); then log -s -t "%s update..." "$tdest" - $COPYHARD --link-dest="$ldest" "$ldest/" "$tdest" + if ! $COPYHARD --link-dest="$ldest" "$ldest/" "$tdest"; then + log -s "copyhard error %d" "$status" + exit 15 + fi else log "No %s directory. Skipping %s backup." "$ldest" "$todo" fi