Re: [sqlite] Handling move/rename of an SQLite database file

2013-11-09 Thread Dan Kennedy

On 11/09/2013 06:47 PM, Simon Slavin wrote:

On 9 Nov 2013, at 10:07am, Dan Kennedy  wrote:


On 11/09/2013 04:58 PM, L. Wood wrote:

Richard Hipp  wrote:
Rollback journal files might be closed and reopened.  [snip]

[snip]* But what about the next open() of a new journal file? Will it use the 
new location of the database file or the old one? 

The old one.

When it starts up, SQLite calculates the full paths
to the database and journal files and stores them
in memory. So if the journal file is opened, moved,
closed and then reopened, it will be the original
location that is opened both times.

Given that the journal file is closed-and-reopened only between transactions, 
if SQLite is unable to reopen the journal file (because it was moved/deleted) 
then it will either create a new one or return an error, right ?  No corruption 
of the database will result.


The problem is that you end up with the database and
journal files in separate directories. Which means that
if an application or power failure occurs during a
subsequent transaction, the next client to open the db
will be unable to find the journal file to roll it
back. If the failure occurred after the original process
started writing to the database, this means the database
file will likely be left in a corrupt state.

Dan.





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


Re: [sqlite] Handling move/rename of an SQLite database file

2013-11-09 Thread Simon Slavin

On 9 Nov 2013, at 10:07am, Dan Kennedy  wrote:

> On 11/09/2013 04:58 PM, L. Wood wrote:
>>> Richard Hipp  wrote:
>>> Rollback journal files might be closed and reopened.  [snip]
>> 
>> [snip]* But what about the next open() of a new journal file? Will it use 
>> the new location of the database file or the old one?  
> 
> The old one.
> 
> When it starts up, SQLite calculates the full paths
> to the database and journal files and stores them
> in memory. So if the journal file is opened, moved,
> closed and then reopened, it will be the original
> location that is opened both times.

Given that the journal file is closed-and-reopened only between transactions, 
if SQLite is unable to reopen the journal file (because it was moved/deleted) 
then it will either create a new one or return an error, right ?  No corruption 
of the database will result.

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


Re: [sqlite] Handling move/rename of an SQLite database file

2013-11-09 Thread Dan Kennedy

On 11/09/2013 04:58 PM, L. Wood wrote:

Richard Hipp  wrote:
Rollback journal files might be closed and reopened.  But the main database
file is opened once and held open until sqlite3_close() (or DETACH if the
file was originally opened using ATTACH).

Thanks for this information. But suppose, while a journal file is open, it is 
moved (along with the main database file) to a new directory.

* The next close() of the journal will work just fine, I assume?

* But what about the next open() of a new journal file? Will it use the new 
location of the database file or the old one?   


The old one.

When it starts up, SQLite calculates the full paths
to the database and journal files and stores them
in memory. So if the journal file is opened, moved,
closed and then reopened, it will be the original
location that is opened both times.

Dan.

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


Re: [sqlite] Handling move/rename of an SQLite database file

2013-11-09 Thread L. Wood
> Richard Hipp  wrote:
> Rollback journal files might be closed and reopened.  But the main database
> file is opened once and held open until sqlite3_close() (or DETACH if the
> file was originally opened using ATTACH).

Thanks for this information. But suppose, while a journal file is open, it is 
moved (along with the main database file) to a new directory.

* The next close() of the journal will work just fine, I assume?

* But what about the next open() of a new journal file? Will it use the new 
location of the database file or the old one?   
  
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Handling move/rename of an SQLite database file

2013-11-07 Thread Simon Slavin

On 7 Nov 2013, at 6:03pm, L. Wood  wrote:

> I did a simple experiment and got an error from sqlite3_step() after renaming 
> the file. This is what I did:
> 
> After the call to sqlite3_open(), I halt/sleep my program for 10 seconds to 
> give me ample time to rename the file. I rename the file. The subsequent 
> sqlite3_prepare_v2() works without errors. However, the sqlite3_step() *does* 
> give an error: Error code 10, "disk I/O error". This does not happen if I do 
> not rename the file.
> 
> Am I missing something? 

SQLite's _open() function doesn't actually open the file.  It sets things up so 
that the first proper operation on the file can open it, when it needs to.

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


Re: [sqlite] Handling move/rename of an SQLite database file

2013-11-07 Thread L. Wood
> D. Richard Hipp wrote:
> No errors are returned. SQLite never notices that the database file has
> been renamed.

I did a simple experiment and got an error from sqlite3_step() after renaming 
the file. This is what I did:

After the call to sqlite3_open(), I halt/sleep my program for 10 seconds to 
give me ample time to rename the file. I rename the file. The subsequent 
sqlite3_prepare_v2() works without errors. However, the sqlite3_step() *does* 
give an error: Error code 10, "disk I/O error". This does not happen if I do 
not rename the file.

Am I missing something?   
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Handling move/rename of an SQLite database file

2013-11-07 Thread Simon Slavin

On 7 Nov 2013, at 5:38pm, Richard Hipp  wrote:

> Rollback journal files might be closed and reopened.

Okay.  That gives us more of the answer to the original question.

Wood, this is the only file that SQLite would care about if moved.  And 
technically you could use NSNotification to tell you if someone moved a journal 
file while SQLite was using it.  But in practise, under both OS X and iOS, it 
doesn't matter.  Losing that file between transactions isn't going to corrupt 
your database and if someone does move or delete it at that point the best 
thing your app could do is crash, so the user knows not to do that.

