Re: [sqlite] database disk image is malformed

2019-11-12 Thread Jukka Marin
On Mon, Nov 11, 2019 at 05:37:37PM +, Simon Slavin wrote:
> On 11 Nov 2019, at 5:13pm, Jukka Marin  wrote:
> 
> > The main process first opens the databases and checks that their
> > version matches that of the software and if not, the databases are
> > closed and initialized by running a script.
> > 
> > After closing the databases, main process forks the children and
> > all processes (including main process) open the databases and use
> > their own connections.
> > 
> > What I was trying to ask was this:  If any of the children dies
> > (a bug in the code), main process will restart the child.  At
> > this point, the main process has the databases open, so the new
> > child receives the connections as well.  What should I do now?
> 
> Okay, that gives us enough information to work with.
> 
> The conservative way to do it is to have the main process close the 
> connection before forking and open it again.  Then, of course, the child 
> processes make their own connections.
> 
> But I don't think that's necessary.  A child process can have access to the 
> main process' database connection but ignore it.  So I think the main process 
> can fork without closing its connection.  Then each child can never use that 
> one but instead make its own.

Okay, that's what I was hoping for.

> Of course, every one of these connections needs to set a timeout.  And every 
> call to the SQLite3 library needs to check its result code and make sure it 
> is getting SQLITE_OK (or, for queries, SQLITE_DONE etc.).

Yes, I'm doing all this,

> > Should the child close the databases before opening them again?
> > Will this close the databases for the main process as well?
> 
> As you suspected, closing the connection releases both memory structures and 
> file handles.  Anything that tries to use that connection will then fail 
> because it has no idea what it's talking to.

Ok.

> What puzzles me is this: you're getting "database malformed" and nothing 
> you've described justifies this.  Assuming that this isn't just one old 
> database which is genuinely corrupt, but that you are using a fresh uncorrupt 
> database each time, you seem to have a genuine bug in your code.

That was happening before I changed my code to open the databases in
the children.  Originally, only main process opened the databases and
the children "inherited" the connections.  I was wondering if this was
okay, but I didn't see a warning in the SQLite docs, so.. I never found
the "how to corrupt your database" manual on my own ;-)

I came back to the mailing list when I noticed the above "problem" of
a child dying and needing to respawn it while the main process already
has the databases open.

So I guess it's safe now that all the children open the databases by
themselves.

Thanks to all who responded!

  -jm
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] database disk image is malformed

2019-11-11 Thread Jukka Marin
On Mon, Nov 11, 2019 at 05:03:25PM +, Simon Slavin wrote:
> On 11 Nov 2019, at 1:42pm, Jukka Marin  wrote:
> 
> > Or does the main process need to close all databases, then fork, then
> > reopen the databases?
> 
> Which processes access the databases ?  The main process ?  Its children ?  
> Are they all using the same connection ?
>  Are they all trying to use the same connection at the same time ?

All processes access the databases.  No, I changed the code so that
every process opens the databases separately, so they use their own
connections (at random times, so probably simultaneously).

The main process first opens the databases and checks that their
version matches that of the software and if not, the databases are
closed and initialized by running a script.

After closing the databases, main process forks the children and
all processes (including main process) open the databases and use
their own connections.

What I was trying to ask was this:  If any of the children dies
(a bug in the code), main process will restart the child.  At
this point, the main process has the databases open, so the new
child receives the connections as well.  What should I do now?
Should the child close the databases before opening them again?
Will this close the databases for the main process as well?

(One way is to stop using the databases in the main process, so
they are not passed to children, but this would be a major change
in the code.)

  -jm
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] database disk image is malformed

