Re: [sqlite] assert crash in wal

2010-12-16 Thread Christian Smith
On Thu, Dec 16, 2010 at 09:41:27AM +0200, Yoni Londner wrote:
> 
> > The underlying error here is that you are attempting to use threads in the
> > first place.  You should never do that.  Threads are evil and should be
> > avoided wherever possible.  Use separate processes for concurrency.  Threads
> > in application programs always result in subtle bugs (such as this one) that
> > are hard to reproduce and waste countless hours of developer time.  Just say
> > "no" to threads.
> Could not agree with you more. Threads are evil. This is exactly the 
> reason I cannot EVER do long operations
> in the main thread (and by long I mean more than 20-30 ms). If I will do 
> long operations, my system wont be
> responsive enough.
> When is it allowed to use threads? Only to do long, standalone 
> operations, that would block the main thread (such
> as wal checkpoints).
> That is exactly what I did in my example program.
> 
> What I really wanted to do, is to use long transactions in the main 
> thread and checkpoint in a background thread.
> long transaction increase the performance (and responsiveness) 
> dramatically, since most of the work is in memory,
> and when committing, much less pages needs to be written to the DB 
> (since many sql statements update the same pages),
> so I/O is reduced by order of magnitude. In addition there is no 
> overhead of begin/end transaction for every statement.

In WAL mode, any data manipulated will not be visible outside the
transaction until the final commit. Therefore, why not collect
data into an internal buffer, and write it out periodically
to SQLite in a background thread. That background thread can
do all the inserts and checkpointing in a big transaction,
without worrying about blocking the foreground data collection
thread.

Once the forground thread has collected enough data for a big
transaction, it passes if off to the background SQLite thread,
then continues on with a new list of data.

Using the above scheme, you'll have all the durability guarantees
as your existing code, and with no restrictions on the checkpoint
time length you currently have.

I understand that this may change the structure of your code
somewhat, but that is preferable to large scale messing with the WAL
code that noone else needs.

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


Re: [sqlite] assert crash in wal

2010-12-15 Thread Yoni Londner

> The underlying error here is that you are attempting to use threads in the
> first place.  You should never do that.  Threads are evil and should be
> avoided wherever possible.  Use separate processes for concurrency.  Threads
> in application programs always result in subtle bugs (such as this one) that
> are hard to reproduce and waste countless hours of developer time.  Just say
> "no" to threads.
Could not agree with you more. Threads are evil. This is exactly the 
reason I cannot EVER do long operations
in the main thread (and by long I mean more than 20-30 ms). If I will do 
long operations, my system wont be
responsive enough.
When is it allowed to use threads? Only to do long, standalone 
operations, that would block the main thread (such
as wal checkpoints).
That is exactly what I did in my example program.

What I really wanted to do, is to use long transactions in the main 
thread and checkpoint in a background thread.
long transaction increase the performance (and responsiveness) 
dramatically, since most of the work is in memory,
and when committing, much less pages needs to be written to the DB 
(since many sql statements update the same pages),
so I/O is reduced by order of magnitude. In addition there is no 
overhead of begin/end transaction for every statement.

Currently I am running wal checkpoint in the main thread, every time sql 
cache is stressed (about 2000 dirty pages).
but checkpoint can take a VERY long time (from 400ms to 20secs!) and 
this time is simply unacceptable.
So I want to run checkpoint in another thread. But then I bump into the 
wal file size problem:
http://www.mail-archive.com/sqlite-users@sqlite.org/msg57071.html

So, this is what I am trying to solve now, using the method I described 
in the link above.
I hope that one of the SQLite developer can attend to this problem, and 
would love to hear if you have
any intention to do this in the near future.
I also would love to hear any comment on the solution I suggested.

Yoni.



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


Re: [sqlite] assert crash in wal

2010-12-15 Thread Yoni Londner
That's was fast!
I tried it, and it seems to work correctly now.
Thanks! :-)
Yoni.

On 16/12/2010 4:08 AM, Richard Hipp wrote:
> The patch at http://www.sqlite.org/src/ci/cf86affcb7 should fix this
> problem.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] assert crash in wal

2010-12-15 Thread Richard Hipp
The patch at http://www.sqlite.org/src/ci/cf86affcb7 should fix this
problem.
-- 
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] assert crash in wal

2010-12-15 Thread Richard Hipp
On Wed, Dec 15, 2010 at 6:18 PM, Yoni Londner  wrote:

> Hi Richard,
>
>  >
>  > Perhaps I speak too soon.  I'm still getting the error even after
> changing
>  > this to SQLITE_CONFIG_SERIALIZED.  I am continuing to investigate
>  >
>
> Note that I used two sql connections (one for each thread)
>

Yes.  I did eventually see that.  Your code appears to be correct and my
tirade against threads rather premature.  I apologize.

At this time, the assertion failures appear to be due to a harmless race
condition.  At least I *think* it is harmless.  By which I mean I cannot see
any harm at the moment.  Nevertheless, I am testing changes that will
eliminate the race condition so that the assert()s can remain in the code.
If everything works out, I should be able to check in a candidate fix later
tonight.





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



-- 
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] assert crash in wal

2010-12-15 Thread Yoni Londner
Hi Richard,

 >
 > Perhaps I speak too soon.  I'm still getting the error even after 
