Sytuacja z życia wzięta. Poszukiwałem jakiegoś dobrego sposobu, zautomatyzowanego najlepiej do systematycznego wykonywania kopii bezpieczeństwa plików na serwerze, oraz bazy {{MySQL}}. Nic nie znalazłem, więc zacząłem nieco kombinować. W sieci jedyne pomocne rzeczy, jakie znajdywałem to fakt, że:
- najlepiej wykorzystać do tego {{Bash}}’a;
- skoro ↑ to potrzeba też {{CRON}}’a.
Super – pomyślałem. Korzystam z Linuxpl.com, który stoi na serwerze {{Debian}}’owym, mam dostęp do {{CRON}}’a, więc wszystko da się zrobić. No ale, przecież nie znam {{Bash}}’a. Krótkie studiowanie samego języka, parę porad od (nie)znajomych i oto jest, mój pierwszy skrypt napisany w {{Bash}}’u, który zarazem niezmiernie może ułatwić mi życie.
Analiza kodu
#!/bin/bash
AKTUALNY=`date +%F`
WYWAL=`date +%F -d"-XX day"`
Zmienna AKTUALNY wprowadza do skryptu po prostu obecną datę – wykonania skryptu. WYWAL odejmuje od daty wykonania skryptu XX dni.
if [ -e /home/{user}/{katalog}/$WYWAL.7z ]
then
rm /home/{user}/{katalog}/$WYWAL.7z
tar cpvfP /home/{user}/{katalog}/www.tar /home/{user}/
/usr/local/mysql/bin/mysqldump {tabela_bazy} -u{użytkownik} -p{hasło} > /home/{user}/{katalog}/{tabela_bazy}.sql
7z a -mx9 /home/{user}/{katalog}/$AKTUALNY.7z /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql
rm /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql
Jeśli istnieje AKTUALNY – XX dni wtedy, podejmij akcje:
- Usuń plik AKTUALNY – XX dni;
- Stwórz kopię zapasową katalogu /home/ użytkownika, pakując go bez kompresji, z zachowaniem praw dostępu do pliku www.tar;
- Pobierz odpowiednią tabelę bazy danych i zapisz ją;
- Spakuj z maksymalną kompresją plik www.tar oraz kopię tabeli bazy danych do pliku AKTUALNY.7z;
- Usuń pozostawione zbędne pliki, które są w archiwum *.7z.
Jeśli natomiast na serwerze nie ma pliku AKTUALNY-XX dni podejmij te same akcje, ale nie usuwaj czegoś, czego nie ma i tak na serwerze (linia nr 7 ↑).
else
tar cpvfP /home/{user}/{katalog}/www.tar /home/{user}/
/usr/local/mysql/bin/mysqldump {tabela_bazy} -u{użytkownik} -p{hasło} > /home/{user}/{katalog}/{tabela_bazy}.sql
7z a -mx9 /home/{user}/{katalog}/$AKTUALNY.7z /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql
rm /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql
fi
W praktyce
Działanie skryptu jest bardzo proste. Pakuje wybrany przez nas folder do archiwum, następnie pobiera tabelę bazy {{MySQL}}, po czym pakuje obydwa pliki (archiwum i kopia bazy) i usuwa niepotrzebne pliki zostawiając jedno archiwum z kopią.
Ustawienia
W skrypcie (który załączę na końcu wpisu) napisałem, co należy zmienić i mniej więcej co należy posiadać. W razie pytań – komentujcie.
Dla przykładu, ja wykonuję skrypt raz na tydzień, więc nie mogę w polu XX day wpisać 30, ponieważ nie znajdzie mi takiego pliku z racji na fakt, że 7+7+7+7=28, a nie 30. Co daje więc efekt, że skrypt ma usunąć skrypt plik, który w nazwie ma aktualna_data-28dni – jest to jedyne rozwiązanie dla cotygodniowych backupów. Jeśli chcesz robić kopię codziennie, a po tygodniu usuwać stare kopie, to wpisujesz tam 7 – proste 8).
Najważniejsze jednak jest wykonanie prostego polecenia zmieniającego uprawnienia skryptu na wykonanie – bez tego ni rusz:
chmod +x skrypt.sh
Bądź z poziomu klienta {{FTP}} zmieniamy uprawnienia na 711.
Licencja
Skrypt udostępniam na licencji {{GPL}} v. 3. Co oznacza, że możecie z nim robić, co chcecie, ale zachowajcie dane autora ;). Byłbym niezmiernie wdzięczny za wszelakie sugestie rozwojowe, bo ktoś może mieć większy łeb ode mnie i podsunie jakieś pomysły.
Skrypt – pobieranie
Zaznacz wszystko i zapisz pod dowolną nazwą, z rozszerzeniem sh – a z poziomu {{CRON}}’a wpisujesz sh /home/{user}/{katalog}/backup.sh i ma działać. Pamiętaj o uzupełnieniu danych w skrypcie.
#!/bin/bash
# Skrypt wykonujący kopię plików na serwerze oraz wybranej tabeli bazy MySQL na serwerach Uniksowych z dostępem do zadań CRON.
# Autor: Filip (inzaghi89) Cierpich
# URL: http://keepmind.eu
# Mail: filip małpa keepmind dot eu
# Licencja: GPL v. 3
# By skrypt działał poprawnie należy:
# - Zamienić:
# -- XX na ilość dni
# -- {user} na naszą nazwę użytkownika w katalogu /home/ na danym serwerze
# -- {katalog} na folder/katalog, w którym ma być zapisana kopia - katalog MUSI być stworzony ręcznie
# -- {tabela_bazy} na tabelę, którą ma pobrać skrypt
# -- {użytkownik} na nazwę użytkownika, za pośrednictwem której logujemy się do PHPmyAdmin
# -- {hasło} na hasło, za pośrednictwem której logujemy się do PHPmyAdmin
#
# - Posiadać:
# -- Uprawnienia wykonania skryptu na serwerze
# -- Zainstalowaną paczkę p7z-full
# -- Dostęp do zadań CRON na serwerze
# 2010-03-20 modyfikacja skryptu dzięki uwadze JaspEra: http://blog.keepmind.eu/pelny-backup-danych-ze-strony-www-dzieki-cronbash.html#comment-856
AKTUALNY=`date +%F` #odpowiada za nazwę pliku - aktualna data, np. 2010-03-18
WYWAL=`date +%F -d"-XX day"` #odejmuje od aktualnej daty XX dni. Np. 2010-03-18 - 10 = 2010-03-08
if [ -e /home/{user}/{katalog}/$WYWAL.7z ]
then
rm /home/{user}/{katalog}/$WYWAL.7z #jeśli istnieje plik 2010-03-08.7z (czyli aktualna data - xx dni = usuń go)
fi
tar cpvfP /home/{user}/{katalog}/www.tar /home/{user}/ #pakuje katalog /home/{user}/ do pliku www.tar
/usr/local/mysql/bin/mysqldump {tabela_bazy} -u{użytkownik} -p{hasło} > /home/{user}/{katalog}/{tabela_bazy}.sql #pobiera tabelę_bazy, którą zdefiniujemy do pliku tabela_bazy
7z a -mx9 /home/{user}/{katalog}/$AKTUALNY.7z /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql #pakuje z najwyższym stopniem kompresji do formatu 7z - wymagany pakiet p7z-full
rm /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql #usuwa plik www.tar i tabela_bazy.sql, które krok wcześniej spakował
A projekt automysqlbackup http://sourceforge.net/projects/automysqlbackup/ nie byłby lepszy do backupu baz mysql?
Do zrobienia backupu samej bazy SQL – możliwe, ale ja potrzebowałem backup wszystkiego.
A nie byłoby prościej, żeby w między if … fi umieścić kasowanie pliku (jeśli istnieje) a resztę wrzucić poza ten blok, bo i tak jest wykonywana (archiwizacja, mysqldump, kompresja)?
Łatwiej potem, jeśli zajdzie potrzeba zmian modyfikować tylko jeden zestaw poleceń. To nie jest kwestia znajomości/nieznajomości basha, tak po prostu zrobiłbym to w jakimkolwiek „języku”.
JaspEr: masz rację. Serdecznie dziękuję :), biorę się za poprawę zaraz.
Pingback: Backup danych na serwerze
Witam.
Przy uruchomieniu za pomocą crona poniższego pliku ze skryptem jak wyżej:
58 12 * * * root /root/cron_polecenia_skrypt/kompresja_kasowanie_thunderbird.sh
skompresowany plik nie zawiera wszystkich plików.
Po uruchomieniu ręcznie w pisując w terminalu polecenie:
/./root/cron_polecenia_skrypt/kompresja_kasowanie_thunderbird.sh
wszystkie dane są prawidłowo zapisane w piku tar i skompresowane za pocą 7z.
Skrypt mam taki:
chmod -R 700 /arch
chown -R root.root /arch/Backup
Co z tym zrobić?
Czy ktoś sie z tym już spotkał?
W ogóle nie rozumiem Twojego wpisu z cron, dlaczego masz jako wykonanie skryptu sh: root /ściezka/skrypt.sh, a nie po prostu „sudo sh…”, albo „sh”.
Cron dla roota zedytujesz poprzez crontab -e root. Tam dodaj sobie ten skrypt jako zapis:
sh /root/cron_polecenia_skrypt/kompresja_kasowanie_thunderbird.sh
Sam skrypt wydaje się być ok. Poza tym sprawdź syslog, czy jakimiś errorami nie pluje.
Nic to nie daje, niestety.
Szukam rozwiązania co z tym zrobić…
hej,
a da się wykonać polecenie cron z pominięciem danego katalogu?
pzrd
Tak, jest taka możliwość. Odpowiada za to „opcja” –exclude w tar. Przykład
tar cpvfP /backup/home.tar /home/ –exclude /home/katalog
Jak tak stworzoną kopię przywrócić, tzn. zastąpić aktualne pliki wykonaną kopią.
W skrócie jak z tych kopii zrobić backup?
Rzekłbym – od tyłu :).
7z x /home/{user}/{katalog}/$AKTUALNY.7z #Gdzie AKTUALNY do data backupu.
I tutaj polecam np. MidnightCommander żeby wybrać sobie foldery/pliki, które chcesz wypakować i nadpisać z archiwum tar.
By przywrócić bazę MySQL:
/usr/local/mysql/bin/mysql {tabela_bazy} -u{użytkownik} -p{hasło} < /home/{user}/{katalog}/{tabela_bazy}.sql
Proszę o pomoc,
Jak dokładnie powinien wyglądać plik jeśli nie mam możliwości granie 7z i chciałbym pełny backup zapisywać jako tar ? Oraz dodać przykładowo dwie bazy danych do porabia.
P.S. Świetny skrypt :)
Jeśli nie masz możliwości instalacji 7z, to usuń po prostu linijkę z 7z (#33), która odpowiada za pakowanie/kompresję. Polecam jednak czymś sobie to skompresować. Rar, zip, cokolwiek.
W linii 34 znajduje się komenda do zrzutu bazy danych do pliku. Musisz podać login i hasło do bazy danych oraz jej nazwę. Następnie wskazać gdzie plik ma się zapisać.
Macie może pomysł jak zrobić do tego automatyczne kasowanie staszych plików niz 3 dni?
I pytanie numer dwa czy można jakoś zamienić tego tara na gzipa?
AKTUALNY2=”www_`date +%F_%H.%M`”
WYWAL2=www_`date +%F_%H.%M -d”-03 day”`
if [ -e /home/xxx/backup/$WYWAL2.tar ]
then
rm /home/xxx/backup/$WYWAL2.tar
fi
tar -zcvf /home/xxx/backup/”www_`date +%F_%H.%M`”.tar /home/xxx/public_html/
Hej, co do pytań. Masz poprawiony skrypt uwzględniający usuwanie archiwów sprzed 3 dni ;). Dodatkowo atrybut „-z” kompresował archiwum gzipem. Dodałem rozszerzenie tylko.
Dziękuje za poprawiony skrypt.
1. Czy plik spakowany musi tak się kończyć *.tar.gz nie może być po prostu samo *.gz?
2. Jednak kasowanie jak nie działało tak nie działa.
Przykładowe poprzednie nazwy pliku w tym folderze gdzie może kasować i tworzyć pliki to:
www_2018-03-23_09.42.tar
www_2018-03-24_14.22.tar
www_2018-03-25_00.00.tar
www_2018-03-27_08.15.tar.gz (no i ten nowy poprawiony skrypt)
Teraz jeszcze zerknąłem i źle wkleiłem też w poprzednim komentarzu. Nie dodałem .gz do pozostałych nazw plików. I nie, nie musi się nazywać .tar.gz żeby był skompresowany plik. Może być jak najbardziej samo .tar.
Poza tym teraz dopiero zauważyłem, że skoro chcesz usuwać poprzednie dni, robisz kopię codziennie, to bez sensu żeby sprawdzało godziny kopii. Ten skrypt będzie usuwał kopie, które powstały dokładnie 3 dni temu.
Możesz również zrobić to w ten sposób:
Wówczas skrypt usunie wszystkie pliki starsze niż 3 dni.
No no no przyznaje. Ze ten skrypt drugi spełnił moje wymogi w 100% :) Bardzo dziękuje za gotowca