2019-11-11 Thread Jukka Marin
On Fri, Nov 08, 2019 at 09:57:25AM +0200, Jukka Marin wrote:
> On Thu, Nov 07, 2019 at 09:26:46AM -0800, Shawn Wagner wrote:
> > This line stood out:
> > 
> > > The main process opens the databases and then forks the other processes
> > which can then perform database operations using the already opened
> > databases.
> > 
> > From
> > https://sqlite.org/howtocorrupt.html#_carrying_an_open_database_connection_across_a_fork_
> > :
> > 
> > > Do not open an SQLite database connection, then fork(), then try to use
> > that database connection in the child process. All kinds of locking
> > problems will result and you can easily end up with a corrupt database.
> > SQLite is not designed to support that kind of behavior. Any database
> > connection that is used in a child process must be opened in the child
> > process, not inherited from the parent.
> > 
> > In this kind of situation, I usually use pthread_atfork() callbacks to
> > automate closing databases and then re-opening them in the parent and child.
> 
> Okay, thanks!  I suspected it could be something like this, but couldn't
> find anything in the SQLite docs.

In some situations, my main process will have the databases opened before
it needs to fork a new child (this happens only if a child dies and
has to be restarted).  If the child process immediately closes its copies
of the databases and then reopens them, will it be safe?

Or does the main process need to close all databases, then fork, then
reopen the databases?

Thanks again!

  Jukka Marin
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] database disk image is malformed

2019-11-08 Thread Jukka Marin
On Thu, Nov 07, 2019 at 09:26:46AM -0800, Shawn Wagner wrote:
> This line stood out:
> 
> > The main process opens the databases and then forks the other processes
> which can then perform database operations using the already opened
> databases.
> 
> From
> https://sqlite.org/howtocorrupt.html#_carrying_an_open_database_connection_across_a_fork_
> :
> 
> > Do not open an SQLite database connection, then fork(), then try to use
> that database connection in the child process. All kinds of locking
> problems will result and you can easily end up with a corrupt database.
> SQLite is not designed to support that kind of behavior. Any database
> connection that is used in a child process must be opened in the child
> process, not inherited from the parent.
> 
> In this kind of situation, I usually use pthread_atfork() callbacks to
> automate closing databases and then re-opening them in the parent and child.

Okay, thanks!  I suspected it could be something like this, but couldn't
find anything in the SQLite docs.

I'll change my code and see what happens :-)

Thanks again for the quick reply!

  Jukka Marin
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] database disk image is malformed

2019-11-07 Thread Jukka Marin
Dear List,

I'm developing software which keeps parameters and real-time data in
SQLite databases on a x86_64/linux system.  I am getting "database
disk image is malformed" errors from SQLite when using select.  Some
select operations succeed, some fail.  This happens on multiple systems.

I would like to know if I'm doing something that is known not to work
with SQLite.  Background information:

The software runs on a xen virtual machine.  The database files are
on a separate disk (actually, a separate partition of the host linux)
which is directly mounted on the virtual machine (not using NFS)
and uses ext4 filesystem.  The whole system runs off a single SSD disk.

SQLite version is 3.28.0 and it is currently built and statically
linked against the application binary.

The databases are originally created by a script and the sqlite3
command.  "pragma journal_mode=wal;" is set for all databases.

The software consists of multiple processes.  The main process opens
the databases and then forks the other processes which can then perform
database operations using the already opened databases.  No locking is
done in the processes, they rely on the SQLite internal mechanisms.
sqlite3_busy_timeout is set to 2500 for all databases.

The processes mostly read (select) data from the databases, but also
occasionally add new rows or update existing rows.


Is this system with multiple processes accessing the databases
safe with SQLite?  If it is, does anyone have ideas of what could
be corrupting the database files?

These systems are running 24/7, but of course, it _may_ be possible
that someone has disconnected the power supply without shutting down
the system first and causing errors in the database files.

Is there something I could do to (try to) prevent database corruption
if power is lost?  (In software - a UPS is a hardware solution, of
course).

If the database is corrupted, is there any way of recovering it?
Maybe I should use sqlite3 to dump and recreate the database (of
course, some or all of the data might get lost)?

Experienced SQLite users, please share your ideas - thank you! :-)

  Jukka Marin
  (a beginner with SQLite)
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users