#!/bin/bash export myScript=${0##*/} export myPath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #" . /usr/local/bin/init_sets.sh . /usr/local/bin/init_sets_db.sh # hodnoty z sql BATCH_NAME="BACKUP_SEQUENCE" child_batch_name="neomag.backup_sequence" #zalogovani zacatku procesu LOG_START_BATCH run_id=$BATCH_ID ## Spusteni ##Prepocet stav subjektu echo `date "+%Y-%m-%d %H:%M"`---Start backup_sequence >>$logFile LOG_START_BATCH "$child_batch_name" "$run_id" child_run_id=$BATCH_ID sqlplus $CONNECT_USER @$SQLPath/backup_sequence.sql $child_run_id >>$logFile && echo `date "+%Y-%m-%d %H:%M"`---Konec backup_sequence >>$logFile mv $logFile $logDir/backup_sequence_sh_$(date "+%Y-%m-%d_%H:%M").log ##ted zaloguju konec procesu change_count=0; LOG_END_BATCH $run_id 'ok' $change_count exit /-- Skrypt służy do uruchamiania procesu kopii zapasowych sekwencji w bazie danych Oracle (najprawdopodobniej tabel/sekwencji dla aplikacji neomag). Korzysta ze zintegrowanego, bazodanowego systemu logowania zdarzeń (Batch Logging). 🛠️ Główne kroki i logika działania: Inicjalizacja środowiska: Skrypt określa swoją ścieżkę (myPath) i nazwę (myScript). Wczytuje (source) pliki konfiguracyjne /usr/local/bin/init_sets.sh oraz /usr/local/bin/init_sets_db.sh, które dostarczają m.in. procedury logowania (LOG_START_BATCH, LOG_END_BATCH) oraz dane połączeniowe do bazy ($CONNECT_USER, $SQLPath). Rejestracja głównego procesu (Parent Batch): Wywołuje LOG_START_BATCH, co wstawia do bazy informacji o nowym, uruchomionym procesie pod nazwą BACKUP_SEQUENCE. Zwrócony ID procesu zapisuje jako run_id. Rejestracja podprocesu (Child Batch) i wykonanie SQL: Loguje datę startu do pliku tekstowego $logFile. Rejestruje w bazie podproces o nazwie neomag.backup_sequence, powiązany z głównym procesem ($run_id). Pobiera jego child_run_id. Łączy się z bazą przez sqlplus i wykonuje skrypt SQL backup_sequence.sql, przekazując mu ID podprocesu. Używa operatora &&, by w przypadku sukcesu sqlplus zalogować w pliku tekstowym wiadomość "---Konec backup_sequence". Sprzątanie i zakończenie: Przenosi bieżący plik logu do katalogu archiwalnego, dodając do jego nazwy znacznik czasu (data i godzina). Zamyka główny proces logowania batcha w bazie z komunikatem 'ok', wywołując LOG_END_BATCH $run_id 'ok' 0. ⚠️ Krytyczne problemy i rekomendacje (Co należy poprawić?): 1. Zgłaszanie fałszywych sukcesów (Błąd w obsłudze błędów) Linia: sqlplus ... && echo ... Jeśli polecenie sqlplus zakończy się błędem (niezerowy kod wyjścia), skrypt pominie wykonanie polecenia echo "Konec...". Niestety, to wszystko. Skrypt przejdzie płynnie do kolejnych instrukcji, zarchiwizuje log, po czym sztywno wyśle do bazy informację: LOG_END_BATCH $run_id 'ok' $change_count. Skutek: Nawet jeśli backup bazy całkowicie zawiedzie, system monitoringu i logowania (Batch Log) odnotuje ten proces jako udany (ok). Rozwiązanie: Należy dodać sprawdzanie kodu błędu $? po wywołaniu sqlplus i ewentualne logowanie błędu, np.: bash Show full code block if sqlplus $CONNECT_USER @$SQLPath/backup_sequence.sql $child_run_id >> $logFile; then echo "$(date '+%Y-%m-%d %H:%M')---Konec backup_sequence" >> $logFile status='ok' else echo "$(date '+%Y-%m-%d %H:%M')---Blad podczas backup_sequence!" >> $logFile status='error' fi mv $logFile $logDir/backup_sequence_sh_$(date "+%Y-%m-%d_%H:%M").log LOG_END_BATCH $run_id "$status" $change_count (Oczywiście należy pamiętać, że sam plik .sql musi zawierać instrukcję WHENEVER SQLERROR EXIT FAILURE, aby sqlplus zwrócił błąd do Basha). 2. Brak mechanizmu blokady (Ochrona przed współbieżnością) Wczytywany plik init_sets.sh dostarcza funkcję makePID(), która blokuje możliwość dwukrotnego uruchomienia tego samego skryptu w tym samym czasie (np. przez nakładające się zadania w Cronie). Ten skrypt z niej nie korzysta. Rozwiązanie: Dodać wywołanie makePID tuż po załadowaniu zmiennych środowiskowych i upewnić się, że plik blokady zostanie usunięty (removePID) po zakończeniu (najlepiej przez mechanizm trap). 3. Przestarzała i mieszana składnia Skrypt używa archaicznego zapisu z backtickami, czyli `date "+%Y-%m-%d %H:%M"` w poleceniach echo, ale kilkanaście linijek niżej przy komendzie mv używa już prawidłowej, współczesnej składni Bashowej $(date "+%Y-%m-%d_%H:%M"). Rozwiązanie: Dla czytelności i bezpieczeństwa w całym skrypcie powinno się używać wyłącznie notacji $(). Podsumowując, skrypt jest prosty i logicznie ułożony, ale jego brak solidnej obsługi błędów (i ukrywanie ich pod radosnym statusem 'ok') czyni go niebezpiecznym "zapalnikiem" cichych awarii w środowisku produkcyjnym.