6f429244e498457b8400e72e4af683b0 Alberto Blog: Archiver Hung Alert Log Error - No space left on device

martedì 11 ottobre 2011

Archiver Hung Alert Log Error - No space left on device

Questo fine settimana un DB dell'ambiente di produzione si è fermato, con il più classico degli errori: Archiver Hung Alert Log Error, No space left on device.

In effetti lo spazio su disco nel path /arch_oracle/ è finito, bloccando così di fatto la transazione del DB.
Ho lanciato lo script di backup per gli archive, e la situazione è tornata alla normalità.

Dopo questa operazione ho pensato ad un programma che facesse le stesse operazioni mie ma ovviamente in automatico.

L'ambiente è in Solaris quindi il tutto è facilitato:
ksh
MULTI_INSTANCE=0
set +u
USER=$(whoami)
LOGFILE="/tmp/Sitarch"
HOST=$(hostname)
OSTYPE=$(uname)

for i in 1 2 3 4 5 6 7 8 9 10 11 12
 do 
 ARCH=" "
        ARCH="$(df -k  /arch_oracle | awk '{print $4}' | tail -1)$ARCH"
 if [ "$ARCH" -le 10010283  ] ; then
 echo "$ARCH"
 echo " \n$(date) Space /arch_oracle is less of $ARCH, Archive job run, check mail.">> $LOGFILE
 /oracle/bckarch.sh >/dev/null 2>&1
 mailx -s " Space /arch_oracle is less of $ARCH, Archive job run, check mail." alberto@abc.com > $LOGFILE
 fi
 sleep 1710
 done


Con questo script in Korn shell schedulato nel crontab il sistema va a verificare ogni 30 min circa se lo spazio è inferiore ad un certo valore (in questo caso a 10 GB) e va a scriverlo in un file di testo, quando trova la condizione vera ossia che il valore è inferiore fa partire lo script bckarch e manda una mail.

Per esigenze il loop ovviamente cambia se volessimo farlo girare 24 * 7.
In questo caso è attivo per 6 ore.

3 commenti:

Roberto ha detto...

Ciao Alberto, mi permetti di commentare PIGNOLAMENTE il tuo script shell? Sì? Grazie ;-)
Sono un ex UNIX system administrator e gli shell scripts sono stati il mio pane quotidiano per diversi anni e forse qualche dritta posso dartela.

0. Innanzitutto, uno script che fa uso al suo interno di un loop con uno sleep per schedulare ogni mezz'ora è alquanto opinabile. Io configurerei crontab per lanciare lo script negli orari e giorni che desidero.
1. Perché quel ksh nella riga 1?
2. Perché definisci all'inizio delle variabili che poi non usi?
3. Perché invece non definisci all'inizio dello script una variabile FREE_SPACE_KB, con cui specificare quanto spazio residuo ammetti prima di effettuare il cleaning della directory?
4. set +u ignoranza mia cosa fa?
5. Riga 13: la sintassi Ksh prevede le doppie parentesi quadre per i tests (però funziona lo stesso)
6. Riga 14: gli outputs di scripts non interattivi vanno sempre indirizzati verso files (anche lo standard error)
7. L'indentazione ben fatta è importante.
8. Specifica sempre che i comandi rispondono in maniera differente nei vari UNIX/Linux e che perciò il tuo script necessita degli adattamenti del caso: elaborazioni dell'output del tipo "df -k /arch_oracle | awk '{print $4}' | tail -1" è altamente probabile che non producano risultati corretti.
9. Perché nella riga 11 imposti la variabile ARCH a spazio, e poi la concateni con se stessa nella riga successiva?
10. Il messaggio della riga 15 non è corretto, va scritto che lo spazio libero rimanente $ARCH è inferiore 10 GB.
11. Nella riga 15 vai in append in $LOGFILE e nella 17 vai in truncate, perdendoti quanto log-gato precedentemente.
12. Alla riga 16 indirizzi tutto verso /dev/null perdendoti eventuali utili messaggi d'errore. Come ti accorgi per esempio se per un problema (il nome è errato, qualcuno ha cancellato il file, non ha il permesso di esecuzione, ...) non viene lanciato lo script /oracle/bckarch.sh?
13. Infine, e forse è la nota più importante, ogni script di sistema che abbia una certa importanza, deve testare il codice di ritorno ($?) di ogni singolo comando, per esempio anche dopo un semplice "cd" va verificato che $? sia zero.

Altri commenti:
"Con questo script in Korn shell schedulato nel crontab il sistema va a verificare ogni 30 min circa"
- Curiosità mia: perché non mettere esattamente 30 minuti, che sono 1800 secondi?

"se lo spazio è inferiore ad un certo valore (in questo caso a 10 GB)"
- 10010283 KB non sono 10 GB, 10485760 KB sono 10 GB

"e va a scriverlo in un file di testo"
- Perché? Non c'è già il file di log che registra quel valore? Ah no è vero, te lo sei fumato con l'indirizzamento in truncate ;-)

"quando trova la condizione vera ossia che il valore è inferiore fa partire lo script bckarch e manda una mail"
- lo script si chiama bckarch.sh e forse valeva la pena farlo vedere.

Alberto ha detto...

Ciao Roberto, come sai i tuoi commenti sono sempre graditi... ;-)
Rispondo per punti:

0. Si avrei potuto farlo come in altri script ma per questo come per altri ho preferito eseguire un loop.
1. Per impostare la shell in Korn della sessione, visto che viene lanciato nel mio caso da un utente con shell in Bash, tuttavia sarebbe stato meglio creare un utente per eseguire script con la shell selezionata.
2. E' una mia abitudine settare delle variabili che ritengo "standard" anche se dopo ne faccio a meno come in questo caso, visto che non sono importanti.
3. Sì questa sarebbe stata una buona idea settare questa variabile.
4. l set -u farà uscire lo script se si tenta di utilizzare una variabile non inizializzate è equivalente al set-o nounset se non ricordo male, nel caso di +u disabilita questi flags.
6. Sì questa è una buona prassi da seguire.
9. E' una mia abitudine concatenare anche se funziona lo stesso senza.
11.E' un errore di copia e incolla selvaggio nella versione in produzione è in append.
12. Questo è vero nella maggior parte dei casi ma visto che questo server lo gestisco solo io mi sento abbastanza sicuro.
13. Sì, l'output dovrebbe essere sempre verificato in questo script in effetti non lo tengo in considerazione ma in altri sì, anche perchè se ha un output 1 mi faccio sempre mandare un mail di Warning.

...e per il resto mancia...;-)

Roberto ha detto...

0. Certo certo, se cade il processo con il loop, per tutto il giorno la directory non è più monitorata.
1. Se vuoi che uno script venga interpretato da una certa shell non si fa così, così la tua shell di prompt "figlia" un altro processo e al termine dello script non torni alla shell di prompt (tra l'altro ci sono altri effetti collaterali dovuti ai terminali e alle modalità batch/interattiva).
Da che mondo e mondo in ambiente UNIX si usa la direttiva shebang (termine ignoto ai più e anch'io ogni volta che la cito devo fare una verifica in Internet) nella PRIMA RIGA degli scripts, che è un finto commento. Nel tuo caso devi scrivere nella prima riga del tuo script: #!/usr/bin/ksh
Leggiti http://en.wikipedia.org/wiki/Shebang_(Unix)
2. Le cattive abitudini sono quelle a cui siamo più affezionati lo so ;-)
4. Mah, mai sentite queste necessità
9. Questa non è però una cattiva abitudine, è una molto stranissima abitudine
12. Sì, ma stai proponendo uno script al mondo intero
13. Non si chiama "output" si chiama codice di ritorno o return code in English

Posta un commento