Резервне копіювання бази даних
Резервне копіювання бази даних

Резервне копіювання є важливою частиною адміністрування будь-якого веб-сайту. Втрата даних через апаратні збої, хакерські атаки або випадкове видалення може призвести до серйозних проблем. Регулярне створення резервних копій бази даних і файлів дозволяє швидко відновити сайт у разі непередбачених ситуацій.

Налаштування резервного копіювання через FTP

Припустимо, що для доступу до сайту ми маємо лише FTP. Налаштуємо резервне копіювання бази даних та файлів з віддаленого сервера на локальний за розкладом. Налаштування проводиться у декілька етапів:

  1. Резервне копіювання бази даних
  2. Резервне копіювання файлів по FTP
  3. Автоматизація запуску за допомогою cron

Резервне копіювання бази даних

Реалізуємо резервне копіювання бази за допомогою PHP-скрипту, який буде розміщений на віддаленому сервері.

Створимо файл backup.php і запишемо в нього наведений нижче код, замінивши у другому рядку параметри на реальні дані SQL-бази. Цей скрипт вивантажує дамп бази, видаляє всі старі SQL-файли в поточній папці і створює новий.

Вхідні параметри

Функція backup_database_tables приймає такі параметри:

  • $sender – email-адреса відправника повідомлення про успішне резервне копіювання.
  • $recipient – email-адреса адміністратора, який отримає повідомлення.
  • $domain – домен сайту, для якого створюється резервна копія.
  • $host – хост бази даних (наприклад, localhost).
  • $name – назва бази даних.
  • $user – ім’я користувача бази даних.
  • $pass – пароль для підключення до бази даних.
  • $tables – список таблиць для резервного копіювання (може бути * для всіх таблиць).

Основні методи

  • Підключення до бази даних: Встановлення з’єднання через mysqli_connect.
  • Отримання списку таблиць: Якщо передано *, виконується SHOW TABLES, і всі таблиці додаються до списку.
  • Створення дампу бази даних: Проходження по кожній таблиці, створення запитів DROP TABLE, CREATE TABLE, INSERT INTO для кожного запису.
  • Очищення старих резервних копій: Видалення всіх .sql файлів у поточній директорії перед створенням нового.
  • Збереження дампу у файл: Файл створюється у форматі db-backup-Y.m.d_H.i-md5hash.sql.
  • Надсилання повідомлення про успіх: Використання функції mail для інформування адміністратора.

Для більш зрозумілого подання даних додамо також функціюformatSizeUnits($bytes), використовується для перетворення розміру файлу в зручний для читання формат. Вона приймає розмір файлу у байтах і повертає рядок із відповідним суфіксом (байти, КБ, МБ, ГБ тощо). Це допомагає відображати розмір резервної копії у зрозумілому вигляді в листі-повідомленні.

    При успішному виконанні резервного копіювання надсилає електронну пошту з повідомленням.

    <?php
    backup_database_tables('sender_email', 'admin_email', 'domain', 'db_host','db_name','db_user','db_password', '*');
    
    function backup_database_tables($sender, $recipient, $domain, $host, $name, $user, $pass, $tables){
        $return = '';    $link = mysqli_connect($host, $user, $pass, $name);
        // Get all of the tables
        if ($tables == '*') {
            $tables = array();
            mysqli_query($link, "SET character_set_results = 'utf8'");
            mysqli_query($link, "SET names 'utf8'");
            mysqli_query($link, "SET character_set_client = 'utf8'");
            mysqli_query($link, "SET character_set_connection = 'utf8'");
           mysqli_query($link, "SET collation_connection = 'utf8_general_ci'");
            
            $result = mysqli_query($link, 'SHOW TABLES');
            while ($row = mysqli_fetch_row($result)) {
                $tables[] = $row[0];
            }
        } else {
            $tables = is_array($tables) ? $tables : explode(',', $tables);
      }
        $return .= '/*' . date("d.m.y H:i") . '*/';
        $return .= "\n\n\n";
        // Cycle through each table and format the data
        foreach ($tables as $table) {
            $result = mysqli_query($link, 'SELECT * FROM ' . $table);
            $num_fields = mysqli_num_fields($result);
            $return .= 'DROP TABLE IF EXISTS ' . $table . ';';
            $row2 = mysqli_fetch_row(mysqli_query($link, 'SHOW CREATE TABLE ' . $table));
            $return .= "\n\n" . $row2[1] . ";\n\n";
    
            for ($i = 0; $i < $num_fields; $i++) {
                while ($row = mysqli_fetch_row($result)) {
                    $return .= 'INSERT INTO ' . $table . ' VALUES(';
                    for ($j = 0; $j < $num_fields; $j++) {
                        // Ensure the value is always a string
                        $row[$j] = isset($row[$j]) ? addslashes((string)$row[$j]) : '';
                        if (trim($row[$j]) !== '') {
                          $row[$j] = preg_replace("/\n/", "/\\n/", $row[$j]);
                    }
                        $return .= '"' . $row[$j] . '"';
                      if ($j < ($num_fields - 1)) {
                          $return .= ',';
                      }
    }$return .= ");\n";
                }
            }
            $return .= "\n\n\n";
        }
        if (glob('./*.sql')) {
            foreach (glob('./*.sql') as $fn) {
                if (is_file($fn)) unlink($fn);
            }
        }
    
        // Save the file
        $backup_name = 'db-backup-' . date("Y.m.d_H.i") . '-' . (md5(implode(',', $tables))) . '.sql';
        $handle = fopen($backup_name, 'w+');
        fwrite($handle, $return);
        fclose($handle);
    
      // Mail notification
        $mail_body = "Database dump for " . $domain . " created on " . date("d.m.y H:i") . "\n\nFile - " . $backup_name . "\n\nFile size - " . formatSizeUnits(filesize($backup_name));
      $subject = $domain . " database";
      $headers = "From: " . $sender;
        mail($recipient, $subject, $mail_body, $headers, "-f " . $sender);
    }
    
    function formatSizeUnits($bytes){
        if ($bytes >= 1073741824) {
            $bytes = number_format($bytes / 1073741824, 2) . ' GB';
        } elseif ($bytes >= 1048576) {
            $bytes = number_format($bytes / 1048576, 2) . ' MB';
        } elseif ($bytes >= 1024) {
            $bytes = number_format($bytes / 1024, 2) . ' KB';
        } elseif ($bytes > 1) {
            $bytes = $bytes . ' bytes';
        } elseif ($bytes == 1) {
            $bytes = $bytes . ' byte';
        } else {
            $bytes = '0 bytes';
        }
        return $bytes;
    }
    ?>
    

    Цей файл слід зберегти на сервері. Тепер звернення до цього файлу, наприклад, з браузера за адресою https://YOURDOMAIN/filepath/backup.php, призведе до виконання скрипта, і в папці поруч із цим файлом з’явиться новий файл, з іменем подібним до db-backup-1354181199-2f69e442c85b. Це і є дамп бази даних.

    Від Тетяна

    IT-спеціалістка, викладачка, фанатка сучасних технологій. З 2009 року занурена у світ цифрового дизайну, веб-розробки та адміністрування систем. Ділюсь знаннями про веб-технології, IT-інструменти та корисні лайфхаки, викладаю студентам, навчаюсь сама.

    Залишити відповідь

    Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *