PDA

Visualizza la versione completa : [FIREBIRD] Migrazione da database SQLite e uso delle transazioni


denis76
11-08-2009, 16:57
Salve a tutti. Sto avendo notevoli problemi con sqlite, il file del database infatti mi si corrompe spesso.
Sto valutando di passare a Firebird. Qualcuno ha esperienza in materia? Firebird è potente tanto quanto Sqlite? Di più?

alka
11-08-2009, 20:58
Originariamente inviato da denis76
Salve a tutti. Sto avendo notevoli problemi con sqlite, il file del database infatti mi si corrompe spesso.
Sto valutando di passare a Firebird. Qualcuno ha esperienza in materia? Firebird è potente tanto quanto Sqlite? Di più?
Sai che domande di questo tipo sono vaghe. Che significa potente?

Ogni database ha le proprie caratteristiche peculiari, per cui la "potenza" è data dall'equilibrio del prodotto rispetto alle proprie esigenze particolari.

Almeno indica cosa utilizzi genericamente di SQLite (per quanto il fatto che venga utilizzato in molti software, anche commerciali, e in maniera abbastanza estensiva, mi fa un po' dubitare del fatto che i problemi possano essere - in senso assoluto - derivanti da un'instabilità così elevata e specifica del database).

Ciao! :ciauz:

denis76
11-08-2009, 21:41
Hai ragione. Spiego meglio cosa voglio sapere.

- Ho bisogno di sapere se può essere usato in modo embedded.
- Se ammette le transazioni.
- Se il database è costituito da un unico file oppure se crea un file per ogni tabella.
- Se ammette accessi concorrenti (in modo embedded).
- Ultimo ma più importante: Se chi lo sta usando ritiene che sia un ottimo prodotto.


Tutto ciò nasce dal fatto che ho parecchi casi di database corrotto (sqlite) senza motivo apparente. Semplicemente ad un certo punto (random) accade che il database restituisce vero ad una eventuale insert mentre in verità il nuovo record non c'è e se si cerca di aprire il database con un qualsiasi programma si ottiene l'output "disk image malformed" o simili.

standard
11-08-2009, 23:21
premettendo la mia completa ignoranza su SQLite, mi sono un po' documentato ed ho "scoperto" che è ServerLess, caratteristica che non mi è mai capitato di incontrare nelle mie esperienze.
Interessante.

comunque dalla documentazione (http://www.sqlite.org/different.html) riporto questo:


On the other hand, a database engine that uses a server can provide better protection from bugs in the client application - stray pointers in a client cannot corrupt memory on the server.
che non significa niente nello specifico del tuo caso, ma riprendendo quanto suggerito da alka, probabilmente l'instabilità non è dovuta tanto al prodotto, ma alle condizioni e al software che vi girano intorno (soprattutto in questo caso).
conscio dell'inutilità dell'intervento,
saluto

standard
11-08-2009, 23:33
questo è un pizzico più utile: http://www.sqlite.org/faq.html#q21
ciao

alka
12-08-2009, 10:17
Originariamente inviato da denis76
- Ho bisogno di sapere se può essere usato in modo embedded.

Sì. E' disponibile nelle versioni Super Server ed Embedded.


Originariamente inviato da denis76
- Se ammette le transazioni.

Sì, le transazioni sono pienamente supportate.


Originariamente inviato da denis76
- Se il database è costituito da un unico file oppure se crea un file per ogni tabella.

Principalmente, il database è costituito da un unico file, ma ci possono essere casi particolari (ad esempio, per copie shadow o altre casistiche) in cui è possibile suddividerlo.


Originariamente inviato da denis76
- Se ammette accessi concorrenti (in modo embedded).

In modo embedded, nessun database dovrebbe permettere accessi concorrenti, poiché questo fa cadere l'utilità di usare il server embedded al posto di una normale architettura client/server. FireBird non lo consente, poiché il file viene "bloccato" - così come accade nel caso client/server, dal database server.


Originariamente inviato da denis76
- Ultimo ma più importante: Se chi lo sta usando ritiene che sia un ottimo prodotto.

La risposta a questa domanda è retorica: se chi lo sta usando non lo ritenesse un ottimo prodotto, passerebbe ad altro. :)


