2010-04-08 7 views
6

Sono sicuro che mi manca qualcosa di abbastanza ovvio, ma non posso per la vita di me fermare i miei script pysqlite che si bloccano con un database è un errore bloccato. Ho due script, uno per caricare i dati nel database e uno per leggere i dati, ma entrambi si bloccheranno spesso e istantaneamente a seconda di ciò che l'altro sta facendo con il database in un dato momento. Ho il timeout su entrambi gli script impostato a 30 secondi:Python/SQLite - database bloccato nonostante grandi timeout

cx = sqlite.connect("database.sql", timeout=30.0) 

E credo di poter vedere qualche prova dei timeout in che ottengo quello che sembra essere un timbro di distribuzione (ad esempio 0.12343827e-06 0.1 - e come faccio a smettere di stampare?) scaricata di tanto in tanto nel mezzo della mia schermata di output formattato Maledizioni, ma nessun ritardo che si verifica mai in remoto vicino al timeout di 30 secondi, ma ancora uno degli altri continua a bloccarsi ancora e ancora da questo. Sto eseguendo RHEL su un blade IBM HS21 IBM a 64 bit a 4 bit, e ho sentito parlare di alcuni problemi relativi al multi-threading e non sono sicuro se questo potrebbe essere rilevante. I pacchetti in uso sono sqlite-3.3.6-5 e python-sqlite-1.1.7-1.2.1, e l'aggiornamento a versioni più recenti al di fuori delle disposizioni ufficiali di Red Hat non è una grande opzione per me. Possibile, ma non desiderabile a causa dell'ambiente in generale.

Ho avuto autocommit=1 in precedenza in entrambi gli script, ma da allora ho disabilitato entrambi e ora sono cx.commit() nello script di inserimento e non si commette nello script di selezione. In definitiva, visto che ho sempre uno script che apporta modifiche, non vedo davvero perché questo blocco debba mai accadere. Ho notato che questo è significativamente peggiore nel tempo quando il database è diventato più grande. Recentemente è stato di 13 MB con 3 tabelle di dimensioni uguali, ovvero circa 1 giorno di dati. La creazione di un nuovo file ha migliorato sensibilmente questo aspetto, il che sembra comprensibile, ma alla fine il timeout non sembra essere rispettato.

Qualsiasi suggerimento è molto apprezzato.

EDIT: da quando ho chiesto di essere stato in grado di ristrutturare leggermente il mio codice e utilizzare un segnale per scrivere periodicamente tra 0 e 150 aggiornamenti in una transazione ogni 5 secondi. Ciò ha significativamente ridotto le occorrenze del blocco, a meno di un'ora al contrario di una volta al minuto circa. Immagino di poter andare oltre assicurandomi che i tempi in cui scrivo i dati vengano compensati di qualche secondo mentre leggo i dati nell'altro script, ma fondamentalmente sto lavorando a un problema perché lo cerco, rendendo non necessario un timeout, che non sembra giusto ancora Ta.

risposta

0

SQLite utilizza il blocco del database per ogni scrittura (aggiornamento/inserimento/eliminazione/...). IMHO, questo blocco viene mantenuto fino alla fine della transazione. Questo è un singolo blocco mantenuto attraverso thread/processi, AFAIK.

Quindi, proverei a terminare esplicitamente sia la transazione che la connessione per scrivere lo script e impegnarmi esplicitamente anche nello script di lettura e provare a eseguire il debug dei problemi di concorrenza.

+0

Intendi chiudere l'intero database? Sto bene con una serratura bloccata, ma nessuno script è in attesa per il rilascio del blocco. –

+0

Sì, voglio dire connessione stretta al database dalla connessione che sta facendo scritture. – Almad

+1

Beh, sto scrivendo sul database ogni pochi secondi, sicuramente la chiusura non cambierà davvero nulla? C'è un ulteriore lavoro in apertura e chiusura, quindi non potrebbe peggiorare la situazione? E anche se sto eseguendo i cambiamenti prima di chiudere, non c'è alcun beneficio nel chiuderlo comunque, poiché non sarebbe più bloccato. –

0

SQLite non è semplicemente ottimizzato per carichi di lavoro pesanti, né pretende di essere (ma non importa scrivere molto in una transazione). Mi sembra che tu stia arrivando al punto in cui devi passare a un altro database come MySQL, PostgreSQL, Oracle o DB2. Alcune di queste opzioni sono davvero costose, ma per alcuni carichi di lavoro è quello che ti serve. (Si noti inoltre che i carichi di lavoro di scrittura-pesanti tendono ad essere meglio fatto con una soluzione di server di database dedicato troppo, nonostante il fatto che che spinge in alto i costi di implementazione e la complessità. Alcune cose semplicemente costano.)

+0

Preferirei piuttosto usare un database corretto, ma non è disponibile per vari motivi. –

+0

Bene, quindi sii pronto per alcune cose da rallentare. Semplicemente non può essere aiutato. –

2

Nelle prime versioni di pysqlite , il parametro timeout su sqlite.connect viene interpretato apparentemente come millisecondi. Quindi il tuo timeout=30.0 dovrebbe essere timeout=30000.