]]>
ваш баннер
]]>

Администрирование сайта. Backup базы данных с помощью PHP скрипта и ограничения хостинга

8 апреля, 2008

Логотип для backup базы данных
Недавно я столкнулся с небольшой проблемой. Нужно было организовать автоматическое создание резервных копий базы данных.

Задача, конечно, стандартная, а, учитывая объем базы (меньше 1МБ), может быть решена без специального софта и оборудования.

Так что я выбрал самый простой способ (осуществляется в три этапа):

1) создание дампа БД;
2) упаковка дампа в архив;
3) отправка архива на eMail.

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

Т.е. все, что нужно сделать – написать скрипт и запускать его с помощью cron.

Скрипт я решил сделать на PHP, и сразу же столкнулся с проблемой.

Для создания дампа базы удобнее всего использовать утилиту mysqldump, которая у меня на хостинге прекрасно работет из консоли, но не запускается из скрипта.

Причина оказалась очень простой. В настройках PHP на сервере хостера были отключены функции: shell_exec(), exec() и т.п.

Поэтому пришлось делать backup в два этапа.

1) Создание дампа БД
Для этого планировщик я просто добавил команду:
mysqldump -uuser_name -hhost_name -puser_password db_name > /path_to_tmp/db_backup/mydbdump.sql

В результате выполнения этой команды, создается файл mydbdump.sql с дампом базы, который будет размещен в папке /path_to_tmp/db_backup/. В параметрах команды, естественно, нужно указать настоящие имена базы, пользователя, пароль и путь к папке /tmp.

Примечание. Для папки /path_to_tmp/db_backup/ должны быть установлены права на запись.

2) Упаковка дампа в архив и отправка по eMail

Эти операции выполняются одним скриптом.

Code (php)
  1. <?php
  2. /**
  3. * Эту функцию я взял на сайте
  4. * http://www.weberdev.com/get_example-4173.html
  5. */
  6. function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
  7.     $file = $path.$filename;
  8.     $file_size = filesize($file);
  9.     $handle = fopen($file, "r");
  10.     $content = fread($handle, $file_size);
  11.     fclose($handle);
  12.     $content = chunk_split(base64_encode($content));
  13.     $uid = md5(uniqid(time()));
  14.     $name = basename($file);
  15.     $header = "From: ".$from_name." <".$from_mail.">\r\n";
  16.     $header .= "Reply-To: ".$replyto."\r\n";
  17.     $header .= "MIME-Version: 1.0\r\n";
  18.     $header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
  19.     $header .= "This is a multi-part message in MIME format.\r\n";
  20.     $header .= "–".$uid."\r\n";
  21.     $header .= "Content-type:text/plain; charset=iso-8859-1\r\n";
  22.     $header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
  23.     $header .= $message."\r\n\r\n";
  24.     $header .= "–".$uid."\r\n";
  25.     $header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n"; // use diff. tyoes here
  26.     $header .= "Content-Transfer-Encoding: base64\r\n";
  27.     $header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
  28.     $header .= $content."\r\n\r\n";
  29.     $header .= "–".$uid."–";
  30.     if (mail($mailto, $subject, "", $header)) {
  31. //        echo "mail send … OK"; // or use booleans here
  32.     } else {
  33.         echo "mail send … ERROR!";
  34.     }
  35. }
  36.  
  37. //размещение и имя файла с дампом базы
  38. $fileName = ‘/path_to_tmp/db_backup/mydbdump.sql’;
  39. //размещение архива с дампом
  40. $archivePath = ‘/home/simpleco/tmp/db_backup/’;
  41. //имя архива
  42. $archiveName = ‘rssevents_backup_’.date(‘Y_m_j_G_i’).‘.zip’;
  43.  
  44. //создаем архив
  45. $zip = new ZipArchive();
  46. if ($zip->open($archivePath.$archiveName, ZIPARCHIVE::CREATE) === TRUE) {
  47.     //добавляем в архив файл с дампом
  48.     $zip->addFile($fileName, ‘mydbdump.sql’);
  49.     $zip->close();
  50. //    echo ‘ok’;
  51. } else {
  52.     echo ‘failed creating zip’;
  53. }
  54.  
  55. //устанавливаем переменные для отправки почты
  56.  
  57. //имя и путь к файлу с архивом
  58. $my_file = $archiveName;
  59. $my_path = $archivePath;
  60. //имя отправителя
  61. $my_name = "my_name";
  62. //обратный адрес
  63. $my_mail = "admin@simplecoding.org";
  64. $my_replyto = "admin@simplecoding.org";
  65. //тема письма
  66. $my_subject = "RSS events backup";
  67. //текст письма
  68. $my_message = ‘Во вложении находится дамп базы. ‘.date(‘F-j-Y G:i’);
  69. //отправляем письмо (в третьем параметре адрес получателя)
  70. mail_attachment($my_file, $my_path, "account_name@gmail.com", $my_mail, $my_name, $my_replyto, $my_subject, $my_message);
  71.  
  72. @unlink($archivePath.$archiveName);
  73. @unlink($fileName);
  74. ?>

