Tag: snipe-it

  • La resurrezione di monitoring: come ho salvato i dati da una microSD corrotta

    La resurrezione di monitoring: come ho salvato i dati da una microSD corrotta

    Una mattina di qualche settimana fa, mentre prendevo il caffè, mi accorgo che la dashboard Grafana non risponde. Stessa cosa per la web UI di Observium e per il logger centrale. Tre servizi giù insieme: non è coincidenza, è un host giù. Quell’host, nel mio homelab, è un Raspberry Pi 5 8GB in case dedicato che chiamo “monitoring” (qui lo chiamo rpi-monitoring) e che fa girare diversi servizi:

    Snipe-IT per asset management

    Observium Community come NMS che polla SNMP gli altri host

    InfluxDB v2 come time series database delle metriche

    rsyslog centrale che riceve log dalla LAN

    MariaDB condiviso fra Snipe-IT e Observium

    Tutto girava su una microSD 64 GB classe A1 generica. Dopo circa un anno di servizio la scheda si è bloccata: kernel pieno di mmc0: Card stuck being busy e poi EXT4-fs error a cascata. Ecco come ho recuperato i dati e ricostruito il servizio.

    Perché la microSD è morta

    Una microSD generica entry-level è progettata per fotografia e video: scritture sequenziali grosse, poche cancellazioni. Quello che le ho fatto fare era l’esatto contrario: SQL relazionale di Snipe-IT, polling SNMP Observium ogni cinque minuti su dieci host con scrittura MariaDB + RRD, ingestion InfluxDB v2 di metriche ogni dieci secondi, rsyslog centrale, journald del Pi, log rotation di Apache e nginx.

    Il TBW sopportabile da una microSD entry-level è qualche TB. Con quel carico ci si arriva in 8-12 mesi. Errore mio: non aver migrato a SSD via USB 3.0 prima.

    Step 1: bitwise dump con ddrescue

    La prima cosa che si fa con un dispositivo morente, prima di provare a recuperare file, è un dump bitwise dell’intera scheda. ddrescue è lo strumento giusto: legge sequenzialmente, prova a recuperare i settori illeggibili con strategie successive e mantiene un logfile delle aree da riprovare. Su un Raspberry Pi di servizio con uno slot USB ho infilato la microSD malata tramite un adattatore e ho lanciato:

    
    sudo apt install gddrescue
    sudo ddrescue -d -r 3 /dev/sda /mnt/ssd/monitoring.img /mnt/ssd/monitoring.log
    

    -d salta la cache del kernel e legge in direct I/O, -r 3 riprova ogni settore tre volte. Il dump è andato avanti per quasi cinque ore. Risultato: 62,8 GB su 64 GB recuperati, 1,2 GB irrecuperabili distribuiti soprattutto nell’area dove stavano i datafile MariaDB di un mese. Già un buon punto di partenza.

    Step 2: montare l’immagine read-only

    Con l’immagine in mano, l’ho associata a un loop device read-only per non rischiare di scriverci sopra:

    
    sudo losetup -r -fP /mnt/ssd/monitoring.img
    sudo losetup -a
    

    Il losetup -a mostra il device /dev/loop0 con partizioni loop0p1 (boot) e loop0p2 (rootfs). Ho montato la rootfs:

    
    sudo mkdir -p /mnt/recover
    sudo mount -o ro /dev/loop0p2 /mnt/recover
    

    Filesystem montato pulito, con qualche file segnato come corrotto in dmesg ma navigabile.

    Step 3: estrazione dati per servizio

    Ho copiato selettivamente i datadir dei servizi importanti su un SSD USB di lavoro:

    
    sudo rsync -aH --info=progress2 /mnt/recover/var/lib/mysql /mnt/ssd/recover/
    sudo rsync -aH --info=progress2 /mnt/recover/var/lib/influxdb /mnt/ssd/recover/
    sudo rsync -aH --info=progress2 /mnt/recover/var/lib/observium /mnt/ssd/recover/
    sudo rsync -aH --info=progress2 /mnt/recover/etc /mnt/ssd/recover/
    

    Per MariaDB il datafile più recente era nell’area corrotta. Ho recuperato il mysqldump notturno dal NAS, datato 7 ore prima del crash: perdita accettabile.

    Step 4: ricostruzione su nuovo hardware

    Ho montato un Raspberry Pi 5 8GB nuovo, microSD A2 ad alta affidabilità solo per OS, SSD USB 3.0 da 480 GB per /var/lib/observium, /var/lib/influxdb, /var/lib/mysql e /var/lib/observium/rrd tramite bind mount in fstab:

    
    /mnt/ssd/observium  /var/lib/observium  none  bind  0  0
    /mnt/ssd/influxdb   /var/lib/influxdb   none  bind  0  0
    /mnt/ssd/mysql      /var/lib/mysql      none  bind  0  0
    /mnt/ssd/rrd        /var/lib/observium/rrd  none  bind  0  0
    

    Ripristino del dump SQL, copia dei datadir InfluxDB e Observium dal SSD di recupero, riavvio servizi. Snipe-IT è tornato online con sette ore di asset persi (un paio di check-out ricostruibili a memoria). Observium ha ripreso polling con storia RRD intatta. InfluxDB ha ripreso con un buco di un paio d’ore.

    Un caso reale dentro il caso

    Mentre chiudevo il restore, intorno alle 22:30, ho notato che Observium non discoverava due switch aggiunti la settimana prima. La config era persa nel buco MariaDB? No: avevano cambiato community string dopo una rotazione che mi ero dimenticato di propagare. Credenziali corrette, switch tornati visibili. La documentazione delle credenziali deve vivere fuori dall’host che stai ripristinando, sempre.

    Cosa funziona bene

    ddrescue fa una cosa e la fa benissimo. Il logfile permette di riprovare incrementalmente sui settori illeggibili senza rifare l’intera immagine. Avere backup esterni (mysqldump notturno su NAS, snapshot config di /etc su altra macchina) ha trasformato un disastro potenziale in un fastidio di mezza giornata.

    Limiti

    L’unico vero limite era la microSD stessa: classe A1 generica per workload database-heavy è stato un errore di partenza. Le microSD A2 industrial sono molto più resistenti, ma per workload veri serve SSD via USB 3.0 o M.2 HAT.

    In pratica

    è la storia di scelte hardware sbagliate compensate da una disciplina di backup ragionevole. Oggi configuro SSD via USB 3.0 da subito su qualsiasi Pi che ospiti database o ingestion log, e tengo backup esterni con cadenza coerente con il valore dei dati. Una microSD corrotta non è più un disastro, è una procedura.


    Immagine generata con Cloudflare Workers AI / SDXL Base 1.