[resending, with small clarification edits, since I didn't see it, 
probably because I wasn't yet subscribed, I hope it won't appear twice]

Hello,
I'm using sqlite 3.3.8 under linux (mandriva 2007.1).
Maybe it's something that's not advisable (I don't know) but in my
program I have various threads, each with the same database file opened.
Additionally I have a couple more programs (one guiless and the other
with a gui to view manipulate the database) that also open the same
database file.
The main program has to run unattended 24/7.
A while ago, the visualization program crashed, leaving the database in
an inconsistent state, hence the main program gave sqlite_corrupt problems.
In order to avoid those problems (and probably I did it wrong), each
time I open the database, I issue a "pragma integrity_check". In case it
fails or every time, with the database opened, I detect an
sqlite_corrupt, I try a vacuum (which I saw that fixed the problems if
invoked manually with the command line utility).
This provokes that the other open connections see the SQLITE_SCHEMA
error (and sometimes, stupidly, I try a vacuum again, that exacerbates 
the problem, I'll change that to just retry).
Well, eventually one of the vacuum wiped the database completely clean.
This is what I see in the log of my program(s):

(the uppercase name after [INFO], [ERROR], [AVISO] identifies the thread
and/or the program, in this case "LISTA CARGA" is another program that
is spawned from time to time).

  [INFO]  LISTA CARGA: startup
  [ERROR] LISTA CARGA: PRAGMA integrity_check devuelve error:
  [ERROR] LISTA CARGA: rowid 17653 missing from index fifo_carroceria
  [ERROR] LISTA CARGA: wrong # of entries in index fifo_carroceria
  [ERROR] LISTA CARGA: wrong # of entries in index fifo_referencias
  [ERROR] LISTA CARGA: trying a VACUUM
  [INFO]  LISTA CARGA: VACUUM ok
  [INFO]  LISTA CARGA: terminated

I would like to know why this happened (I don't see any error previous
to this one).
Then this provoked the following cascade of events:



  [ERROR] DESCARGA: sqlite3_step: UPDATE bandejas SET
cantidad=cantidad-1 WHERE numero=4 AND posicion=1 SQLITE_SCHEMA -
database schema has changed
  [ERROR] DESCARGA: Detectado fallo en la base de datos, intento un VACUUM
  [INFO]  DESCARGA: VACUUM ok

this is my fault, I suppose I shouldn't vacuum here, but simply retry,
I'll fix it.


  [ERROR] COMPR.NIVEL CARGA: sqlite3_step: SELECT
modelos.referencia,count(*) FROM fifo_fis LEFT OUTER JOIN modelos ON
fifo_fis.modelo=modelos.modelo and fifo_fis.color=modelos.color GROUP BY
fifo_fis.modelo,fifo_fis.color SQLITE_SCHEMA - database schema has changed
  [INFO]  COMPR.NIVEL CARGA: reintenta 1

ok, the above succeeded by simply retrying.

  [ERROR] COMPR.NIVEL CARGA: sqlite3_step: SELECT sum(cantidad) FROM
bandejas WHERE referencia='W06J3809905  S3H' SQLITE_SCHEMA - database
schema has changed
  [INFO]  COMPR.NIVEL CARGA: reintenta 1

same here


[ERROR] CARGA: sqlite3_step: SELECT ocupacion,cantidad_por_caja FROM
referencias WHERE referencia='W06L6809905G C9Z' SQLITE_SCHEMA - database
schema has changed
[INFO]  CARGA: reintenta 1

and here

Then the real problem ensues:

  [ERROR] COMUNICACION FIS: sqlite3_step: SELECT secuencia FROM fifo_fis
WHERE nr_carroceria='60920850' SQLITE_CORRUPT - database disk image is
malformed
  [ERROR] COMUNICACION FIS: intento un VACUUM
  [INFO]  COMUNICACION FIS: VACUUM ok
  [INFO]  COMUNICACION FIS: reintenta 1
  [ERROR] COMUNICACION FIS: sqlite3_prepare: SELECT secuencia FROM
fifo_fis WHERE nr_carroceria='60920850' SQLITE_ERROR - no such table:
fifo_fiS


at this point the database is clean: there are no tables.

Apart from the glaring errors on my part that I'll try to fix:

1) is sqlite suitable when you have multiple threads accessing the same
database? Or should I delegate the access in a single thread and
serialize the queries from the various threads?
2) is sqlite suitable when you access the database from multiple programs?
3) why did the first error (rowid missing, wrong # of entries) occur?
4) is "VACUUM" the best way to correct such problems?
5) what is the way to recover from "SQLITE_SCHEMA"? close and reopen the
   database?


In case it is useful to spot what I did wrong, this is the procedure I 
use to execute a query (it is pascal, but it should be readable):

function TSQLiteQuery.Execute(query: string): boolean;
var vm:pointer;
     finished:boolean;
     procedure AddRow;
     var i:integer;
         TempRow:TStringList;
     begin
       TempRow:=TStringList.create;
       for i:=0 to sqlite3_column_count(vm)-1 do
         TempRow.Add(StrPas(sqlite3_column_text(vm,i)));
       FRows.Add(TempRow);
     end;
begin
   result:=false;
   finished:=false;
   FRows.Clear;
   if FSQLiteHandle=nil then exit;
   FSQLiteReturnId:=sqlite3_prepare(FSQLiteHandle,PChar(query),-1,@vm,nil);
   if FSQLiteReturnId<>SQLITE_OK then
   begin
     Flog.Error('sqlite3_prepare: '+query+' '+SqliteReturnString);
     exit;
   end;
   repeat
     FSQLiteReturnId:=sqlite3_step(vm);
     case FSQLiteReturnId of
       SQLITE_DONE:
         begin
           result:=true;
           finished:=true;
         end;
       SQLITE_ROW: AddRow;
       else  {SQLITE_ERROR or SQLITE_MISUSE}
         begin
           FSQLiteReturnId:=sqlite3_reset(vm);
           FLog.error('sqlite3_step: '+query+' '+SqliteReturnString);
           finished:=true;
           If FSQLiteReturnId=SQLITE_CORRUPT then
           begin
             FLog.Error('intento un VACUUM');
             if Vacuum then FLog.Info('VACUUM ok');
           end;
         end;
     end;
   until finished;
   sqlite3_finalize(vm);
end;


TIA

Bye
-- 
Luca Olivetti
Wetron Automatización S.A. http://www.wetron.es/
Tel. +34 93 5883004      Fax +34 93 5883007


_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to