Скрипт резервного копіювання. Про безпеку даних. Як прибрати старі копії файлів, зберігши кілька останніх

Способів резервного копіюваннябезліч, але особисто для мене вони мають свої мінуси через які я не використовую їх. Простіше написати кілька простих скриптів, наприклад, за допомогою так званого bat-ника або PowerShell. У цій статті я розповім, як можна налаштувати резервне копіювання за допомогою скриптів, я їх комбіную та створю зв'язки.

Схема резервного копіювання

Найчастіше backup зводиться до збереження деяких файл. Це можуть образи віртуальних машин, файли користувачів, бекап бази SQL, Вивантаження інформаційної бази 1С: Підприємство і т.д. Правильніше всі ці резервні копії файлів зберігати в іншому місці, це може бути мережна папка, зовнішній диск, стрічковий накопичувач, FTP і т.д. Завдяки зручності я використовую ftp сервер.

Давайте розберемо схему як це все відбувається:

  1. Копіюємо або переміщуємо їх до папки для відправки в архів
  2. Перевіряємо папку на наявність у ній нових backup"ів
  3. Відправляємо файли до архіву FTP сервер
  4. Видаляємо старі файли backup

У першому пункті ми створили файли, які потрібно скопіювати на наш FTP сервер. Тепер нам потрібно скопіювати їх у папку, яку відправимо на FTP. Для цього можна скористатися простою командою:

Copy "ШЛЯХ_ДО_ВИХІДНОЇ_ПАПКИ\* C:\Backup\

Виконавши цю команду, всі наші файли будуть скопійовані C:\Backup\. Виконувати цю командумає сенс, якщо Ви збираєте з різних місцьВаші backup"и. Тепер нам знадобиться скрипт, який перевірятиме папку на появу нових файлів і відправляти їх на FTP сервер. Створюємо порожній файл backup.ps1 та в нього записуємо наступний скрипт.

$a = (Get-Host).UI.RawUI $a.WindowTitle = "Sync Folder To Ftp" $ftp = "ftp://АДРЕС_FTP_СЕРВЕРА/" $localDirectory = "C:\Backup" $user = "ИМЯ_ПОЛЬЗОВАТЕЛЯ" $pass = "ПАРОЛЬ" $webclient = New-Object System.Net.WebClient $webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass) $Files = Get-ChildItem $localDirectory | Where {$_.LastWriteTime -gt (Get-Date).AddDays(-1)} foreach ($File in $Files) { $LocalFile = $File.FullName Write-Host "Getting $File from $localDirectory" -Foreground "Red" $webclient.UploadFile($ftp + $File, $LocalFile) Write-Host "Puting $File to $ftp" -Foreground "Yellow" } Write-Host "Finished Sync to $ftp" -Foreground "Green" !}

Давайте розберемо як працює даний скрипт. Спочатку задаються змінні, у яких вказується сервер, ім'я користувача, пароль, вихідна папка. Потім у рядку $Files = Get-ChildItem $localDirectory | Where ($_.LastWriteTime -gt (Get-Date).AddDays(-1)) робиться вибірка всіх файлів, у яких дата зміни більша (-qt) ніж поточна дата мінус 1 день. Тут можете підкоригувати Ваш розклад. Я резервне копіювання роблю щодня. Потім у циклі ми проходимо по кожному файлу, що задовольняє умови та відправляємо його на сервер FTP.

Щоб не займати місце на диску, я видаляю бекапи старше 30 днів. В принципі, після відправки на FTP їх можна відразу видаляти, я залишаю їх тільки для того що, якщо вони раптом знадобляться не довелося б витрачати час на скачування їх з FTP, та й зайва копія backup"ів не завадить, мало що може трапиться з FTP. Так що якщо місце Вам дозволяє, рекомендую зберігати їх і на вихідному сервері.

Для чищення папки я використовую скрипт removeOldBackups.ps1

$fullTargetPath = "C:\Backup" $deleteFiles = Get-Childitem $fullTargetPath -Recurse |

Where ($_.LastWriteTime -lt (Get-Date).AddDays(-30)) | Foreach (Remove-Item $_.FullName -Force -Recurse)Вкрай простий скрипт, поясню лише одну рядок Where($_.LastWriteTime -lt (Get-Date).AddDays(-30)) | у цьому рядку порівнюється дата зміни файлу з поточною датою мінус 30 днів, під це порівняння потраплять файли, у яких LastWriteTime менше

поточної дати

мінус 30 днів. За потреби можете підправити під Ваші потреби. ПередмоваІдея створення скрипта, який здатний у кілька кліків зробити резервну копію сайту (всі файли + дамп бази даних), з'явилася в той час, коли я працював над кількома проектами, а розробку та тестування вів на

локальному веб-сервері

. Ще тоді у мене стояв Денвер, який згодом змінив на локальний комбайн, що стрімко розвивається, з веб-служб - OpenServer.

Проекти були відвідувані, тому спочатку робилася локальна копія всього сайту, а вже після неї можна було працювати та експериментувати, не допускаючи перебоїв у роботі живого проекту. Резервну копію робив так: логінився по SSH і пакував папку проекту архіватором 7Zip або TGZ, робив дамп за допомогою mysqldump і завантажував усе це добро через веб або SCP/WinSCP.

Відразу ж ліньки далася взнаки і виникла думка про автоматизацію: "було б круто якби все що я вбиваю в консоль робилося автоматом для кожного сайту, а від мене вимагалося лише кілька кліків". Перший пошук рішення автоматизації SSH під Windows відразу ще привів мене до утиліти, яку я вже давно використовую для роботи з файлами на серверах.

  1. Принцип роботи скрипта резервного копіювання
  2. Отже, суть роботи автоматизованого скрипта резервного копіювання полягає в наступному:
  3. Запускаємо програму WinSCP, яка логіниться на сервер і робимо резервну копію сайту+БД, а також архівує всі дані, використовуючи архіватор з високим ступенемстиснення - 7Zip або TAR+GZip;
  4. Завантажуємо архів;
  5. Закриваємо WinSCP та чистимо логи + видаляємо тимчасово згенерований скрипт для WinSCP з командами;
  6. Готово! Потрібна копія ще одного сайту? - GOTO 1!

Сайтів може бути не один, а кілька, тому передбачено використання безлічі ini-файлів з окремими налаштуваннямидля кожного веб-сайту.

Усі операції з обробки та управління WinSCP буде проводити скрипт. написаний скриптовою мовою bat-файлів під Windows. За допомогою нього також реалізований простий консольний інтерфейс, який дозволяє виконувати всі необхідні операції.

Для цієї задачі, виходячи з її простоти, цілком достатньо скриптової мови bat-файлів, але все ж таки ніхто не заважає здійснити реалізацію даної системи на Autoit або ж однією з мов програмування високого рівня, Таких як C #, Delphi і т.п.

Увага! Скрипт є актуальним лише в тому випадку, якщо у вас є доступ до консолі сервера по SSH.

Інтерфейс та меню резервного копіювання

Після запуску скрипту нам доступне просте меню:

Перший пункт (тиснемо 1 та ентер) - відповідає за процес резервного копіювання та відображає список доступних конфігураційних файлів-шаблонів для сайтів.

Другий пункт - генерація шаблону конфігураційного файлу та відкриття його для редагування.

Третій пункт - Коротка довідканаписання файлів-шаблонів.

На малюнку нижче відкрито меню з вибором доступних до резервування сайтів:

Тут підпункт "0. All sites listed below" відповідає за запуск резервного копіювання всіх сайтів з вказаними нижче конфігураційними файлами. Так що можна зробити резервну копію для одного сайту або для всіх відразу.

Приклад конфігураційного файлу для скрипту

Ось приклад конфігураційного файлу somesite.com.ini для резервного копіювання сайту somesite.com:

Sitename_string=somesite_com store_path=D:\Backup\ archive_method=7z archive_password=StrOngp@sswOrd hostname=000.111.222.333 ssh_user=root ssh_password=p@ssmetotheserver mysql_user=site 85g mysql_db_name=site1_db dirs_to_backup=/var/www/somesite.com /www/* /var/www/somesite.com/www/.htaccess

Як бачите, все просто та нічого зайвого. Розкажу докладно про кожний рядок налаштувань:

sitename_string - привласнюємо виразну назву сайту (тільки латиниця та символ _ ).

store_path - шлях на локальному комп'ютері, куди буде завантажено архів із резервною копією

archive_method – метод архівації файлів сайту.

  • 7z - буде використано однойменний архіватор, на виході отримаємо архів із розширенням "zip".
  • gz - архівація за допомогою TAR+GZip, на виході вийде архів із розширенням "tgz".

archive_password - пароль на архів, працює лише коли archive_method=7z .

hostname - зовнішня IP-адреса або домен сервера, на якому хоститься сайт і БД.

ssh_user - ім'я користувача для підключення по SSH. Найчастіше для виконання всіх операцій потрібен root, хоча можна спробувати налаштувати іншого непривілейованого користувача.

ssh_password !! - пароль для вищезазначеного користувача.

mysql_user* – ім'я користувача для підключення до БД сайту на MySQL сервері.

mysql_password - пароль для вказаного MySQL користувача. Повинен бути встановлений обов'язково!

mysql_db_name – назва бази даних сайту, для якої будемо робити повний дамп.

dirs_to_backup ** - пишемо через пропуск список повних шляхів, директорій та файлів, які потрібно архівувати.

Примітки:

Якщо залишити значення порожнім то пароль буде запитаний потім у інтерактивному режимі(рекомендую не зберігати пароль).

* Передбачається що скрипти та база даних MySQLрозміщені на тому самому сервері. Тобто адреса MySQL-сервера – 127.0.0.1 (localhost).

** За замовчуванням архіватори не пакують файли.htaccess, тому потрібно додатково вказувати до них повний шлях!

** Вказувати обов'язково повні, а не відносні шляхи до папок чи файлів.

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

Підготовка до роботи та використання скрипту

Все дуже просто!

Насамперед потрібно визначитися де ми зберігатимемо скрипт з усіма його конфігураціями. Рекомендую не зберігати подібні програмита дані на локальній машинів відкритому вигляді, тому що це не безпечно, тим більше якщо в конфігураціях будуть збережені паролі для root доступудо серверів. Комплекс можна зберігати десь на зашифрованому носії або там, куди не отримають доступ віруси або сторонні люди. У плані безпеки – вибір за вами, йдемо далі.

Нехай весь комплекс розташовуватиметься по дорозі:

  • D:\Backup\ - сюди завантажуватимуться архіви з резервними копіями.
  • D:\Backup\script\ - тут лежатиме наш скрипт та програма WinSCP.

1) Завантажуємо останню налаштовану та портабельну версію програми WinSCP з сайту PortableApps - WinSCP Portable. Встановлюємо програму в папку D:\Backup\script\ - там створиться папка WinSCPPortable, а в ній буде файл WinSCPPortable.exe.

2) Завантажуємо архів зі скриптом і шаблонами ось тут - backup_sites_v1.2 і розпаковуємо його в папку D:\Backup\script\.

3) Відкриваємо файл backup_sites_v1.2.bat для редагування та правимо в секції "WinSCP configuration" шляхи:

  • "D:\Backup\script\WinSCPPortable\WinSCPPortable.exe" - шлях до програми WinSCP Portable;
  • "D:\Backup\script\WinSCPPortable\Data\settings\winscp.log" - шлях яким створюється лог-файл програми WinSCP Portable.

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

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

Створити новий шаблонсайту для скрипту можна такими способами:

  1. Просто копіюємо INI-файл, перейменувавши його під потрібною назвою, а потім правимо в ньому налаштування;
  2. Генеруємо шаблон скриптом. Запускаємо скрипт, тиснемо 2 і вводимо ім'я домену або назву сайту (тільки латиниця та символ _ ). Відкриється блокнот з новоствореним файлом, після внесених змінзбережіть його та закрийте.

Який варіант зручніше – вибирайте самі.

5) Все готово, можна запускати скрипт і намагатися робити резервну копію одного зі своїх сайтів.

Після підтвердження вибору сайту для бекапа може бути запрошений пароль користувача SSH, якщо він не був вказаний у конфігураційному файлі. Відразу запуститься вікно з логом роботи програми WinSCP, в якому буде відображено хід дій на сервері, а також прогрес завантаження готового архіву з сервера.

Коли WinSCP завершить скачування архіву, то вікно закриється, щоб завершити роботу скрипта достатньо натиснути у вікні будь-яку клавішу.

Про безпеку даних

Скрипт у процесі своєї роботи генерує тимчасовий файл".tmp" із набором команд для WinSCP. У цьому файлі є логін і пароль для доступу до сервера SSH.

В INI-шаблонах з налаштуваннями сайтів також міститься важлива інформація – це параметри доступу до БД.

Настійно НЕ рекомендую зберігати цей скрипт та файли налаштувань на дисках, до яких можна отримати прямий доступ у будь-який момент після запуску та нескладних маніпуляцій із комп'ютером. Для зберігання можна зробити шифрований диск або купити окремий носій.

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

Вся відповідальність за використання даного скрипта покладається на вас, будьте уважні!

Висновок

Скрипт можна відкоригувати і доопрацювати, щоб він став функціональнішим і проробляв ті дії, які вам потрібні на ваших сайтах.

Також даний спосібавтоматизації WinSCP можна використовувати для побудови інших скриптів, які виконуватимуть різні завданняна вашому VPS або Dedicated сервер через консоль.

Оновлено: 21.07.2017 Опубліковано: 15.08.2016

Цей скрипт написаний на Unix Shell під керуванням операційної системи CentOS. Він працюватиме на більшості систем сімейств Linuxта BSD.

Приклад скрипту

Скрипт створюватиме для кожної бази свій дамп. Це необхідно для швидкого відновленняданих.

  1. #!/bin/bash
  2. PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
  3. destination="/backup/mysql"
  4. userDB="backup"
  5. passwordDB="backup"
  6. fdate=`date +%Y-%m-%d`
  7. find $destination -type d \(-name "*-1[^5]" -o -name "*-?" \) -ctime +30 -exec rm -R() \; 2>&1
  8. find $destination -type d -name "*-*" -ctime +180 -exec rm -R() \; 2>&1
  9. mkdir $destination/$fdate 2>&1
  10. for dbname в `echo show databases | mysql -u$userDB -p$passwordDB | grep -v Database; do
  11. case $dbname in
  12. information_schema)
  13. continue;;
  14. mysql)
  15. continue;;
  16. performance_schema)
  17. continue;;
  18. test)
  19. continue;;
  20. *) mysqldump --databases --skip-comments -u$userDB -p$passwordDB $dbname | gzip > $destination/$fdate/$dbname.sql.gz;;
  21. done;

Опис скрипту

1 Вказуємо на шлях до інтерпретатора.
2 Задаємо системні змінні, щоб не довелося у скрипті прописувати повні шляхидо виконуваних файлів.
4 - 7 Задаємо змінні.
4 Каталог, в якому зберігатимемо резервні копії.
5 Обліковий запис для підключення до бази даних.
6 Пароль для підключення до бази даних.
7 Дата, коли запускається скрипт.
9 Знаходимо всі резервні копії, які старші за 30 днів і видаляємо їх. Залишаємо для архіву файли на 15 число.
10 Видаляємо всі резервні копії старше 180 днів.
11 Створюємо каталог, у якому зберігатимемо резервні копії. Як ім'я каталогу використовуємо дату запуску скрипта у форматі РРРР-MM-ДД.
13 - 25 Підключаємося до бази даних та витягуємо список усіх баз даних. Для кожної робимо резервну копію.
15 - 22 Пропускаємо службові бази information_schema, mysql, performance_schema, test.
23 Робимо резервну копію для баз.

Підготовка системи

Підключаємося до бази даних та створюємо обліковий записз правом на створення резервних копій:

> GRANT SELECT, SHOW VIEW, RELOAD, REPLICATION CLIENT, EVENT, TRIGGER, LOCK TABLES ON *.* TO backup@localhost IDENTIFIED BY "backup";

* в даному прикладіми створюємо обліковий запис backupз паролем backup.

Створюємо каталог, в якому зберігатимуться резервні копії:

mkdir -p /backup/mysql

Збереження даних на віддаленому комп'ютері

Резервні копії необхідно створювати на віддаленому комп'ютеріабо зовнішньому диску, щоб вони були доступні при виході з сервера. У цьому прикладі використовується Загальна папкана віддаленому сервері, в якій розміщуватимуться файли з backup.

Щоб спростити процес монтування мережевий папки, відкриємо для редагування наступний файл:

і додамо до нього наступний рядок:

//192.168.0.1/backup /mnt cifs user,rw,noauto,credentials=/root/.smbclient 0 0

* у цьому прикладі виконується монтування спільної папки backupна сервері з IP-адресою 192.168.0.1 у каталог /mnt. Як мережевий файлової системивикористовується cifs(протокол SMB: сервер samba або загальна папка Windows). Параметри для підключення user: дозволяє виконати монтування будь-якому користувачеві, rw: з правом на читання та запис, noauto: не монтувати автоматично при старті системи, credentials: файл, у якому написано логін та пароль для підключення до спільної папки.

Тепер створимо файл з логіном та паролем:

# vi /root/.smbclient

і приведемо його до такого вигляду:

username=backup
password=backup

* username: Ім'я користувача, password: пароль. Зрозуміло, у вашому випадку вказуються свої дані.

Тепер введіть наступну команду.

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

Завдання: Бекап данихв локальну директорію та на окремий сервер, з використанням мінімуму стороннього ПЗ, логуванням та оповіщенням адміністратора в jabber при збоях. Усі основні функції більшості програмного забезпечення для автоматичного бекапу, але без установки його, а отже без його багів (що, власне, і призвело до подібної ідеї).

А тепер до діла.

Для початку створимо та відкриємо скрипт
nano backup-script
Тепер у скрипті додамо рядок
#!/bin/bash
Оголосимо деякі змінні.
TN - TASKNAME - ім'я завдання. Використовується для виведення в лог та визначення назви файлу.
Так як завдань кілька (щомісячне, щотижневе, щоденне) і писати на кожен випадок скрипт було ліньки, я створив універсальний, в якому треба просто розкоментувати потрібні рядки. Найменування завдань писати треба без прогалин, бажано в латиниці, якщо не хочете проблем із кодуванням та неправильними параметрами команд.
TN=docs-monthly
#TN=docs-weekly
#TN=docs-daily
OF – Output File – ім'я вихідного файлу. Виходить із змінної TN, тобто імені завдання.
OF=$TN.tar.gz
Оголошуємо змінну шляхом до файлу лога, і далі всі повідомлення про помилки і решту будемо виводити в лог.
LOGFILE=/var/log/backup.log
Зробимо запис у балку про початок бекапу (дата, час, ім'я завдання)
echo >>$LOGFILE echo "=========================================== ==========" >>$LOGFILE echo "$(date +"%d-%b-%Y %R")" >>$LOGFILE echo "Завдання \"$TN\" запущено. .." >>$LOGFILE
Є проблема в тому, що якщо вказувати в параметрах команд (напр. tar) імена каталогів з пробілами, скрипт спрацьовує з помилкою. Рішення знайдено на просторах інтернету - операційна система linuxвикористовує пробіл як стандартний роздільник параметрів команди. Перевизначимо стандартний роздільник (зберігається у змінній $IFS) відмінним від пробілу, наприклад \n - знаком перенесення рядка.
Запам'ятовуємо старе значення стандартного роздільника
OLD_IFS=$IFS
Замінюємо стандартний роздільник своїм
IFS=$"\n"
SRCD - SouRCe Directory - каталог з даними для бекапу
Тепер можна перераховувати кілька каталогів, роздільником буде перенесення рядків, як ми самі вказали рядком вище
SRCD="/mnt/source/folder_1 /mnt/source/folder_2 /mnt/source/folder_N"
TGTD - TarGeT Directory - каталог у який будуть складатися бекапи
TGTD="/var/backups/"
Природно ми розуміємо, що зберігати важливі бекапи тільки на джерелі як мінімум легковажно. Тому залишимо копію і на віддаленому ресурсі, який окремо монтуватимемо за допомогою mount і fstab. Відразу поясню чому я використав mount і fstab, а не один mount - я монтую цей каталог і в інших своїх скриптах, а як сказав один із знайомих програмістів - хороший програмістне писатиме той самий код двічі (якось так, буквально не пам'ятаю, але сподіваюся сенс доніс).
TGTD2="/mnt/archive/"
Сам процес архівування у варіанті "Створити новий архів"
tar -czf $TGTD$OF $SRCD &>>$LOGFILE
та у варіанті "Оновити файли у старому архіві"
tar -u -f $TGTD$OF $SRCD &>>$LOGFILE
У другому випадку краще замість $OF використовувати конктретне ім'я файлу тому що у мене, наприклад, щодня апдейтіться щотижневий архів, а їх $TN (імена завдання) не збігаються, відповідно і $OF.

У змінній "?" цурається статус виконання останньої команди. Збережемо його, щоб скористатися пізніше.
STATUS = $?
Повертаємо стандартний роздільник до вихідного значення
IFS=$OLD_IFS
Тепер додамо умову - якщо процес упаковки в архів tarзакінчився з помилкою, відправляємо повідомлення адміну, видаляємо невдалий файлбекапа. Інакше продовжуємо далі – монтуємо мережеву кулю та кидаємо в неї копію архіву. Після кожної операції перевіряємо результат виконання, пишемо логи, або продовжуємо, або сповіщаємо адміна і перериваємо процедуру.
if [[ $STATUS != 0 ]]; then rm $TGTD$OF &>>$LOGFILE echo "#################################### ######" >>$LOGFILE echo "### Відбулася помилка! ##########################" >>$LOGFILE echo "$(date +"%d-%b-%Y %R%nФайл ") бекапа $OF не створено" | sendxmpp -t -f /usr/local/etc/XMPP_settings логін_отримувача@домен &>>$LOGFILE else echo "Файл бекапу збережено як \"$TGTD$OF\"" >>$LOGFILE echo "Бекап успішно завершено в $(date +"%R %d-%b-%Y")!" >>$LOGFILE echo "Монтування файлової системи для резервного архіву $TGTD_archive" >>$LOGFILE mount $TGTD2 &>>$LOGFILE if [[ $? ! = 0]]; then echo "############################################### ###############" >>$LOGFILE echo "### Відбулася помилка при монтуванні резервного ресурсу ###" >>$LOGFILE echo "########## ################################################## #" >>$LOGFILE echo "$(date +"%d-%b-%Y %R%nФайл") бекапа $OF не скопійовано на резервний ресурс" | sendxmpp -t -f /usr/local/etc/XMPP_settings логін_одержувача@домен &>>$LOGFILE exit fi echo "Почато копіювання файлу на резервний ресурс" >>$LOGFILE cp -f $TGTD$OF $TGTD_archive$OF &>> $LOGFILE if [[ $? ! = 0]]; then echo "############################################### ###############" >>$LOGFILE echo "### Сталася помилка при копіюванні на резервний ресурс ###" >>$LOGFILE echo "######### ################################################## ##" >>$LOGFILE echo "$(date +"%d-%b-%Y %R%nФайл") бекапа $OF не скопійовано на резервний ресурс" | sendxmpp -t -f /usr/local/etc/XMPP_settings логін_отримувача@домен &>>$LOGFILE else echo "Копіювання файлу успішно завершено в $(date +"%R %d-%b-%Y")!" >>$LOGFILE echo "Файл скопійований як \"$TGTD_archive$OF\"" >>$LOGFILE fi echo "Розмонтування файлової системи для резервного архіву $TGTD_archive" >>$LOGFILE umount $TGTD2 &>>$LOGFILE echo "Всі операції завершено успішно!" >>$LOGFILE fi exit

У процесі ми копіюємо архів з локального хвали в віддалене. Звичайно, перевіряємо, що кожна операція успішно завершена, і пишемо все в логі.
Для надсилання повідомлення адміністратору я використовую XMPP повідомлення, тому що в організації піднято Jabber-сервер, і я більше люблю отримати швидке повідомленняпро збій, ніж лізти в пошту, вбиваючи паролі, тикаючи на посилання, і чекаючи поки що браузер мені все відобразить. У жодному разі ніхто не заважає вам використовувати sendmail замість sendxmpp.
Файл /usr/local/etc/XMPP_settings такого змісту:

#логін_відправника@домен;IP_jabber_сервера:порт_jabber_сервера пароль_відправника login@domen;127.0.0.1:5222 password
У файлі fstabрядок описує підключення кулі Windows
//192.168.0.250/arhiv /mnt/archive cifs noauto,rw,iocharset=utf8,cp866,file_mod=0666,dir_mod=0777,noexec,_netdev,credentials=/root/.passwd_to_archive_directory 0 0
Тепер залишилося лише додати завдання до cron. Це можна зробити за допомогою файлу /etc/crontab, але я, через звичку до GUI, що залишилася у спадок від віндовс, користуюся веб-інтерфейсами для таких випадків. Команда повинна виконуватися з правами рута, тобто, наприклад, sudo bash backup_script. Додаючи команду в cron можна визначити що вона відразу виконуватиметься від імені root`а

У ході обговорень торкнулися проблеми розростання логів. Пішов найпростішим (на мій погляд) шляхом: зберігатимемо тільки останні N рядків лога, наприклад 300. У скрипт додадуться два рядки, в яких ми збережемо останні 300 рядків лога в тимчасовий файл, потім затримаємо їм лог
tail -n 300 $LOGFILE >/tmp/unique_fantastic_filename.tmp mv -f /tmp/unique_fantastic_filename.tmp $LOGFILE
Наведу повний текстскрипта:
#!/bin/bash TN=docs-monthly #TN=docs-weekly #TN=docs-daily OF=$TN.tar.gz LOGFILE=/var/log/backup.log echo >>$LOGFILE echo "== ================================================== =" >>$LOGFILE echo "$(date +"%d-%b-%Y %R")" >>$LOGFILE echo "Завдання \"$TN\" запущено..." >>$LOGFILE OLD_IFS= $IFS IFS=$"\n" SRCD="/mnt/source/folder_1 /mnt/source/folder_2 /mnt/source/folder_N" TGTD="/var/backups/" TGTD2="/mnt/archive/" tar -czf $TGTD$OF $SRCD &>>$LOGFILE #tar -u -f $TGTD$OF $SRCD &>>$LOGFILE STATUS=$? IFS=$OLD_IFS if [[ $STATUS != 0 ]]; then rm $TGTD$OF &>>$LOGFILE echo "#################################### ######" >>$LOGFILE echo "### Відбулася помилка! ##########################" >>$LOGFILE echo "$(date +"%d-%b-%Y %R%nФайл ") бекапа $OF не створено" | sendxmpp -t -f /usr/local/etc/XMPP_settings логін_отримувача@домен &>>$LOGFILE else echo "Файл бекапу збережено як \"$TGTD$OF\"" >>$LOGFILE echo "Бекап успішно завершено в $(date +"%R %d-%b-%Y")!" >>$LOGFILE echo "Монтування файлової системи для резервного архіву $TGTD_archive" >>$LOGFILE mount $TGTD2 &>>$LOGFILE if [[ $? ! = 0]]; then echo "############################################### ###############" >>$LOGFILE echo "### Відбулася помилка при монтуванні резервного ресурсу ###" >>$LOGFILE echo "########## ################################################## #" >>$LOGFILE echo "$(date +"%d-%b-%Y %R%nФайл") бекапа $OF не скопійовано на резервний ресурс" | sendxmpp -t -f /usr/local/etc/XMPP_settings логін_одержувача@домен &>>$LOGFILE exit fi echo "Почато копіювання файлу на резервний ресурс" >>$LOGFILE cp -f $TGTD$OF $TGTD_archive$OF &>> $LOGFILE if [[ $? ! = 0]]; then echo "############################################### ###############" >>$LOGFILE echo "### Сталася помилка при копіюванні на резервний ресурс ###" >>$LOGFILE echo "######### ################################################## ##" >>$LOGFILE echo "$(date +"%d-%b-%Y %R%nФайл") бекапа $OF не скопійовано на резервний ресурс" | sendxmpp -t -f /usr/local/etc/XMPP_settings логін_отримувача@домен &>>$LOGFILE else echo "Копіювання файлу успішно завершено в $(date +"%R %d-%b-%Y")!" >>$LOGFILE echo "Файл скопійований як \"$TGTD_archive$OF\"" >>$LOGFILE fi echo "Розмонтування файлової системи для резервного архіву $TGTD_archive" >>$LOGFILE umount $TGTD2 &>>$LOGFILE echo "Всі операції завершено успішно!" >>$LOGFILE fi tail -n 300 $LOGFILE >/tmp/unique_fantastic_filename.tmp mv -f /tmp/unique_fantastic_filename.tmp $LOGFILE exit

Всім дякую за увагу!

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

Публікую чергове рішення щодо резервного копіювання веб-сервера. Цей bash скрипт створює єдиний архів бази даних та всіх файлів сайту. Для зручності на диску локально зберігається останні 30 резервних копій. А для надійності архіви резервних копій викладаються на хмарне сховищеЯндекс.Диск.
Подібних рішень повно у мережі. Але цей скрипт найповніше відображає моє бачення резервного копіювання веб-серверів.

Основні засади резервного копіювання

Архіви робимо вбудованими засобами операційної системи, щоб полегшити процес створення архіву та прискорити відновлення сайту на новому сервері за потреби.
Використовуємо формати архіву, які дозволяють зберегти всі атрибути файлів та папок. Щоб отримати точну копіюсайту на новому місці
Окремо архівуємо зі стиском базу даних і директорію веб-сервера з усіма файлами. А потім поєднуємо в єдиний архів уже без стиску. Ім'я архіву для зручності формуємо на підставі імені домену та дати його створення.
Організуємо локальне сховищез 30-ти останніх архівних копій. Щоб була можливість «відкотити» сайт у попередній станна випадок непередбачених ситуацій. Наприклад, при зараженні вірусами. Або невдале оновлення CMS.
Організуємо незалежне сховище резервних копій у хмарному сховищі Яндекс.Диск та викладаємо туди наші архіви.

BASH скрипт резервного копіювання файлів сайту та бази даних MySQL

#!/bin/bash # #ver 1.0 #2013-09-09 # #Змінні Бази даних DBHOST="localhost" #Адреса MySQL сервера DBUSER="bd_user" #Ім'я користувача бази даних DBPASS="dBpAsS" #Пароль користувача бази даних DBNAME="db_name" #Ім'я бази даних DBARC=$DBNAME.sql.gz #Ім'я архіву бази даних # #Змінні WEBDAV WEBDAVURL="https ://webdav.yandex.ru/backup/" #Адреса Яндекс.Диск. Папка має існувати! WEBDAVUSER=" [email protected]# Ім'я користувача від Яндекс.Диска (Яндекс.Пошти) WEBDAVPASS="MyPasWordAtYandexMail" #Пароль від Яндекс.Диска # #Змінні сайту SCRIPTDIR="/home/serveruser/backup/" #Абсолютний шлях звідки запускається скрипт і де зберігатися ="/home/serveruser/web/mydomain.com/public_html/" #Абсолютний шлях до сайту від кореня диска SCREXCLUDE="webstat" #Що не потрапить до архіву SCRARC="public_html.tar.gz" #Ім'я архіву файлів сайту # #Змінні резервні копії ARCNAME="mydomain.com"=$(date "+%F(%H:%M)")".tar" #Ім'я архівної копії сайту ARCMAX="30" #Кількість файлів у локальному сховищі # # Переходимо в кореневу директоріювебсервера cd $SCRDIR # #Створюємо файловий архівзі стисненням, враховуємо винятки tar cfz $SCRIPTDIR$SCRARC --exclude=$SCREXCLUDE * # #Повертаємося до папки зі скриптом, де лежать усі архіви cd $SCRIPTDIR # #Архивуємо базу даних зі стисненням mysqldump -h$DBHOST - p$DBPASS $DBNAME | gzip > $DBARC # #Об'єднуємо файловий архів і дамп бази даних, тепер уже без стиснення tar cf $SCRIPTDIR$ARCNAME $SCRARC $DBARC # #Надсилаємо результат в Яндекс.Диск curl --user $WEBDAVUSER:$WEBDAVPASS -T $ARCNAME $ WEBDAVURL # #Прибираємо проміжні архіви rm *.gz # #Видаляємо старі копії сайту, залишаємо кілька свіжих копій ls -t *.tar | tail -n+$ARCMAX | xargs rm -f

Тепер розберемо скрипт по поличках. Зі змінними вказаними на початку скрипту все зрозуміло. Я постарався максимально відокремити мух від котлет та все необхідне прокоментував.
Перейдемо до виконуваної частини скрипта.

Як створити архів файлів сайту

Зі створенням архіву проблем, як правило, немає. Головне не заплутатися з абсолютними та відносними шляхами. Щоб бути впевненими, що ви архівуєте та де зберігаєте.
Щоб уникнути повних абсолютних шляхівв архіві попередньо перейдемо до кореневої директорії сайту.

Я так не люблю, розкриваєш архів, а там папка home, заходиш у неї, а там ще одна, ти в неї, за нею наступна і так далі, коротше матрьошка. Замучишся до вмісту діставатися.
Тому перед створенням архіву виконаємо команду:

Cd $SCRDIR

Тоді в архіві буде одразу вміст кореневої директорії сайту без жодних папок та підпапок. Приблизно так:


Якщо у Вас є файли, яким не обов'язково бути в резервній копії сайту, маю це папка webstatтоді необхідно налаштувати параметр —exclude.

Докладніше про всі параметри tarможна почитати в офіційному мануалі.

Як створити резервну копію бази даних MySQL

Для отримання дамп бази даних нам знадобляться параметри доступу до неї. Всі вони описані в змінних скриптах і не повинні викликати труднощів. Для зменшення розміру файлу стискаємо висновок утиліти mysqldump. Я використовую gzip, який у *NIX-ах присутній за замовчуванням.
Якщо у Вас використовується стара версія MySQLсервера, до 4.1, то на базах великого обсягу може стати в нагоді параметр -quick. Використання якого вказує команді mysqldumpОдночасно писати дамп бази на диск, а не кешувати його в пам'яті. У більш свіжих версіяхцей параметр увімкнено за замовчуванням.

Єдиний файл резервних копій сайту

Щоб рішення було витонченим, об'єднаємо два архіви файлів сайту та дампа бази даних в один архів. Тільки тепер уже без стиснення, оскільки кожен із них ми їх попередньо пропустили через gzip.
Для зручності ім'я файлу складемо з імені домену і часу створення.

Як зберегти резервну копію сайту в Яндекс.Диск

Як хмарне сховище зовсім не обов'язково має виступати Яндекс.Диск. Ви можете використовувати, наприклад, Microsoft SkyDrive або будь-який інший сервіс, який використовує протокол WebDAV для доступу.

Як прибрати старі копії файлів, зберігши кілька останніх

Наприкінці скрипту приберемо непотрібні файли, це архіви файлів та бази даних та обмежимо кількість архівний копійсайту.
Здійснимо пошук застарілих резервних копій та за наявності таких їх видалимо. За це відповідає наступний код:

Ls-t*.tar | tail -n+$MAXARC | xargs rm -f

Як це працює? За командою lsшукаються архіви (файли з розширенням tar), висновок формується за часом створення файлу. Далі команда tailфільтрує список вирізуючи з нього 30 перших. А залишок передається команді rmвидалення. Параметр fу неї служить для «мовчання» у разі, якщо нема чого видаляти. Таке буває, коли Ви тільки почали збирати резервні копії та їх кількість не перевищує значення змінної $MAXARC.
Щиро кажучи, після виконання цієї команди в «живих» залишиться лише 29 резервних копій.

Запуск скрипту резервного копіювання

Зберігаємо скрипт, наприклад backup.sh. І привласнюємо йому права на виконання:

#chmod +x backup.sh

Найзручніше використовувати CRON для запуску скрипту за розкладом. Я створюю резервні копії раз на добу в години найменшого навантаження, тобто в другій половині ночі під ранок.
Не забуваємо про власників папок та файлів, коли запускатимемо скрипт на виконання. Адже файли користувача VASYA будуть недоступними, якщо запустити скрипт від імені користувача PETYA.

Результати роботи скрипта резервного копіювання


Щодня о 6-й ранку на сервері створюється резервна копія сайту (файли плюс база даних) і відправляється в хмарне сховище Яндекс.Диск.
Під час написання статті як тестовий майданчик виступав реальний сервер, на якому працює цей блог. На сервері використовується CentOS 6.4 з усіма оновленнями на початок вересня 2013 року.
Зауваження та побажання щодо роботи скрипта вітаються. У планах реалізувати обмеження за кількістю резервних копій не лише на сервері, а й у хмарі Яндекс.Диск. Поки що архіви, що накопичилося з часом, доводиться вичищати вручну.