САЙТОСТРОЙ.РУ
Построй свой сайт!

Как резервировать базу данных на FTP-сервер

опубликовано 02.09.2014

Хостинг-провайдерами зачастую предоставляется услуга хранилища для backup. Но когда дело доходит до практического использования этого хранилища, оказывается, что получить туда доступ можно лишь по протоколу FTP. Другой вариант: Вы хотите хранить копию базы данных Вашего сайта на независимой площадки, чтобы обезопасить себя от случая уничтожения данных в дата-центре Вашего осногого хостинга. Можно заказать виртуальный хостинг начального уровня, на который традиционно загружаются файлы посредством FTP. В этой статье рассказывается, каким образом можно автоматически выгружать архив со свежей базой MySQL на сервер FTP и при этом контролировать число таких архивов.

Из соображений безопасности лучше всего завести отдельный MySQL-эккаунт с минимальными правами. Для использования утилиты mysqldump необходимы права: SELECT (выборка данных) и LOCK TABLES (блокировка таблиц). Под административным эккаунтом в командной строке mysql

[root@myserver] # mysql -u root -p -h localhost

создадим такого пользователя:

GRANT SELECT,LOCK TABLES ON mydatabase.* TO backuper@localhost IDENTIFIED BY "PASSWORD";
FLUSH PRIVILEGES;

Мы предоставили такой доступ ко всем таблицам Вашей базы данных mydatabase новому пользователю с логином backuper и паролем PASSWORD. Хост базы данных указан по умолчанию, когда он расположен на том же сервере, что и машина, с которой мы будем осуществлять доступ, - localhost. На виртуальном хостинге, скорее всего, это будет отдельный хост. Вторая команда необходима для немедленного вступления изменений в силу, иначе сервер MySQL не будет нас пускать под новым пользователем.

Теперь создадим скрипт db_dump

[root@myserver] # cat > /root/db_dump

для выгрузки и архивирования базы данных, следующего содержания:

rm -f /root/db_dump.zip
mysqldump mydatabase -u backuper -pPASSWORD -r /root/db_dump.sql
zip /root/db_dump.zip /root/db_dump.sql
rm -f /root/db_dump.sql

(По окончанию ввода нажмите Ctrl+D).

Этот скрипт подчищает предыдущий архив, который мы храним в папке /root/; вызывает утилиту mysqldump для дампа всех таблиц базы mydatabase под созданным нами пользователем backuper с паролем PASSWORD в файл /root/db_dump.sql; запаковывает базу /root/db_dump.sql в архив /root/db_dump.zip; удаляет исходный дамп.

Для того, чтобы скрипт мог исполняться, поставим ему атрибут выполнения:

[root@myserver] # chmod a+x /root/db_dump

Теперь перейдем к самой интересной части - скрипту для загрузки и контроля архивов на FTP-сервере. Для этого мы будем использовать PHP с модулем ftp. Чтобы проверить, подключен ли этот модуль, нужно выполнить команду:

[root@myserver] # php -m | grep ftp

Если отобразилась строка "ftp", все в порядке. В противном случае модуль необходимо подключить в файле настроек PHP - /etc/php.ini.

Теперь создадим сам скрипт, который будем называть db_to_ftp:

#!/usr/bin/php
$host="FTPHOST";
$login="FTPUSER";
$password="FTPPASSWORD";
$max_files_to_store=24*7; // 7 days

if($fc=ftp_connect($host))
{
if(ftp_login($fc, $login, $password))
{
$curtime=time();
$current_name=date("Y-m-d-H", $curtime)."H.zip";

ftp_put($fc, "db/".$current_name, "/root/db_dump.zip", FTP_BINARY);

$archives=ftp_nlist($fc,"db");
$archives_list=array();

foreach($archives as $archive_id=>$archive_name)
{
if(preg_match("#^db/([0-9]{4})-([0-9]{2})-([0-9]{2})-([0-9]{2})H.zip$#i", $archive_name, $matches))
{
$archives_list[]=array(
"timestamp"=>strtotime($matches[3].".".$matches[2].".".$matches[1]." ".$matches[4].":00:00"),
"filename"=>$archive_name
);
}
}

function time_sort($a,$b)
{
return $a["timestamp"]<$b["timestamp"];
}

usort($archives_list, "time_sort");

// files to delete
$archives_list_to_delete=array_slice($archives_list, $max_files_to_store);

foreach($archives_list_to_delete as $file_id=>$file_item)
{
ftp_delete($fc, $file_item["filename"]);
print "DELETED: ".$file_item["filename"]." ";
}

}
else
{
print "ERROR: can not login to $host. ";
}

ftp_close($fc);
}
else
{
print "ERROR: can not connect to FTP. ";
}
?>

На сервере FTP необходимо создать папку db, где и будут размещаться наши архивы. Все необходимые настройки вынесены в начало файла. В переменной $max_files_to_store хранится максимальное число архивов на сервере. Текущее значение соответствует неделе ежечасного резервирования базы. А мы разберем, что же делает скрипт:

  1. соединяется с FTP-сервером и заходит под указанным логином;
  2. загружает файл /root/db_dump.zip под именем ГОД-МЕСЯЦ-ДЕНЬ-ЧАСH.zip. Такая адресация необходима для корректного определения возраста архива. Кроме того, удобно восстанавливать нужный срез базы, имея перед глазами дату его создания;
  3. получает список файлов и присваивает им метки времени в соответствии с именем файла;
  4. сортирует этот список, отсекает устаревшие архивы и удаляет их с сервера.

Как и полагается, устанавливаем права на этот скрипт:

[root@myserver] # chmod a+x /root/db_to_ftp

Теперь нам необходимо, чтобы оба скрипта выполнялись последовательно, например, каждый час. Для этого воспользуемся планировщиком задач crond, внесем в его расписание

[root@myserver]# crontab -e

соответствующую запись (в открывшемся редакторе VIM нажимаем Shift+I и вставляем строку):

0 * * * * /root/db_dump; /root/db_to_ftp

Нажимаем Escape, вводим ":wq" и видим сообщение об успешном добавлении задания в расписание.

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

сохранённые бэкапы
 

Update. На практике обнаружено, что на некоторых серверах необходимо переходить в пассивный режим, поэтому необходимо выполнить команду:

ftp_pasv($fc, true);Используйте её, если на сервере с бэкапами стали появляться пустые архивы. Скорее всего, серверу не удаётся их выгрузить.

теги: ftp, mysql

Комментарии и вопросы

Статью никто не комментировал.


Задать вопрос или оставить комментарий

Ваше имя:
Комментарий:
Код с картинки справа:=


Просим с уважением относиться к труду автора сайта и при копировании документов указывать ссылки на http://saytostroy.ru.