Come testare le condizioni di gara in un database?


30

Provo a scrivere il codice del database per assicurarmi che non sia soggetto alle condizioni di gara, per assicurarmi di aver bloccato le righe o le tabelle corrette. Ma spesso mi chiedo: il mio codice è corretto? È possibile forzare a manifestare eventuali condizioni di gara esistenti? Voglio essere sicuro che se si verificano in un ambiente di produzione la mia applicazione farà la cosa giusta.

In genere so esattamente quale query simultanea può causare un problema, ma non ho idea di come costringerli a correre contemporaneamente per vedere se si verifica il comportamento corretto (ad esempio ho usato il tipo corretto di blocco), che gli errori giusti sono gettato, ecc.

Nota: utilizzo PostgreSQL e Perl, quindi se non è possibile rispondere in modo generico a questa, probabilmente dovrebbe essere ricodificato come tale.

Aggiornamento: lo preferirei se la soluzione fosse programmatica. In questo modo posso scrivere test automatici per assicurarmi che non ci siano regressioni.


Per "condizioni di gara" intendi "deadlock"?
Gaius,

2
@Gaius ... no, anche se credo che sia un possibile risultato di alcune condizioni di gara
xenoterracide

Le condizioni di gara di @Gaius in un database farebbero cose come far cadere una tabella prima che fosse creata o aggiornare una riga prima che fosse inserita. In generale, immagino che sia gestito dalla logica dell'applicazione al di fuori del database stesso.
Segna D il

aggiornare una riga prima che fosse inserita? ciò non causerebbe un problema di db. nessuna condizione di competizione sarebbe come recuperare una riga e aggiornarla, ma fare in modo che un altro utente la aggiorni dopo che la tua riga è stata recuperata ma prima che l'elaborazione sia stata elaborata.
xenoterracide,

1
@MarkD - No. Esistono molti tipi di condizioni di gara derivanti dall'incapsulamento errato di un'unità atomica di lavoro nel database. Ecco un esempio Ricorda, "una condizione di gara o un pericolo di gara è un difetto in un sistema o processo elettronico in base al quale l' output o il risultato del processo dipendono inaspettatamente e criticamente dalla sequenza o dalla tempistica di altri eventi ". ( fonte )
Nick Chammas,

Risposte:


11

Lo faccio sempre con i miei moduli T-SQL.

In sostanza, tutto ciò che devi fare è far funzionare i tuoi moduli da due o più connessioni in un ciclo per un paio di minuti . In genere, tutti i potenziali problemi sono esposti in pochi minuti, supponendo che tu abbia una scatola di SQL Server con CPU decenti.

Ho scritto alcuni esempi qui e qui .


4

Di solito lavoro con lo strumento da riga di comando di RDBMS, avendo appena avviato 2 (o più) istanze della CLI. È quindi possibile riprodurre uno per uno e come una gara (che sembrerebbe un action-RPG) le istruzioni SQL inviate dal livello applicazione. Dovresti sperimentare / sentire i sistemi di blocco in azione poiché la tua CLI "si bloccherà" un po ', aspettando che i blocchi vengano rilasciati dalla CLI degli altri.

Se questo sembra chiaro come fango, non esitare a dirlo ;-)


potresti dare un esempio passo dopo passo? e possono essere scritti test programmatici per fare la stessa cosa?
xenoterracide,

1

Le condizioni di gara richiedono più thread di esecuzione, quindi per testare l'unità dovrai essere in grado di avviare uno o più thread. In Oracle userei DBMS_Scheduler per eseguire un processo per simulare un secondo utente. Se PostgreSQL / Perl ha un modo per avviare programmaticamente un secondo processo, allora dovresti essere in grado di fare qualcosa del genere:

Processo 1 Processo 2

Avviare il processo 2. >>                            
Ritardo per consentire a 2 di fare il suo lavoro. 
. Blocca le righe o modifica i dati.
. Ritardo per consentire a 1 di fare il suo lavoro.
Tentare di bloccare le righe o modificare i dati. .
Verificare che sia stata eseguita la corretta gestione. .
Finisce. .
                                                Finisce.

È bello vedere pensare a come gestire le condizioni di gara e, soprattutto, come testarle.


Non descriverei tali test come test unitari, perché i test unitari devono essere eseguiti esattamente nello stesso modo ogni volta. Le condizioni di gara falliscono i processi coinvolti in modo intermittente, non sempre esattamente allo stesso modo.
AK,

@AlexKuznetsov Hai ragione sul fatto che condizioni di gara impreviste possono mostrare loro se stessi in modo intermittente, tuttavia l'OP si riferisce alle condizioni previste che ritiene che il codice gestisca. Queste condizioni specifiche possono essere riprodotte con precisione e la manipolazione può essere verificata con un test unitario.
Leigh Riffel,

-2

Fintanto che blocchi le file non dovresti arrivare alla condizione di gara poiché ciò di solito è causato quando non è presente alcun blocco.

Ma potresti rimanere bloccato se una domanda blocca la tua domanda per troppo tempo.

Questo è difficile da testare poiché il tempo per le query può cambiare quando il database cresce.

Le query che funzionano correttamente con 100.000 righe di dati di test vengono eliminate dal grafico con 10.000.000 di righe.

Questo tipo di problema può essere molto difficile da trovare in anticipo, ma molti DB hanno un metodo per identificare le query lente.

Usando quel normale, dovresti essere in grado di intrappolare qualsiasi domanda andando in difficoltà con un ampio avviso.

Se ti blocchi da solo, è un'altra storia, ma lì non posso fare a meno.


@darioo lol Ho pensato che forse wn fosse un acronimo di qualcosa ... idk cosa avrebbe significato per "fare il blocco da solo" Se intende non con un ORM, ho controllato il codice che il mio ORM emette sicuramente non fa il blocco a destra. Questo è uno dei motivi per cui mi piacerebbe poter testare potenziali scenari di gara.
xenoterracide,

Sì, intendevo proprio, e normalmente il driver del database gestisce il blocco, la riga, la tabella o eventualmente il campo, ma sto solo aprendo la possibilità che tu usi un DB che non gestisce il blocco;)

.. Sono abbastanza sicuro se ho una transazione con più istruzioni che il mio DB non saprà quali file bloccare automaticamente ... cose del genere select for updatenon esisterebbero se lo facessero ...
xenoterracide
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.