Try to add: -DSQLITE_THREADSAFE =1 to your compilation options. -- Marco Bambini http://www.sqlabs.com
On Dec 15, 2010, at 2:34 PM, Yoni Londner wrote: > Hi, > > I wrote a little program that insert in a loop rows in to the DB, and in > another thread run wal_checkpoint. > After few minutes (6-7) I get (consistently) the following assert error: > > sqlite_test: ..//src/wal.c:1364: walMerge: Assertion `iLeft>=nLeft || > aContent[aLeft[iLeft]]>dbpage' failed. > > I compiled sqlite from fossil, with -DSQLITE_DEBUG and -DSQLITE_TEST > I pasted below the program and the stacks. > Am I doing something wrong? > > Yoni. > > (gdb) info threads > 2 Thread 26132 0x0804ed3b in pthreadMutexEnter (p=0x8103068) > at ..//src/mutex_unix.c:238 > * 1 Thread 26133 0xb7734424 in __kernel_vsyscall () > (gdb) bt > #0 0xb7734424 in __kernel_vsyscall () > #1 0xb75e2640 in raise () from /lib/i686/cmov/libc.so.6 > #2 0xb75e4018 in abort () from /lib/i686/cmov/libc.so.6 > #3 0xb75db5be in __assert_fail () from /lib/i686/cmov/libc.so.6 > #4 0x080776a8 in walMerge (aContent=0xb7729088, aLeft=0x96157b4, nLeft=2, > paRight=0xb759a898, pnRight=0xb759a89c, aTmp=0x9619cb8) at > ..//src/wal.c:1364 > #5 0x080778a0 in walMergesort (aContent=0xb7729088, aBuffer=0x9619cb8, > aList=0x9614654, pnList=0xb759a8f0) at ..//src/wal.c:1405 > #6 0x08077c63 in walIteratorInit (pWal=0x93f5c60, pp=0xb759a984) > at ..//src/wal.c:1510 > #7 0x08077d8b in walCheckpoint (pWal=0x93f5c60, sync_flags=2, nBuf=1024, > zBuf=0x93c3968 "\r") at ..//src/wal.c:1579 > #8 0x08079c0b in sqlite3WalCheckpoint (pWal=0x93f5c60, sync_flags=2, > nBuf=1024, > zBuf=0x93c3968 "\r") at ..//src/wal.c:2647 > #9 0x0805de51 in sqlite3PagerCheckpoint (pPager=0x93c2f08) at > ..//src/pager.c:6558 > #10 0x0809e68d in sqlite3BtreeCheckpoint (p=0x93c17a8) at > ..//src/btree.c:7953 > #11 0x0804b8fb in sqlite3Checkpoint (db=0x93c0af0, iDb=10) at > ..//src/main.c:1402 > #12 0x080dd80d in sqlite3VdbeExec (p=0x93c36d8) at ..//src/vdbe.c:5225 > #13 0x0806b932 in sqlite3Step (p=0x93c36d8) at ..//src/vdbeapi.c:394 > #14 0x0806bba9 in sqlite3_step (pStmt=0x93c36d8) at ..//src/vdbeapi.c:458 > #15 0x080497af in sqlite3_exec (db=0x93c0af0, zSql=0x80e3e75 "PRAGMA > wal_checkpoint", > xCallback=0, pArg=0x0, pzErrMsg=0xb759b38c) at ..//src/legacy.c:70 > #16 0x0804937b in _sql_exec (conn=0x93c0af0, query=0x80e3e75 "PRAGMA > wal_checkpoint", > fail_if_locked=0) at sqlite_large_wal.c:52 > #17 0x080494d8 in thread_do () at sqlite_large_wal.c:104 > #18 0xb75a34c0 in start_thread () from /lib/i686/cmov/libpthread.so.0 > #19 0xb769784e in clone () from /lib/i686/cmov/libc.so.6 > (gdb) thread 2 > [Switching to thread 2 (Thread 26132)]#0 0x0804ed3b in pthreadMutexEnter ( > p=0x8103068) at ..//src/mutex_unix.c:238 > 238 assert( p->nRef>0 || p->owner==0 ); > (gdb) bt > #0 0x0804ed3b in pthreadMutexEnter (p=0x8103068) at > ..//src/mutex_unix.c:238 > #1 0x0804e6db in sqlite3_mutex_enter (p=0x8103068) at ..//src/mutex.c:112 > #2 0x0804da91 in sqlite3_free (p=0x958de28) at ..//src/malloc.c:470 > #3 0x0804dbcf in sqlite3DbFree (db=0x93b4068, p=0x958de28) at > ..//src/malloc.c:503 > #4 0x0806f289 in releaseMemArray (p=0x96130d8, N=6) at > ..//src/vdbeaux.c:1018 > #5 0x0807021f in closeAllCursors (p=0x94df2b8) at ..//src/vdbeaux.c:1538 > #6 0x08070f21 in sqlite3VdbeHalt (p=0x94df2b8) at ..//src/vdbeaux.c:2042 > #7 0x080d1991 in sqlite3VdbeExec (p=0x94df2b8) at ..//src/vdbe.c:861 > #8 0x0806b932 in sqlite3Step (p=0x94df2b8) at ..//src/vdbeapi.c:394 > #9 0x0806bba9 in sqlite3_step (pStmt=0x94df2b8) at ..//src/vdbeapi.c:458 > #10 0x080497af in sqlite3_exec (db=0x93b4068, > zSql=0x80e3e24 "INSERT INTO tbl1 values('", 'a' <repeats 19 times>, > "', '", 'b' <repeats 19 times>, "')", xCallback=0, pArg=0x0, > pzErrMsg=0xbf9dd57c) > at ..//src/legacy.c:70 > #11 0x0804937b in _sql_exec (conn=0x93b4068, > query=0x80e3e24 "INSERT INTO tbl1 values('", 'a' <repeats 19 > times>, "', '", 'b' <repeats 19 times>, "')", fail_if_locked=1) at > sqlite_large_wal.c:52 > #12 0x080493ed in sql_exec (conn=0x93b4068, > query=0x80e3e24 "INSERT INTO tbl1 values('", 'a' <repeats 19 > times>, "', '", 'b' <repeats 19 times>, "')") at sqlite_large_wal.c:64 > #13 0x0804945b in do_insert (conn=0x93b4068) at sqlite_large_wal.c:85 > #14 0x08049663 in main (argc=<value optimized out>, argv=<value > optimized out>) > at sqlite_large_wal.c:139 > (gdb) > > > #include "sqlite3.h" > #include "stdio.h" > #include "stdlib.h" > #include "fcntl.h" > #include "errno.h" > > #define NSEC_PER_MS 1000000 > #define MS_SEC 1000 > #define NSEC_PER_SEC 1000000000 > > typedef unsigned long long u64; > static u64 _time_monotonic_nsec(void) > { > struct timespec t; > if (clock_gettime(1, &t)) > { > printf("error clock_gettime\n"); > exit(1); > } > return ((u64)t.tv_sec) * NSEC_PER_SEC + t.tv_nsec; > } > > u64 _time_monotonic_ms(void) > { > return _time_monotonic_nsec()/NSEC_PER_MS; > } > > void sleep_ms(int ms) > { > int start = _time_monotonic_ms(), diff = 0; > #ifndef __ZWIN32__ > struct timespec req; > req.tv_nsec = (ms%MS_SEC)*NSEC_PER_MS; > req.tv_sec = ms/MS_SEC; > #endif > while (1) > { > req.tv_nsec = ((ms-diff)%MS_SEC)*NSEC_PER_MS; > req.tv_sec = (ms-diff)/MS_SEC; > if (nanosleep(&req, NULL) && errno!=EINTR) > break; > if ((diff = _time_monotonic_ms()-start) >= ms) > break; > } > } > > static void _sql_exec(sqlite3 *conn, char *query, int fail_if_locked) > { > char *err; > int ret; > if ((ret = sqlite3_exec(conn, query, NULL, 0, &err))) > { > if (!fail_if_locked && (ret == SQLITE_BUSY || ret == > SQLITE_LOCKED)) > return; > printf("sqlite: failed exec (%p) %s. err: %s\n", pthread_self(), > query, err); > exit(1); > } > } > > static void sql_exec(sqlite3 *conn, char *query) > { > _sql_exec(conn, query, 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 void do_insert(sqlite3 *conn) > { > int i; > while (1) > { > for (i=0; i<10000; i++) > { > sql_exec(conn, "INSERT INTO tbl1 values('aaaaaaaaaaaaaaaaaaa', " > "'bbbbbbbbbbbbbbbbbbb')"); > } > sleep(1); > } > } > > static int thread_do() > { > sqlite3 *conn = sql_open_conn(); > int i; > sleep(1); > while (1) > { > sleep(1); > printf("checkpoint\n"); > fflush(0); > for (i=0; i<20; i++) > { > _sql_exec(conn, "PRAGMA wal_checkpoint", 0); > sleep_ms(100); > } > } > } > > int main(int argc, char **argv) > { > char *err_msg = NULL; > pthread_t thread; > int fd, i = 0; > time_t start; > sqlite3 *conn = NULL; > printf("Start\n"); > if (unlink("test.db") || unlink("test.db-wal") || > unlink("test.db-shm")) > printf("failed unlink test.db\n"); > fd = open("test.db", O_CREAT|O_RDWR, 0666); > if (fd<0) > { > printf("could not open test.db\n"); > exit(1); > } > close(fd); > sqlite3_config(SQLITE_CONFIG_MULTITHREAD); > conn = sql_open_conn(); > 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, thread_do, NULL)) > { > printf("could not start thread\n"); > exit(1); > } > do_insert(conn); > sqlite3_close(conn); > printf("Finished\n"); > return 0; > } > _______________________________________________ > 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