Originariamente inviato da denis76
Tutto ciò nasce dal fatto che ho parecchi casi di database corrotto (sqlite) senza motivo apparente. Semplicemente ad un certo punto (random) accade che il database restituisce vero ad una eventuale insert mentre in verità il nuovo record non c'è e se si cerca di aprire il database con un qualsiasi programma si ottiene l'output "disk image malformed" o simili.
Come dicevo nel messaggio precedente, io mi accerterei che non si tratti di un problema legato ad un uso improprio del database, in linea di principio.

Il motivo è semplice: se lo stesso "errore" lo si commette anche nel nuovo database a cui si è passati, il problema si ripeterà, con la differenza che invece di impiegare il tempo a individuare causa e adottare una soluzione, questo verrà perso in una inutile migrazione.

Detto questo, ritengo personalmente che FireBird sia decisamente un ottimo prodotto.

Tutte le informazioni, comunque, le trovi sul sito ufficiale (http://www.firebirdsql.org).

Ciao! :ciauz:

denis76
12-08-2009, 16:01
Il programma è multithread.
Nel caso si debba inserire o modificare i dati uso le transazioni in modo da impedire agli altri thread di accedere al database. Nel caso invece di estrazione dei dati può capitare che il database venga interrogato contemporaneamente da più threads.
Credo che sia questa la situazione che in qualche modo danneggia il database. Credo cioè che sqlite in ambiente multithread non sia molto valido.
E' da molto tempo che indago la cosa alla ricerca di un eventuale bug ma, posso garantire, leggendo i log semplicemente si vede che a volte il database si danneggia senza motivo apparente. Il programma non va mai in crash e non restituisce errori. Semplicemente restituisce vero inserendo un ennesino record, dopodiché il programma verifica se il record c'è davvero ma non lo trova.
Ho inserito addirittura alcune funzioni che, qualora il database sia danneggiato, permetta al programma di scrive i dati in un file di testo al fine che continui a funzionare.
Speravo che qualcuno avesse usato firebird in modalità multithread e che mi garantisse che funziona perfettamente.

alka
12-08-2009, 16:19
Originariamente inviato da denis76
Il programma è multithread.

Multithread è una cosa, gli accessi concorrenti sono un'altra.


Originariamente inviato da denis76
Nel caso si debba inserire o modificare i dati uso le transazioni in modo da impedire agli altri thread di accedere al database.
Questo tipo di controllo lo si effettua proteggendo la risorsa attraverso i meccanismi di sincronizzazione multithreading, cioè critical section, mutex, semafori, ecc.

Le transazioni non hanno a che vedere con questo contesto.


Originariamente inviato da denis76
Nel caso invece di estrazione dei dati può capitare che il database venga interrogato contemporaneamente da più threads.

In tal caso, è necessario che ogni thread abbia una propria connessione al database; altrimenti, se si utilizza la stessa connessione fisica, occorre sincronizzare l'accesso (ciò significa che non tutti i thread possono utilizzare lo stesso oggetto che rappresenta la connessione contemporaneamente, ma l'accesso a quest'ultimo deve essere "protetto").


Originariamente inviato da denis76
Credo che sia questa la situazione che in qualche modo danneggia il database. Credo cioè che sqlite in ambiente multithread non sia molto valido.

Probabilmente, gli oggetti delle librerie che accedono a questo database non sono thread-safe. Ma questo non è un difetto, bensì una caratteristica.
Anche la stessa libreria VCL è prevalentemente NON thread-safe, ma questo non significa che NON sia "valida". Si tratta di utilizzare gli strumenti nel contesto per il quale sono stati progettati.


Originariamente inviato da denis76
E' da molto tempo che indago la cosa alla ricerca di un eventuale bug ma, posso garantire, leggendo i log semplicemente si vede che a volte il database si danneggia senza motivo apparente.
Direi che il motivo lo abbiamo trovato. :)


