X

Восстановление поврежденного tgz архива, после передачи по ftp.

Настраивая бэкап очередного сайта, заметил что часть архивов битая. Очень сильно удивился такому сюрпризу. Изучив ситуацию, нашел в чем дело...

Прежде всего нужно вкратце рассказать как работают бэкапы у меня:

  • На сервере с сайтами, по определенному расписанию запускается bash скрипт
  • В скрипте делается дамп базы, архивируется папка сайта и при необходимости разные доп. файлы (например кроны).
  • К именам полученных файлов добавляется метка времени и все это складывается в бэкап-папку  соответствующего сайта
  • Далее, файлы копируются на удаленный сервер с помощью утилиты ftp
  • И напоследок чистим папку с бэкапами, чтобы на исходном сервере хранить только несколько последних версий бэкапа

Как и написано, система бэкапа делает несколько архивов (минимум 2-а: база + папка сайта). Так вот на сервере бэкапов, я обнаружил что некоторые архивы открывается нормально (виден листинг файлов), а часть повреждена. Именно то, что часть архивов была в норме меня и ввело в ступор. Поврежденный файл имел примерно тот же размер что и на исходном сервере, при этом на исходном сервере файл не был поврежден. Именно поэтому я заподозрил в некорректной работе непосредственно ftp передачу между серверами.

Проблема оказалась довольно простая: несколько месяцев назад, я перенаправил все бэкапы на сервер с ОС Windows Server. Соответственно, и FTP сервер был поднят родной для Windows Server. Немного погуглив, я узнал следующее: при ASCII передаче с Linux сервера на Windows, по-разному обрабатывается перевод каретки (перевод строки). Linux передает "\n", Windows использует "\r\n". Соответственно файл ломается.

Теперь давайте разберемся, почему часть файлов билась, а часть нет. В архивах, где внутри был один единственный файл (например дамп базы), архиватор мог прочитать имя файла и показать его мне. В архивах где было несколько файлов, архиватор не могу прочитать второй файл и поэтому сразу сообщал об ошибке. Ну, а по сути при попытке разархивировать архив ошибка была в обоих случаях. Т.е. учитывайте то, что если архиватор (WinRar, 7Zip) открыл архив и вы видите имя файла, это еще не значит что архив целый.

Ладно, думаю вы уже поняли, что я получил много битых архивов. Поискав решение, я наткнулся на пост, в котором описывается ситуация похожая на мою, но самое главное там описывалось как восстановить такие файлы. Сделать это довольно просто:

Для Windows

  • Качаем файлик: http://www.gzip.org/fixgz.zip или отсюда
  • Разархивируем, находим утилиту: fixgz.exe
  • Далее передаем ей битый файл и получаем отремонтированный
  • Синтаксис команды: # fixgz broken.gz fixed.gz , где broken.gz = битый файл, fixed.gz = файл куда будет записан отремонтированный
  • Я положил этот файлик fixgz.exe в C:\Windows , дальше прошелся по проблемным файлам и все восстановил

Для Linux

  • Качаем файлик: http://www.gzip.org/fixgz.zip или отсюда
  • Распаковываем
  • Открываем в редакторе: fixgz.c и добавляем следующей строчкой "#include <stdlib.h>" после "#include <stdio.h>" (иначе при компиляции будут warning-и)
  • Далее компилируем файл: # gcc -o fixgz fixgz.c
    (при необходимости вначале установите gcc: #apt-get install gcc или #yum install gcc)
  • В итоге, в этой директории должен появиться бинарный файл fixgz, его и используем
  • Передаем битый файл и получаем отремонтированный
  • Синтаксис команды: # fixgz broken.gz fixed.gz , где broken.gz = битый файл, fixed.gz = файл куда будет записан отремонтированный

 

Теперь надо разобраться как же поправить bash скрипт, чтобы файлики отправлялись не битые? В этом нам поможет мануал на утилиту ftp, который можно найти тут: man ftp , нас интересует вот эта часть, где описываются команды, доступные после установки соединения:

binary - Устанавливает режим передачи файлов для поддержки передачи двоичных образов.

Добавляем эту команду перед командой put, получится что-то типа:

ftp -i -n $HOST $PORT<< EOF
user $USER $PASS
binary
put $SRC_FILE $DEST_FILE
bye
EOF

 

После этого все начинает работать так, как и ожидалось.

Категории: Linux Windows

Комментарии (3)

  • Благодарю, именно то, что я и искал. Тоже перекидываются дампы баз данных в gz архивах. И тоже все битые оказываются после передачи.
    Binary добавил, посмотрю на следующий бэкап.

    • Проверил - проблема решена, спасибо еще раз

      • Рад, что все получилось! Спасибо за комментарий.