changing
 > this to SQLITE_CONFIG_SERIALIZED.  I am continuing to investigate
 >

Note that I used two sql connections (one for each thread)

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


Re: [sqlite] assert crash in wal

2010-12-15 Thread Max Vlasov
On Wed, Dec 15, 2010 at 11:14 PM, Doug  wrote:

> .  And getting concurrency with processes means you introduce the
> complexities of interprocess communication/synchronization which is much
> easier to handle with threads in the same process.
>
>
Doug, nothing stops you from using different threads of different
connections in the same process. That's how for example my fts
implementations works. When the user presses keys in the edit box, the
secondary thread look-ups word that starts with those letters in a different
connection to the same base, works like a charm. Sure, memory usage can
increase in this case, but if one compares footprints of modern libraries,
frameworks and so on with sqlite, even with several connections sqlite is
still the winner

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


Re: [sqlite] assert crash in wal

2010-12-15 Thread Doug
From: sqlite-users-boun...@sqlite.org
[mailto:sqlite-users-boun...@sqlite.org] On Behalf Of Richard Hipp
>The underlying error here is that you are attempting to use threads in the
first place.  You should never do that.  Threads are evil and should be
avoided wherever possible.  Use separate processes > for concurrency.
Threads in application programs always result in subtle bugs (such as this
one) that are hard to reproduce and waste countless hours of developer time.
Just say "no" to threads.

Richard, you've said this many times on this list.  Wouldn't using separate
processes hurt performance significantly?  It means you can't ever share the
page cache (either by sharing an SQLite connection between threads in a
serial way protected by mutex, etc, or by actually using shared cache
semantics).  And getting concurrency with processes means you introduce the
complexities of interprocess communication/synchronization which is much
easier to handle with threads in the same process.  

But you are right about the costs -- the benefits of using threads incur a
cost -- a cost of being very careful.

Doug



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



Re: [sqlite] assert crash in wal

2010-12-15 Thread Richard Hipp
On Wed, Dec 15, 2010 at 11:49 AM, Richard Hipp  wrote:

>
>
> On Wed, Dec 15, 2010 at 8:34 AM, 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?
>>
>
> ...
>
>
>> sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
>>
>
> Read about SQLITE_CONFIG_MULTITHREAD here:
> http://www.sqlite.org/threadsafe.html
>
> MULTITHREAD is not safe to use with two or more threads sharing the same
> database connection.
>


Perhaps I speak too soon.  I'm still getting the error even after changing
this to SQLITE_CONFIG_SERIALIZED.  I am continuing to investigate

-- 
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] assert crash in wal

2010-12-15 Thread Richard Hipp
On Wed, Dec 15, 2010 at 8:34 AM, 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?
>

...


> sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
>

Read about SQLITE_CONFIG_MULTITHREAD here:
http://www.sqlite.org/threadsafe.html

MULTITHREAD is not safe to use with two or more threads sharing the same
database connection.

The underlying error here is that you are attempting to use threads in the
first place.  You should never do that.  Threads are evil and should be
avoided wherever possible.  Use separate processes for concurrency.  Threads
in application programs always result in subtle bugs (such as this one) that
are hard to reproduce and waste countless hours of developer time.  Just say
"no" to threads.


> 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
>



-- 
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] assert crash in wal

2010-12-15 Thread Yoni Londner
Isn't that the default?
from sqliteInt.h:
#if !defined(SQLITE_THREADSAFE)
#if defined(THREADSAFE)
# define SQLITE_THREADSAFE THREADSAFE
#else
# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */
#endif
#endif

Anyway, I added the define and it still happening.

Yoni.

On 15/12/2010 3:39 PM, Marco Bambini wrote:
> Try to add:
> -DSQLITE_THREADSAFE =1
> to your compilation options.
>
> --
> Marco Bambini
> http://www.sqlabs.com
>
>
>
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] assert crash in wal

2010-12-15 Thread Marco Bambini
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' , 
> "', '", 'b' , "')", 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'  times>, "', '", 'b' , "')", fail_if_locked=1) at 
> sqlite_large_wal.c:52
> #12 0x080493ed in sql_exec (conn=0x93b4068,
> query=0x80e3e24 "INSERT INTO tbl1 values('", 'a'  times>, "', '", 'b' , "')") at sqlite_large_wal.c:64
> #13 0x0804945b in do_insert (conn=0x93b4068) at sqlite_large_wal.c:85
> #14 0x08049663 in main (argc=, argv= 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 100
> #define MS_SEC 1000
> #define NSEC_PER_SEC 10
> 
> 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(),

[sqlite] assert crash in wal

2010-12-15 Thread Yoni Londner
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' , 
"', '", 'b' , "')", 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' , "', '", 'b' , "')", fail_if_locked=1) at 
sqlite_large_wal.c:52
#12 0x080493ed in sql_exec (conn=0x93b4068,
 query=0x80e3e24 "INSERT INTO tbl1 values('", 'a' , "', '", 'b' , "')") at sqlite_large_wal.c:64
#13 0x0804945b in do_insert (conn=0x93b4068) at sqlite_large_wal.c:85
#14 0x08049663 in main (argc=, argv=)
 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 100
#define MS_SEC 1000
#define NSEC_PER_SEC 10

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;