> So the question is what is so special about sqlite3RunVacuum that it needs > more space than a simple emulation of its actions?
I believe renaming of the file cannot be atomic. So in case of OS crash you can be in situation without database at all - no old and no new. Also deleting of old file can be problematic when other processes have open handles to it. Even if Unix system will allow that all those processes won't know that they should re-open there handles to work with new file. Pavel On Tue, Mar 16, 2010 at 11:18 AM, Max Vlasov <max.vla...@gmail.com> wrote: >> This means that to VACUUM a SQLite database of size X, you need at >> least 2X of _additional_ free disk space available. That seems rather >> wasteful, just looking at it as a SQLite user. Although >> programmatically there may be reasons for it that I'm not aware of. >> >> > > Hmm, did some research, I think that VACUUM requirements for free disk > space is too big. > > When I read the comments it was obvious that the algorithm uses very simple > approach: > Attach blank database, copy all data, detach, rename. Sure I might be > wrong in details, but generally it looks like this. > > With this actions journal file(s) for the new database should not contain > much data. So my quess is one only need at most the size of the actual data > from the source base plus very tiny journal file. But in fact (as everyone > sees) it uses much more. > > I just tried to perform VACUUM on a test base and emulate the actions with > manual attach/copy with the same base. > > We have: > - truecrypt volume, size: 10M in order to see all the "disk full" errors. > - new connection, testdb.db3 > - CREATE TABLE [TestTable] ([Id] INTEGER PRIMARY KEY AUTOINCREMENT,[Value] > Text) > - 100,000 times > INSERT INTO TestTable (Value) VALUES > ("12345678901234567890123456789012345678901234567890") > Final size: 6M > - After we have completely filled the db, let's remove half of the records. > DELETE FROM TestTable WHERE Id < 50000 > > Now we have our 6M db (ready to be decreased to ~3) and about 4M of free > space. > > So two scenarios: > > ======== 1. Simple vacuum > > Trying to perform VACUUM: > Result: "database or disk is full" error. > > ======== 2. Emulation of Vacuum actions. > > testdb_new.db3 is a new connection (tiny file 3k in size) > > ATTACH 'Q:\testdb_new.db3' AS newdb > > BEGIN TRANSACTION > ; the following operations create two db-journal files so rollback is > possible. > > CREATE TABLE newdb.TestTable ([Id] INTEGER PRIMARY KEY AUTOINCREMENT,[Value] > Text) > ; actually sqlite3RunVacuum does some string formatting with results from > sqlite_master and performing corresponding queries. so this create table is > probably the same query. > > INSERT INTO newdb.TestTable SELECT * FROM main.TestTable > ; the operation is ok, Windows reports 3M free, but this is probably due > to cached writes. > > END TRANSACTION > ; Ok, testdb_new is 3m and 1M is free > > ========= > > So the question is what is so special about sqlite3RunVacuum that it needs > more space than a simple emulation of its actions? > > Thanks > > Max > _______________________________________________ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users > _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users