So yes, OS X does give you a mechanism for keeping track of files being moved.  
But there's not much point in using it with a SQLite database.

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


Re: [sqlite] Handling move/rename of an SQLite database file

2013-11-07 Thread Richard Hipp
On Thu, Nov 7, 2013 at 12:04 PM, Simon Slavin  wrote:

>
> Assuming that the user is using OS X, use of standard VFS, access on a
> local disk, no ATTACH, no Jedi mind tricks ...
>
> Does SQLite ever close and reopen database or journal files between
> _open() and _close() ?
>

Rollback journal files might be closed and reopened.  But the main database
file is opened once and held open until sqlite3_close() (or DETACH if the
file was originally opened using ATTACH).


-- 
D. Richard Hipp
d...@sqlite.org
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Handling move/rename of an SQLite database file

2013-11-07 Thread Simon Slavin

On 7 Nov 2013, at 3:58pm, Richard Hipp  wrote:

> On Thu, Nov 7, 2013 at 10:31 AM, L. Wood  wrote:
> 
>> QUESTION: What error codes can each of the following functions possibly
>> return while the database file is renamed/moved during the execution of the
>> function?
> 
> No errors are returned.  SQLite never notices that the database file has
> been renamed.
> 
> In Unix, once a file is opened, the process only deals with the file
> descriptor.  The underlying filename can change or even deleted (unlinked)
> and the application will never know.

Richard (or any of the team),

Assuming that the user is using OS X, use of standard VFS, access on a local 
disk, no ATTACH, no Jedi mind tricks ...

Does SQLite ever close and reopen database or journal files between _open() and 
_close() ?  An example of a time I might expect this would be during a VACUUM, 
or as a transaction finishes while journal_mode = DELETE.

My guess is that if SQLite closes one of these files it creates a new one with 
the name and path it already knows, but I wonder if it might close and reopen 
one of these files.  Of course, if it closes a file you've moved, then tries to 
delete it, it won't be able to delete it.

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


Re: [sqlite] Handling move/rename of an SQLite database file

2013-11-07 Thread Zsbán Ambrus
On Thu, Nov 7, 2013 at 4:31 PM, L. Wood  wrote:
> Users could rename/move a database file while my (Mac OS X) program has made 
> an SQLite connection to the file. I want to handle this properly.

One thing you have to be particularly careful about is the extra files
sqlite creates next to the database file, such as the rollback journal
files.  The page http://sqlite.org/tempfiles.html documents how sqlite
currently uses these.  In particular, if sqlite finds the database
file but does not file the associated journal file, your database can
go corrupted.  I don't know how you could assure that this does not
happen.

Instead of trying to handle errors from the frontend of sqlite, you
might get a more robust solution if you wrote a custom VFS backend for
sqlite, possibly by modifying the existing uniq VSF backend.  The VFS
is documented on http://sqlite.org/vfs.html .

Sqlite performs all operating system dependent functions through the
replacable VFS backend.  These operations include opening a file,
reading, writing, file locking.  This way if, for example, if you
detect that a user have moved the database file and sqlite wants to
open the corresponding rollback journal file, you can make sure that
it opens the correct rollback journal.

Besides ensuring that there the extra files are found correctly, you
will also have to make sure that file locking works correctly accross
moves.  All this gets quite complicated (maybe even impossible),
especially if multiple programs want to open the same sqlite database
concurrently.

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


Re: [sqlite] Handling move/rename of an SQLite database file

2013-11-07 Thread Richard Hipp
On Thu, Nov 7, 2013 at 10:31 AM, L. Wood  wrote:

>
> QUESTION: What error codes can each of the following functions possibly
> return while the database file is renamed/moved during the execution of the
> function?
>

No errors are returned.  SQLite never notices that the database file has
been renamed.

In Unix, once a file is opened, the process only deals with the file
descriptor.  The underlying filename can change or even deleted (unlinked)
and the application will never know.

Note that renaming or unlinking a database file while it is being written,
then killing the writer process or turning the power off, can corrupt the
database file since it leave the associated journal file with a different
name.  See http://www.sqlite.org/howtocorrupt.html#unlink for additional
information.

-- 
D. Richard Hipp
d...@sqlite.org
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Handling move/rename of an SQLite database file

2013-11-07 Thread L. Wood
Users could rename/move a database file while my (Mac OS X) program has made an 
SQLite connection to the file. I want to handle this properly.


Mac OS X (Unix) has ways to track a file that is renamed/moved, so if I can get 
enough information about how SQLite works in this regard, handling this should 
be possible.


Below is a question that I believe I need answered to be able handle this 
properly, but feel free to add more thoughts of your own if you think I need 
more information.


QUESTION: What error codes can each of the following functions possibly return 
while the database file is renamed/moved during the execution of the function?


* sqlite3_open()
* sqlite3_prepare_v2()
* sqlite3_step()
* The various "sqlite3_column()" functions - could they return something 
unexpected?
* sqlite3_finalize()
* sqlite3_close()



My thinking is that if I knew all the possible error codes, I could - upon such 
an error - check if the file was renamed/moved. If it was, I could close and 
reopen the database connection on the new path and continue/restart execution 
as required. If it was not renamed/moved, it would be a genuine error to be 
handled like any other error. (And of course, I would perform the renamed/moved 
check in between the SQLite function calls, but that's not related to SQLite 
per se.)


Again, you're welcome to add your own thoughts to the mix. Thank you.


I'm using SQLite 3.8.1.   
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users