Originariamente inviato da denis76
Il programma non va mai in crash e non restituisce errori. Semplicemente restituisce vero inserendo un ennesino record, dopodiché il programma verifica se il record c'è davvero ma non lo trova.
Questo perché è probabile che quel valore di ritorno sia l'esito dell'operazione effettuata da un altro thread, e che viene restituita quando le operazioni del thread secondario vengono "interrotte" dal sistema operativo per passare al primo.


Originariamente inviato da denis76
Speravo che qualcuno avesse usato firebird in modalità multithread e che mi garantisse che funziona perfettamente.
Posso garantire che funziona perfettamente, ma non posso di certo garantire che la libreria non produca effetti indesiderati o errori se viene utilizzata in un contesto che non è supportato all'interno.

Come dicevo sopra, sincronizza l'accesso al database utilizzando gli oggetti comunemente adottati a questo scopo (e che in Delphi - se è questo il linguaggio che usi - sono disponibili, con classi specifiche o attraverso le API di Windows).

Ciao! :ciauz:

denis76
12-08-2009, 16:58
Anche la stessa libreria VCL è prevalentemente NON thread-safe, ma questo non significa che NON sia "valida".
Non uso componenti vcl ma fpc su Linux.


è necessario che ogni thread abbia una propria connessione al database
Certamente.


Questo tipo di controllo lo si effettua proteggendo la risorsa attraverso i meccanismi di sincronizzazione multithreading, cioè critical section, mutex, semafori, ecc.
La transazione mi permette di effettuare un lock sulla tabella impedendo a chiunque di modificarla fintantoché non la libero.
Nel sito si legge che sqlite è thread-safe. A tal proposito ho fatto alune prove testando l'accesso di più threads in lettura e scrittura. Non ho avuto problemi di acun genere. Ogni thread, attendendo che la tabella si liberi, ha poi concluso il suo lavoro correttamente. Da dire che le prove le ho fatte usando 16 threads contemporaneamente mentre normalmente il programma ne usa solo 3.
Inserire però delle critical section a questo punto, tanto per togliersi ogni dubbio potrebbe essere una buona cosa. Il mio sospetto è che in verità rimanga qualcosa nella cache del disco gestita dal kernel anche se la transazione è terminata ed il commit è stato dato. Leggo che firebird ha un apposito parametro configurabile per regolare questa cosa.

C'è da dire che il sistema operativo ed il database sono un supporto solido (disk on module) e non su un disco normale. Forse la cosa complica le condizioni di lavoro. Il sistema operativo ed il programma però non si fermano mai e non mi si è mai corrotto il filesystem.
L'archivio sqlite va aumentando anche se i record vengono cancellati per cui non credo che il file venga scritto sempre sui soliti punti del disco degradandolo.

alka
12-08-2009, 17:26
Originariamente inviato da denis76
La transazione mi permette di effettuare un lock sulla tabella impedendo a chiunque di modificarla fintantoché non la libero.

Ok, però questo è il modo più limitativo di usare le transazioni. :(


Originariamente inviato da denis76
Nel sito si legge che sqlite è thread-safe.
Potrebbero non esserlo i componenti che usi per accedervi.
O potrebbe esserci un'altra causa...


Originariamente inviato da denis76
C'è da dire che il sistema operativo ed il database sono un supporto solido (disk on module) e non su un disco normale.
Questo potrebbe essere un problema: so che determinati volumi lavorano con la scrittura tramite cache, e non è sempre garantita se c'è una disconnessione della periferica.

Io indagherei in questo frangente, perché potrebbe essere l'origine del problema (visto che la corruzione di un file di dati è una condizione molto particolare).

Magari verifica se lo stesso problema avviene anche con un disco "normale".

Ciao! :ciauz:

Loading