Восстановление поврежденного 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, получится что-то типа:
1 2 3 4 5 6 7 8 |
ftp -i -n $HOST $PORT<< EOF user $USER $PASS binary put $SRC_FILE $DEST_FILE bye EOF |
После этого все начинает работать так, как и ожидалось.
Author: | Tags: /
| Rating:
3 comments.
Write a comment