Gestire bug non riproducibili


73

Supponiamo che il tuo team scriva un sistema software che (sorprendentemente!) Funziona bene.

Un giorno uno degli ingegneri esegue erroneamente alcune query SQL che modificano alcuni dei dati DB, quindi se ne dimentica.

Dopo qualche tempo scopri i dati corrotti / errati e tutti si grattano la testa su quale parte del codice ha causato questo e perché, inutilmente. Nel frattempo il project manager insiste sul fatto che troviamo la parte del codice che l'ha causato.

come lo gestisci?


32
Se l'ingegnere se ne è dimenticato, come fai a sapere che è quello che è successo? In che modo è stato danneggiato da qualcuno che esegue uno script e non da un bug?
DaveG,

18
Ha avuto un'epifania dopo un giorno o due. Questo è un ipotetico nel caso in cui non si fosse mai ricordato quale avrebbe potuto facilmente essere il caso.
Nik Kyriakides,

12
Questo è un ipotetico. Sono sicuro che il Primo Ministro vorrebbe farci inseguire questo è il più possibile se non lo ricordasse mai. So che lo farei.
Nik Kyriakides,

59
xkcd.com/583 ;) [lingua NSFW]
Baldrickk,

100
"Supponiamo che il tuo team scriva un sistema software che funziona bene." Smettila di prendermi in giro con fantasie impossibili!
Paul D. Waite,

Risposte:


134

È ovvio che nessun project manager investirà una quantità infinita di tempo in un simile problema. Vogliono impedire che si ripeta la stessa situazione.

Per raggiungere questo obiettivo, anche se non si riesce a trovare la causa principale di tale fallimento, è spesso possibile adottare alcune misure

  • Rileva tali guasti in anticipo nel caso in cui si ripresentino
  • Rendi meno probabile lo stesso fallimento accadrà di nuovo
  • Rendere il sistema più robusto rispetto al tipo specifico di incoerenza

Ad esempio, una registrazione più dettagliata, una gestione più accurata degli errori o la segnalazione immediata degli errori potrebbero aiutare a prevenire lo stesso errore o a trovare la causa principale. Se il tuo sistema consente l'aggiunta di trigger di database, forse è possibile aggiungere un trigger che impedisce in primo luogo l'introduzione di incoerenze.

Pensa a quale potrebbe essere il tipo di azione appropriato nella tua situazione e suggeriscilo alla squadra; Sono sicuro che il tuo project manager sarà soddisfatto.

Un giorno uno degli ingegneri esegue erroneamente alcune query SQL che modificano alcuni dei dati DB, quindi se ne dimentica.

Come menzionato da altri, è anche una buona idea vietare tale procedura (se si ha influenza su come funziona il sistema). A nessuno dovrebbe essere consentito eseguire query ad hoc non documentate che modificano il contenuto del database. Se è necessaria una query di questo tipo, accertarsi che esista una politica per archiviare la query insieme alla data di esecuzione, al nome della persona che l'ha eseguita e al motivo per cui è stata utilizzata, in un luogo documentato.


8
@NicholasKyriakides Probabilmente entrambi. Tutte queste sono misure di buon senso per semplificare il debug "differito". Probabilmente sono stati scritti in innumerevoli procedure.
Nic Hartley,

29
Di tanto in tanto capita di avere qualche tipo di problema serio in un sistema di produzione e di non riuscire a determinarne la causa nonostante uno sforzo significativo. Alla fine, lo attribuisci ai raggi cosmici e provi a migliorare la segnalazione (quindi se si ripete, avrai maggiori possibilità di trovare la causa) e mitigazione (quindi se si ripete, il danno sarà minimo) e vedi se ripete.
David Schwartz,

2
@Nicholas Kyriakides: esperienza personale nel corso di diversi decenni.
Doc Brown,

4
Va anche notato che è molto probabile che, anche se ci fosse un bug, potrebbe non essere più lì. Il meglio che a volte puoi fare è correggere i dati e migliorare test / procedure per assicurarti che lo stesso problema non si ripeta.
Kutschkem,

2
La ricerca di problemi intermittenti riguarda la registrazione e la ricerca di un punto di strozzamento in grado di rilevarli quando si verificano, quindi camminare all'indietro da lì per individuare la fonte. A volte richiede cose spiacevoli come i trigger o la distribuzione di codice con registrazione degli errori rumorosa, solo per ottenere un controllo su quando / dove dell'errore.
AaronLS,

