Назад | Перейти на главную страницу

Bash-скрипт для резервного копирования mysql - обработка ошибок

Я пытаюсь создать резервную копию нескольких таблиц MyISAM таким образом, чтобы позволить мне rsync / rdiff каталог резервных копий в удаленное место. Я придумал сценарий, который выгружает только недавно измененные таблицы и устанавливает дату файла, чтобы rsync мог забирать только измененные, но теперь я не знаю, как обрабатывать ошибки - я хотел бы сценарий для выхода со значением, отличным от 0, в случае ошибок. Как я мог это сделать?

#/bin/bash   
BKPDIR="/var/backups/db-mysql"
mkdir -p $BKPDIR
ERRORS=0

FIELDS="TABLE_SCHEMA, TABLE_NAME, UPDATE_TIME"
W_COND="UPDATE_TIME >= DATE_ADD(CURDATE(), INTERVAL -2 DAY) AND TABLE_SCHEMA<>'information_schema'"
mysql --skip-column-names -e "SELECT $FIELDS FROM information_schema.tables WHERE $W_COND;" | while read db table tstamp; do

    echo "DB: $db: TABLE: $table: ($tstamp)"
    mysqldump $db $table | gzip > $BKPDIR/$db-$table.sql.gz
    touch -d "$tstamp" $BKPDIR/$db-$table.sql.gz
done
exit $ERRORS

В mysqldump команда возвращает 0 в случае успеха и> 0 в случае предупреждения / ошибки. Поскольку вы зацикливаете, вам нужно будет защитить $ ERRORS от перезаписи последующими успешными командами, поэтому требуется немного логики

mysqldump ...
EXITSTATUS=$?
if [ "$ERRORS" -eq "0" -a "$EXITSTATUS" -ne "0" ]
   then 
       ERRORS=$EXITSTATUS 
   fi

Теперь, когда ваш скрипт завершится, он выйдет с 0 или статусом из первой обнаруженной ошибки.

Хорошо, пришлось немного переделать. Ответ Иана не сработал, так как mysqldump передается по конвейеру в gzip, поэтому я получил возвращаемое значение gzip, поэтому я использовал PIPESTATUS, а затем мне пришлось переупорядочить команду для цикла while, чтобы получить переменную Errors вне подоболочки.

#/bin/bash
ERRORS=0
BKPDIR="/var/backups/db-mysql"
mkdir -p $BKPDIR

FIELDS="TABLE_SCHEMA, TABLE_NAME, UPDATE_TIME"
W_COND="UPDATE_TIME >= DATE_ADD(CURDATE(), INTERVAL -2 DAY) AND TABLE_SCHEMA<>'information_schema'"

while read db table tstamp; do

        echo "DB: $db: TABLE: $table: ($tstamp)"
        mysqldump $db $table | gzip > $BKPDIR/$db-$table.sql.gz

        EXITSTATUS=${PIPESTATUS[0]}
        if [ "$EXITSTATUS" -ne "0" ]
        then 
                 echo "ERROR when backing up $db $table!"
                 ERRORS=$((ERRORS+1))
        fi

        touch -d "$tstamp" $BKPDIR/$db-$table.sql.gz

done < <(mysql --skip-column-names -e "SELECT $FIELDS FROM information_schema.tables WHERE $W_COND;")

if [ "$ERRORS" -ne "0" ]
then 
        echo "ERRORS when backing up MySQL!" 
fi

exit $ERRORS

я использую

ERRORS=$? 

после команды mysqldump.

$? возвращает статус последней выполненной команды.

Если вы хотите, вы можете проверить результаты после всех команд и установить ОШИБКИ на основе нескольких результатов.