Hi, I just wanted to add that I changed the program a little bit to not use transactions and threads, and I still get the same problem (huge WAL file). All I do is endless loop of insert, and every X insert, I perform a checkpoint on another sqlite connection (but in the same thread). It only worked if I do the checkpoint on the same connection. Yoni.
On Tue, Aug 10, 2010 at 11:46 AM, Yoni Londner <[email protected]> wrote: > Hi Richard, > Thanks for the quick response. > I wrote a little program that demonstrate the error (below). > It opens a new DB, create a table, and start an endless loop of INSERT's. > In a background thread it performs a wal checkpoint. > There is no difference in WAL file size - with or without transactions > (passed by argument to the program). > This is the result after 45 seconds: > -rw-r--r-- 1 1.0K 2010-08-10 11:41 test.db > -rw-r--r-- 1 1.1G 2010-08-10 11:42 test.db-wal > -rw-r--r-- 1 8.0M 2010-08-10 11:42 test.db-shm > > Program compiled with GCC on debian lenny, using sqlite 3.7.0. > > #include "sqlite3.h" > #include "stdio.h" > #include "stdlib.h" > #include "fcntl.h" > > static void sql_exec(sqlite3 *conn, char *query) > { > char *err; > if (sqlite3_exec(conn, query, NULL, 0, &err)) > { > printf("sqlite: failed exec %s. err: %s\n", query, err); > exit(1); > } > } > > static sqlite3 *sql_open_conn(void) > { > sqlite3 *conn; > if (sqlite3_open_v2("test.db", &conn, SQLITE_OPEN_READWRITE, NULL)) > { > printf("sqlite3_open_v2 failed\n"); > exit(1); > } > return conn; > } > > static int do_checkpoint() > { > sqlite3 *conn; > while (1) > { > sleep(2); > printf("calling wal checkpoint\n"); > fflush(0); > conn = sql_open_conn(); > if (sqlite3_wal_checkpoint(conn, NULL)) > { > printf("sqlite3_wal_autocheckpoint failed\n"); > exit(1); > } > sqlite3_close(conn); > } > } > > int main(int argc, char **argv) > { > sqlite3 *conn = NULL; > char *err_msg = NULL; > pthread_t thread; > int fd, i, use_transactions = 0; > time_t start; > if (argc>1) > use_transactions = atoi(argv[1]); > printf("use_transactions=%d\n", use_transactions); > printf("Start\n"); > if (unlink("test.db") || unlink("test.db-wal")) > { > printf("failed unlink test.db\n"); > exit(1); > } > fd = open("test.db", O_CREAT|O_RDWR, 0666); > if (fd<0) > { > printf("could not open test.db\n"); > exit(1); > } > close(fd); > conn = sql_open_conn(); > sqlite3_enable_shared_cache(1); > sql_exec(conn, "PRAGMA journal_mode=WAL"); > sql_exec(conn, "PRAGMA synchronous=normal"); > sql_exec(conn, "PRAGMA temp_store=memory"); > sql_exec(conn, "PRAGMA wal_autocheckpoint=-1"); > sql_exec(conn, "create table tbl1 (one varchar(20), two varchar(20))"); > if (pthread_create(&thread, NULL, do_checkpoint, NULL)) > { > printf("could not start thread\n"); > exit(1); > } > start = time(); > if (use_transactions) > sql_exec(conn, "BEGIN TRANSACTION"); > while (1) > { > if (use_transactions && !(i++%100000)) > { > printf("END BEGIN transactions\n"); > fflush(stdout); > sql_exec(conn, "END TRANSACTION"); > sql_exec(conn, "BEGIN TRANSACTION"); > } > sql_exec(conn, "INSERT INTO tbl1 values('aaaaaaaaaaaaaaaaaaa', " > "'bbbbbbbbbbbbbbbbbbb')"); > } > if (use_transactions) > sql_exec(conn, "END TRANSACTION"); > sqlite3_close(conn); > printf("Finished\n"); > return 0; > } > On Tue, Aug 10, 2010 at 9:36 AM, Richard Hipp <[email protected]> wrote: > >> On Tue, Aug 10, 2010 at 2:24 AM, Yoni Londner <[email protected]> wrote: >> >> > Hello, >> > I have a questions about the correct use of transactions and WAL. >> > >> > I am writing an application that: >> > 1. should very fast >> > 2. should be very responsive >> > 3. don't care if the last N minutes of data will be lost (but DB should >> > never be corrupted) >> > >> > What I tried to do: >> > 1. open a transactions and close it every 3 minutes (So most of the >> tune >> > all work is on memory, and thus is very fast) >> > 2. disable wal auto checkpoint (So I wont have very slow queries due to >> a >> > checkpoint) >> > 3. run wal checkpoint in another thread (with another connection) - so >> it >> > wont affect the responsiveness of the main thread. >> > >> > Results: >> > 1. process memory is increasing with no upper limit >> > 2. eventually I get an I/O error >> > >> >> I'm guessing your write transactions are preventing the checkpoint from >> running to completion. Hence, the WAL grows without bound and the >> wal-index >> (an in-memory structure proportional in size to the WAL file) eventually >> uses up all memory. >> >> Set PRAGMA synchronous=NORMAL. This prevents all fsync() calls on the >> writer thread at the cost of durability, which you say you don't care >> about. >> Omit the 3-minute transactions, allowing each write to be its own >> transaction. Writes then will still be in-memory (if you count the >> operating system filesystem cache as "in-memory"). But then the >> checkpoints >> will be able to run and keep the size of the WAL file under control. >> >> >> >> > >> > Questions: >> > 1. what am I doing wrong. >> > 2. what is the correct way to achieve the goals I mentioned before. >> > >> > Thanks, >> > Jon. >> > _______________________________________________ >> > sqlite-users mailing list >> > [email protected] >> > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users >> > >> >> >> >> -- >> D. Richard Hipp >> [email protected] >> _______________________________________________ >> sqlite-users mailing list >> [email protected] >> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users >> > > _______________________________________________ sqlite-users mailing list [email protected] http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

