Вчера приезжаю с отдыха, а один из проектов, над которым работал больше месяца сгорел. Сгорел во всех смыслах, большой пожар неделю назад был в украинском дата-центре в Одессе (hosting.ua), где сервер временно размещался. К счастью бэкап проекта был, его быстро восстановили, хотя потеряли часть критически не важных данных.
Суть в том, что потеря данных может быть в любом, даже в самом навороченном дата-центре. Нельзя полагаться только на RAID, дизель-генераторы и автоматизированные системы пожаротушения. Сервер могут арестовать (по ошибке или просто за компанию с другими), может пройти короткое замыкание или начаться война, попасть метеорит, застрять таракан в лопастях вентилятора или прогрызть проводку мышь, да на него кофе в конце концов могут пролить. Где-то читал, что одна комания бэкапила данные в всемирном торговом центре с одного небоскрёба на сервер в другом небоскрёбе. А потом наступило 9 сентября 2001 года.
В отдельности вероятность этих событий очень маленькая, но вместе, за годы, умноженная на человеческое разгильдяйство — какое-либо чрезвычайное событие, которое приведёт к потере целого сервера, может вполне произойти и нужно быть к этому готовым. Панацея одна — делать бэкапы, причём важно чтобы они хранились где-нибудь подальше (дома или в другом территориально расположенном дата-центре)
Самый простой способ, особенно в случае не очень часто меняющихся и важных данных, просто сохранять файлы и дампы на свой рабочий диск раз в пару недель. Ситуация осложняется, если сайтов несколько, или данные достаточно важные.
Я около года назад сделал небольшой PHP скрипт, который использую для бэкапа своих проектов. Файлик лежит в корне веб-сайта, делает бэкап базы и файлов и заливает данные на удалённый сервер. Для каждого нового сайта я заливаю этот скрипт в корень директории сайта и ставлю его выполнение раз в пару дней в cron. Раз в месяц я сливаю архивы с FTP к себе на домашний компьютер.
Я приведу команды для подобного бэкапа в linux. Для вызова консольных команд из PHP можно использовать команды exec или system. Можно на основе этих команд сделать bash скрипт.
Бэкап файлов
Сохраняем сайт в tar архив:
tar -cf {путь к получаемому tar архиву} {полный путь к директории сайта}
например: tar -cf site.tar /var/www/site.com/htdocs
Сжимаем полученный архив в tar.gz (т.к. tar не сжимает, а только пакует файлы в один):
gzip -c {путь к tar архиву} > {путь к получаемому tar.gz архиву}
например: gzip -c /var/www/site.com/htdocs/site.tar > /var/www/site.com/htdocs/site.tar.gz
Бэкап MySQL базы данных
Сохраняем базу в SQL дамп:
mysqldump —quote-names —add-drop-table —user={юзер БД} —password={пароль к БД} —host={хост, как правило localhost} {название БД}>{путь к сохраняемому SQL дампу}
например: mysqldump —quote-names —add-drop-table —user=root —password=12345 —host=localhost site_database>/var/www/site.com/htdocs/dump.sql
Аналогично сжимаем дамп базы данных в gz архив.
Восстановление данных из архивов
Распаковка файлов из tar.gz в текущую директорию:
tar zxvf {tar.gz архив}
например: tar zxvf archive.tar.gz
Восстановление базы из sql дампа:
mysql —host={хост} —user={юзер БД} —password={пароль к БД} {название БД}<{SQL дамп}
например: mysql —host=localhost —user=root —password=12345 site_database<dump.sql
Если дамп сжат в gz, то нужно его перед тем как скормить утилите mysql предварительно разархивировать:
gzip -d {название gz файла}
Заливаем на FTP средствами PHP:
Если бэкапить скриптом, то полученные архивы неплохо бы сразу залить на удалённый FTP. Простейший код для заливки файла по FTP в PHP:
$conn_id = ftp_connect({FTP сервер:порт});
$login_result = ftp_login($conn_id, {FTP логин}, {FTP пароль});
if ($conn_id && $login_result) $upload = ftp_put($conn_id, {путь к заливаемому файлу}, {путь сохраняемого файла по FTP}, FTP_BINARY);
ftp_close($conn_id);
Шифруем архивы средствами GPG:
Чтобы можно было использовать любой FTP хостинг, а также без опасений заливать и хранить бэкапы где угодно, неплохо бы их шифровать. Я для шифрования использую GPG — аналог симметричного шифрования PGP.
Для начала создадим на сервере приватный и публичный ключ. Для шифрования нам понадобиться только публичный ключ, а для расшифрования нужен секретный ключ.
Для создания ключей выполняем: gpg —gen-key
- Тип ключа (первый вопрос) выбираем по умолчанию — 1
- Выбор размера ключа — по умолчанию 1024 (или можно 2048 байта)
- Третий вопрос, время действия ключа выбираем 0 (никогда не истекает)
- Четвёртый вопрос — указание личных данных (имя и мэйл). Главное имя — название ключа. У меня это backup_key.
- В конце нужно заполнить пароль. Пароль нужен для получения доступа к секретному ключу. НЕ ЗАБЫВАЕМ ЗАПИСАТЬ!
САМОЕ ГЛАВНОЕ! Не забываем скачать и сохранить в надёжном месте у себя на компьютере секретный и публичный ключ, и пароль к секретному ключу, а то расшифровать потом архивы самому не получиться =)
Чтобы потом импортировать ключи на новую систему, выполняем:
gpg —import {путь к asc файлу с данными ключа}
Шифрование архива средствами GPG:
gpg —recipient {название ключа} —output {получаемый шифрованный файл} —encrypt {файл для шифрования}
например: gpg —recipient backup_key —output dump.sql.gz.gpg —encrypt dump.sql.gz
Расшифрование GPG файла:
gpg -d {шифрованный файл} > {файл}
например: gpg -d dump.sql.gz.gpg > dump.sql.gz
Чтобы расшифровать архивы в Windows, можно скачать консольную GPG для Windows. Если делать шифрование средствами PHP, нужно в корневой папке апача создать папку .gnupg и положить туда публичный ключ, чтобы он мог шифровать архивы.