Разберем, как работает этот скрипт.

В начале (строки 6 - 35) объявлена функция mail_attachment, которая выполняет отправку письма с вложением. Признаюсь честно, писать эту функцию самому мне было лень :-) . Поэтому я использовал готовую – с этого сайта.

После этого, упаковываем файл с дампом в архив (строки 45 - 53). Для этого создаем объект типа ZipArchive и вызываем его метод open с параметром ZIPARCHIVE::CREATE. А с помощью метода addFile добавляем в архив файл с дампом.
И, естественно, не забываем закрыть архив (метод close).

Примечание. Подробнее почитать о создании архивов с помощью PHP можно в статье «Создание zip архивов на PHP».

Дамп упакован, добавляем его в качестве вложения к письму и отправляем (строка 70). Имена параметров функции mail_attachment говорят сами за себя, поэтому описывать я их не буду.

Завершающим этапом, удаляем файлы с дампом и архивом (строки 72, 73).

Теперь осталось только загрузить этот скрипт на сервер и добавить команду для cron.

php -q /path_to_backup_script/dbbackup.php

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

Как видите, решение получилось не очень красивое, но работоспособное. Конечно, использовать его для больших баз данных не получится. Но, с другой стороны, если ваша база содержит десятки или сотни мегабайт информации, то вряд ли она находится на shared хостинге :-) .

Удачи!

А как вы делаете бэкапы?

Понравилась статья? Подпишитесь на продолжение rss link !

]]>

Добавьте эту страницу в google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

]]>

Опубликовано в PHP, Разное

]]>

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

Вы можете отслеживать обсуждение записи с помощью RSS 2.0 rss link

Вы также можете оставить комментарий, или трекбек с Вашего сайта.

  1. Scratch 10.04.2008 в 21:51 (Ответить)

    Хороший хостинг, например, позволяет делать регулярные бэкапы всего что есть. И даже позволяет настроить автоматическую заливку на внешний http://FTP.

    А так, в свое время я писал скрипт для бэкапа. Который делал полный и инкрементальный бэкапы, формировал GZ-архивы и отправлял на мыло (или заливал на указанный FTP).

    Код для базы был выдран из PhpMyAdmin и немного переписан. (а не использовался внешний mysqldump).
    Работало достаточно быстро, и не требовало возможности запускать файлы (т.к. архивы тоже формировались при помощи PHP).

    Но с наличием нормальной системы бэкапа это совершенно не нужно :)

    1. Владимир 11.04.2008 в 13:40 (Ответить)

      >> с наличием нормальной системы бэкапа это совершенно не нужно

      Согласен, только она не всегда нормальная :-)

  2. Eagle 10.04.2008 в 22:57 (Ответить)

    А я делаю так:

    http://sypex.net/
    Sypex Dumper

    +

    CRON

    1. Владимир 11.04.2008 в 13:42 (Ответить)

      Спасибо за ссылку.
      Интересный вариант, нужно будет попробовать.

      1. Sam 11.04.2008 в 15:38 (Ответить)

        Вариант, кстати, очень даже. Я пользовал его для дампов в 200 и более мб.

  3. Зачем создавать ZIP архив в PHP, когда можно использовать Linux/Unix’овый gzip или compress.zlib:// ?

  4. Sam 11.04.2008 в 11:57 (Ответить)

    Так не попрёт?

    mailx -s “Recent Backup” me@test.com < mysqldump –add-drop-database –add-drop-table –user username –
    password=password1 –databases db1 db2

    1. Владимир 11.04.2008 в 14:43 (Ответить)

      Попрет :-)
      Если, конечно, есть доступ к mailx

      1. Sam 11.04.2008 в 14:59 (Ответить)

        Ну, к какому-то мейлеру точно должен быть доступ… не обязательно к mailx.

  5. Sam, хороший способ, спасибо, еще бы жать это счастье с помощью GZIP, но с этим уже сам смогу разобраться.

Оставить комментарий

Введите ваш комментарий

* - обязательные для заполнения поля

Quicktags:

]]>