51

Questo non è un bug

Almeno non sul tuo codice. È un bug nel tuo processo . Il tuo project manager dovrebbe essere molto più preoccupato per il tuo processo che per il tuo codice.

come lo gestisci?

Molto semplicemente, non permettendo agli ingegneri di modificare i database di produzione o di sviluppo condivisi .


Supponendo che questo sia un database di sviluppo condiviso:

Idealmente, se possibile, evita innanzitutto di avere un database condiviso . Invece, hanno database per sviluppatori di breve durata. Questo dovrebbe essere automatizzato con gli script, altrimenti il ​​costo per testare diventa troppo grande e c'è un incentivo a non testare le cose. È possibile disporre di questi database sulla workstation dello sviluppatore o su un server centrale.

Se, per qualche motivo, DEVI assolutamente avere un database condiviso, dovresti usare gli infissi - in sostanza, qualcosa che imposta il database su uno stato buono ogni volta che devi usarlo. Questo evita che gli sviluppatori vengano morsi dai cambiamenti degli altri.

Se è necessario applicare modifiche permanenti al database, è necessario impegnarle nel controllo del codice sorgente . Configura il tuo database in modo tale che gli sviluppatori non dispongano dell'autorizzazione per scrivere direttamente su di esso e dispongano di un programma che estrae le modifiche dal controllo del codice sorgente e le applica.

Infine, dalla tua descrizione su come stai eseguendo il debug delle cose, sembra che non stai usando CI . Usa CI . È un po 'una seccatura da configurare, ma farà risparmiare molto tempo a lungo termine, per non parlare del fatto che ti impedisce di preoccuparti di bug di database non riproducibili. Adesso dovrai solo preoccuparti degli heisenbugs !


Supponendo che questo sia un database di produzione:

Se i tuoi sviluppatori stanno cambiando i database di produzione, molte cose sono andate terribilmente storto, anche se le modifiche sono assolutamente corrette.

Gli sviluppatori non dovrebbero mai accedere ai database di produzione . Non c'è assolutamente alcun motivo per farlo, e così tante cose che possono andare molto molto male.

Se è necessario correggere qualcosa in un database di produzione, eseguire prima il backup, ripristinare quel backup su un'istanza diversa (sviluppo) e quindi giocare attorno a quel database di sviluppo. Una volta che pensi di avere una correzione pronta (sul controllo del codice sorgente!), Esegui nuovamente il ripristino, applica la correzione e vedi il risultato. Quindi, dopo aver eseguito nuovamente il backup delle cose (e idealmente impedire gli aggiornamenti simultanei), si corregge l'istanza di produzione, idealmente tramite una patch software.

Se devi testare qualcosa in un database di produzione ... no, non lo fai. Qualunque test tu debba fare, dovresti farlo in un'istanza di sviluppo. Se hai bisogno di alcuni dati per fare i test, li ottieni lì.


12
Quindi, la tua soluzione consigliata è viaggiare nel tempo?
Benubird,

7
Sebbene questa sia una soluzione decente per l'esempio dato, la domanda ha un contesto molto più generale di gestione dei bug che non possono essere riprodotti e dei manager che vogliono che li perseguitino. Ciò può applicarsi a molto più che semplici problemi di database e gestione delle autorizzazioni. Sento che questa risposta in realtà non risponde alla domanda prevista, solo nell'esempio dato.
Kyle Wardle,

@KyleWardle concordato. Penso che la risposta di Doc Brown copra abbastanza bene il caso generale (registrazione dettagliata e gestione degli errori, condizioni di guardia). Ho principalmente aggiunto il mio perché ho visto che nessuno aveva menzionato i fallimenti del processo che hanno portato al problema in primo luogo
goncalopp,

2
@Benubird Penso che la risposta si riduce a "il modo in cui affronti questo sta impedendo che accada di nuovo". Non penso che tu possa "risolvere" un database di produzione corrotto dal punto di vista dell'ingegneria del software.
goncalopp,

1
Non modificherai il codice per inserire i dati nel database di sviluppo. Ovunque abbia lavorato, comprese grandi aziende, gli sviluppatori sono liberi di inserire dati di test e utilizzare le stesse credenziali utilizzate dall'applicazione.
David Conrad,

