Резервне копіювання є важливою частиною адміністрування будь-якого веб-сайту. Втрата даних через апаратні збої, хакерські атаки або випадкове видалення може призвести до серйозних проблем. Регулярне створення резервних копій бази даних і файлів дозволяє швидко відновити сайт у разі непередбачених ситуацій.
Налаштування резервного копіювання через FTP
Припустимо, що для доступу до сайту ми маємо лише FTP. Налаштуємо резервне копіювання бази даних та файлів з віддаленого сервера на локальний за розкладом. Налаштування проводиться у декілька етапів:
- Резервне копіювання бази даних
- Резервне копіювання файлів по FTP
- Автоматизація запуску за допомогою 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
. Це і є дамп бази даних.