13

Un database di produzione dovrebbe avere la registrazione dell'accesso completo e controlli di accesso basati sui ruoli. Quindi dovresti avere prove concrete su CHI ha fatto COSA QUANDO nel database spostando così l'attenzione dal codice alla scarsa sicurezza operativa.


2
Sembra che potrebbero non sapere esattamente quando si è verificata la corruzione dei dati, il che potrebbe rendere difficile capire quali log debbano investigare.
Nathanael,

3
Sfortunatamente, tracciando uno di questi abbiamo scoperto che stava distruggendo anche i registri. (Sì. Il bug era reale.)
Giosuè,

La registrazione della coppia con i lavori pianificati che verificano l'integrità dei dati, anche se solo durante la notte, significa che i problemi possono essere segnalati in anticipo e risolti. Se vuoi stare molto attento, richiedi una revisione tra pari per le modifiche.
Keith,

Ovunque abbia lavorato, gli sviluppatori si connettono al database con le stesse credenziali utilizzate dall'app, quindi la registrazione degli accessi mostrerà solo quando quell'ID ha apportato la modifica, non che sia stato fatto da un umano piuttosto che da un programma. Suppongo che potresti confrontare il timestamp con i registri dell'applicazione per vedere se l'applicazione stava facendo qualcosa che avrebbe scritto sul database in quel momento.
David Conrad,

@DavidConrad: Perché gli sviluppatori hanno accesso alle credenziali utilizzate dall'app in produzione? È necessario utilizzare una sorta di gestione segreta in modo che tali credenziali non possano nemmeno essere lette se non dall'account del servizio dell'applicazione, dai server delle applicazioni di produzione.
Daniel Pryden,

6

In questo caso, alla fine hai capito la causa, ma prendendo il tuo ipotetico che non hai ...

Innanzitutto, analizza cosa è cambiato. Se il sistema funzionava bene prima, uno sguardo attento a tutto ciò che è stato fatto di recente potrebbe rivelare la modifica che ha causato il bug. Rivedere sistematicamente il controllo della versione, i sistemi di installazione continua / distribuzione e controllo della configurazione per vedere se qualcosa è cambiato. Esegui git bisect o un meccanismo equivalente per eseguire una ricerca binaria. Controlla i registri. Cerca i tronchi che non sapevi di avere. Parla con chiunque abbia accesso al sistema per vedere se ha fatto qualcosa di recente. Per il tuo problema, se sei abbastanza approfondito in questo processo, si spera che questo possa rivelare le query SQL dimenticate.

Secondo, strumentazione. Se non riesci a trovare direttamente la causa di un bug, aggiungi la strumentazione attorno per raccogliere dati sul problema. Chiediti "se potessi riprodurre questo bug a comando, cosa vorrei guardare nel debugger" e poi registralo. Ripeti se necessario fino a quando non avrai una migliore comprensione del problema. Come suggerisce Doc Brown, aggiungere la registrazione per gli stati rilevanti per il bug. Aggiungi asserzioni che rilevano dati corrotti. Ad esempio, se il bug è un arresto anomalo dell'applicazione, aggiungere un meccanismo di registrazione degli arresti anomali. Se ne hai già uno, ottimo, aggiungi annotazioni ai registri degli arresti anomali per registrare lo stato potenzialmente rilevante per l'incidente. Valuta se possono essere coinvolti problemi di concorrenza e testa per esercitare la sicurezza dei thread .

Terzo, resilienza. I bug sono inevitabili, quindi chiediti come puoi migliorare i tuoi sistemi per essere più resiliente in modo che il recupero dal bug sia più semplice. I tuoi backup potrebbero essere migliorati (o esistenti)? Migliore monitoraggio, failover e avvisi? Più ridondanza? Migliore gestione degli errori? Disaccoppiare i servizi dipendenti l'uno dall'altro? Puoi migliorare i tuoi processi relativi all'accesso al database e alle query manuali? Nel migliore dei casi, queste cose renderanno le conseguenze del tuo bug meno gravi e, nel peggiore dei casi, sono probabilmente buone cose da fare comunque.


5
  1. Spiega al tuo project manager che ritieni che la causa più probabile sia l'accesso manuale al database.
  2. Se vogliono ancora che tu cerchi il codice che ha causato questo, vai a dare un'altra occhiata al codice.
  3. Torna tra un paio d'ore (o qualche altro momento appropriato) e dì che non riesci a trovare alcun codice che avrebbe causato questo, quindi credi ancora che la causa più probabile sia l'accesso manuale al database.
  4. Se vogliono ancora che tu cerchi il codice, chiedi quanto tempo vorrebbero che tu dedicassi a questo. Ricorda sottilmente che non lavorerai sulla funzione X, sul bug Y o sul miglioramento Z mentre lo stai facendo.
  5. Trascorrere tutto il tempo che chiedono. Se pensi ancora che la causa più probabile sia l'accesso manuale al database, diglielo.
  6. Se vogliono ancora che tu cerchi il codice, intensifica il problema in quanto questo è chiaramente diventato un uso improduttivo del tempo della tua squadra.

È inoltre possibile considerare se è necessario aggiungere ulteriori processi per ridurre la probabilità di accesso manuale al database che causa questo tipo di problema in futuro.


1
Non avevo idea che uno degli ingegneri facesse un aggiornamento manuale + gli ingegneri non eseguivano quasi mai query direttamente sul database. Questo ha appena fatto, come una cosa una tantum e se ne è dimenticato. Abbiamo trascorso un giorno + preparandoci a trascorrere un'intera settimana a scoprire cosa non va. La mia domanda è cosa succede se non riesci a trovare la causa e non puoi suggerire quale potrebbe essere la causa potenziale.
Nik Kyriakides,

5
"La mia domanda è cosa succede se non riesci a trovare la causa e non puoi suggerire quale potrebbe essere la causa potenziale" Questo è il motivo esatto per cui è stato inventato il flag "non risolto - impossibile duplicare".
esoterik,

4

Stavo lavorando nel team di sviluppo per un prodotto di database mainframe quando un cliente ha riferito di avere un database corrotto. Un danneggiamento nel senso che lo stato interno dei bit sul disco significava che il database non era leggibile tramite il software del database. Nel mondo dei mainframe i clienti ti pagano milioni di dollari e devi prenderli sul serio. Questo è ciò che abbiamo fatto:

Passaggio 0: aiutare il cliente a rimettersi in funzione riparando il database.

Step 1: esaminando il file su disco a livello esadecimale abbiamo stabilito che la corruzione era sistematica: c'erano molti casi della stessa corruzione. Quindi è stato sicuramente causato a livello del software del database. In effetti, era sufficientemente sistematico che ritenevamo di poter escludere problemi multi-threading.

Dopo aver eliminato molte altre teorie ci siamo concentrati su un'utilità che potrebbe essere utilizzata per la riorganizzazione fisica del database. Sembrava essere l'unico codice che aveva accesso ai dati al giusto livello. Abbiamo quindi scoperto un modo di eseguire questa utility, con opzioni accuratamente selezionate, che riproduceva il problema. Il cliente non è stato in grado di confermare o negare che questo è ciò che avevano fatto, ma poiché era l'unica spiegazione che avremmo potuto trovare, abbiamo deciso che era la causa probabile e non avevano altra scelta che accettare la nostra diagnosi .

Passaggio 2: Abbiamo quindi apportato due modifiche al software: (a) ha reso più difficile causare questo effetto accidentalmente attraverso un'interfaccia utente "sì, so cosa sto facendo" e (b) introducendo un nuovo file di registro in modo che se è mai successo di nuovo, avremmo un registro delle azioni dell'utente.

Quindi sostanzialmente (a) ripara il danno e ripristina la corsa dal vivo, (b) trova la causa principale, (c) fai tutto il necessario per prevenirlo, o per consentire una facile diagnosi se si ripete.


3

Dalla mia esperienza, ciò che il tuo capo vuole è una certa garanzia che ciò non si ripeterà. Se è il caso che nessun codice fosse la causa, perché ciò è garantito dai test di unità, quindi supponendo che tu abbia già una copertura di test sulla tua base di codice, la soluzione dovrebbe aggiungere "test" al tuo database. Citerò Don Gilman, perché ha inchiodato lì:

Un database di produzione dovrebbe avere la registrazione dell'accesso completo e controlli di accesso basati sui ruoli. Quindi dovresti avere prove concrete su CHI ha fatto COSA QUANDO nel database spostando così l'attenzione dal codice alla scarsa sicurezza operativa.

Inoltre, è necessario disporre di una procedura operativa standard per la modifica dei dati in produzione. Ad esempio, nessun DBA dovrebbe modificare i dati, nessuno sviluppatore dovrebbe eseguire autonomamente la modifica e dovrebbero, come definito nello SOP, richiedere reciprocamente formalmente la modifica tramite posta o ticket.

Ci deve essere una citazione come questa da qualche parte, se non puoi citarmi su di essa:

C'è una ragione perfettamente valida per i cuochi che non sono i responsabili della pulizia dei servizi igienici.


1

Esistono diverse cose che devono essere fatte con bug non riproducibili.

  1. Crea un biglietto per questo

Crea un biglietto e registra tutto ciò che ti viene in mente nel biglietto. Controlla anche se questo "bug" è già stato registrato e collega i biglietti insieme. Alla fine potresti ottenere abbastanza biglietti per stabilire uno schema su come riprodurre il bug. Ciò include soluzioni alternative utilizzate per provare a evitarlo. Anche se questa è l'unica istanza, se c'è una prima volta, alla fine ci sarà una seconda volta. Quando trovi la causa, chiudi il biglietto con una spiegazione di quale sia stata la causa in modo da avere una forte idea di cosa è successo se si verifica di nuovo (correzione persa in unione errata)

  1. Fai un'analisi di indurimento

Guarda il sistema, cosa non ha funzionato e come è fallito. Prova a trovare aree del codice che possono essere aggiornate per rendere meno probabile l'errore. Qualche esempio...

  • Sostituisci il codice ad-hoc con una chiamata dedicata (come execute(<query>)conexecuteMyStoredProcedure(<params>)
  • Esegui script di verifica notturni per verificare l'integrità dei dati (in modo che possano essere rilevati entro 24 ore la prossima volta)
  • Aggiungi / migliora la registrazione e l'archiviazione (backup).
  • Modifica limiti di sicurezza impropri (ad esempio, le persone / i programmi che leggono solo i dati non dispongono dell'autorizzazione di scrittura; non consentire agli sviluppatori che non sono responsabili della produzione di accedere ai server di produzione)
  • Aggiungi verifica dei dati / servizi igienico-sanitari se mancanti

Questo potrebbe non correggere il bug, ma anche se non lo fa, il sistema è ora più stabile / sicuro, quindi paga comunque.

  1. Aggiungi avvisi di sistema

Un po 'parte del 2, ma è successo qualcosa e devi sapere quando succede di nuovo. Dovresti creare alcuni script / programmi di controllo dello stato per monitorare il sistema, in modo che gli amministratori possano essere avvisati entro 24 ore dalla ricomparsa del bug (minore è il ritardo, meglio è, entro limiti ragionevoli). Ciò renderà la pulizia molto più semplice. (Si noti che oltre ai registri dei database, il sistema operativo dovrebbe anche registrare chi accede a esso e tutte le azioni non lette che eseguono. Come minimo, ci dovrebbero essere registri di rete del traffico verso quella macchina)


0

Il tuo problema non è stato causato da un errore nel tuo software, ma da qualcuno che armeggiava con il database. Se chiamate cose che vanno male come "bug", allora il vostro bug è facilmente riproducibile: le cose andranno sempre male quando qualcuno fa cose stupide nel database. E ci sono modi per evitare questo "bug", non consentendo la modifica manuale del database o l'utilizzo di software non testato e controllando rigorosamente chi può modificare il database.

Se chiami "errori" solo nel tuo database i guasti, allora non hai un bug irreversibile, non hai alcun bug. Potresti avere una segnalazione di bug, ma hai anche prove che il problema non è stato causato da un bug. Quindi puoi chiudere la segnalazione dei bug, non come "irreproducibile", ma qualcos'altro come "database danneggiato". Non è raro avere segnalazioni di bug in cui le indagini dimostrano che non esiste alcun bug, ma un utente ha utilizzato il software in modo errato, le aspettative dell'utente erano sbagliate ecc.

In quel caso sai ancora che c'era un problema che non vuoi ripetere, quindi fai la stessa azione del primo caso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.