> So as long as you're in the simple case (e.g. doing a simple SELECT while > another process INSERTs). you should never see a deadlock, correct?
Yes, as long as you don't use transactions, or your transactions are homogeneous (in terms of using only SELECTs or only INSERTs/UPDATEs/DELETEs), or all your non-homogeneous transactions start with BEGIN IMMEDIATE or BEGIN EXCLUSIVE. > And the explanation would seem to indicate this: > sqlite3_busy_handler() -- do this on your prepared statement Busy handler is set per-connection, not per-statement. > if sqlite3_step() returns SQLITE_BUSY then something is terribly wrong as > this should only occur in a deadlock. It occurs in a deadlock or when busy handler is tired of waiting and decided that it's enough. > I guess my question ends up being how does one guarantee this works: If busy handler allows infinite waiting and there's no access to the database from any other process then yes, this pseudo code will never return SQLITE_BUSY. Pavel On Thu, May 13, 2010 at 8:58 AM, Black, Michael (IS) <michael.bla...@ngc.com> wrote: > OK...so after reading that it sounds like the situation you need to avoid is > a deadlock. > > So as long as you're in the simple case (e.g. doing a simple SELECT while > another process INSERTs). you should never see a deadlock, correct? > > And the explanation would seem to indicate this: > sqlite3_busy_handler() -- do this on your prepared statement > if sqlite3_step() returns SQLITE_BUSY then something is terribly wrong as > this should only occur in a deadlock. > > I guess my question ends up being how does one guarantee this works: > > process1: > sqlite3_open() > while(1) { > sqlite3_prepare_v2("insert stuff"); > sqlite3_busy_handler(); > sqlite3_step(); // this should NEVER return SQLITE_BUSY -- busy handler > takes care > sqlite3_finalize(); > } > > process2: > sqlite3_open() > while(1) { > sqlite3_prepare_v2("select stuff"); > sqlite3_busy_handler(); > sqlite3_step(); // this should NEVER return SQLITE_BUSY > sqlite3_finalize(); > } > > Michael D. Black > Senior Scientist > Northrop Grumman Mission Systems > > > ________________________________ > > From: sqlite-users-boun...@sqlite.org on behalf of Pavel Ivanov > Sent: Thu 5/13/2010 7:40 AM > To: General Discussion of SQLite Database > Subject: Re: [sqlite] multi processes,so many errores of SQLITE_BUSY and > SQLITE_MISUSE > > > >> Hmmm...bad assumption on my part....seems so logical that if it's busy just >> try again -- and that idea worked on Liubin's problem. > > Read 4th paragraph from here > http://www.sqlite.org/c3ref/busy_handler.html ("The presence of a busy > handler ...") and see why it's not a good idea to always wait while > database is busy (word "locked" here would be better than "busy"). > >> I see this http://www.sqlite.org/c3ref/stmt.html -- but it doesn't quite >> address the BUSY condition. > > See here http://www.sqlite.org/c3ref/step.html: > > "SQLITE_BUSY means that the database engine was unable to acquire the > database locks it needs to do its job. If the statement is a COMMIT or > occurs outside of an explicit transaction, then you can retry the > statement. If the statement is not a COMMIT and occurs within a > explicit transaction then you should rollback the transaction before > continuing." > > From the same page: > > "SQLITE_ERROR means that a run-time error (such as a constraint > violation) has occurred. sqlite3_step() should not be called again on > the VM. More information may be found by calling sqlite3_errmsg(). > With the legacy interface, a more specific error code (for example, > SQLITE_INTERRUPT, SQLITE_SCHEMA, SQLITE_CORRUPT, and so forth) can be > obtained by calling sqlite3_reset() on the prepared statement. In the > "v2" interface, the more specific error code is returned directly by > sqlite3_step(). > > SQLITE_MISUSE means that the this routine was called inappropriately. > Perhaps it was called on a prepared statement that has already been > finalized or on one that had previously returned SQLITE_ERROR or > SQLITE_DONE." > > > I believe you can put words "error code" in this text instead of > "SQLITE_ERROR", its meaning will be the same - if you call > sqlite3_step after an error again then SQLITE_MISUSE will be returned > (although from my experience in some cases repeated sqlite3_step can > work, but generally you better call sqlite3_reset). > > > Pavel > > On Thu, May 13, 2010 at 8:13 AM, Black, Michael (IS) > <michael.bla...@ngc.com> wrote: >> Hmmm...bad assumption on my part....seems so logical that if it's busy just >> try again -- and that idea worked on Liubin's problem. I see this >> http://www.sqlite.org/c3ref/stmt.html -- but it doesn't quite address the >> BUSY condition. >> >> I also found this thread >> http://www.mail-archive.com/sqlite-users@sqlite.org/msg06916.html >> >> Which doesn't mention using reset (perhaps he is but just doesn't mention >> it) but using busy_handler instead. This guy seems to have stressed it >> pretty hard. >> >> >> >> >> >> Michael D. Black >> Senior Scientist >> Northrop Grumman Mission Systems >> >> >> ________________________________ >> >> From: sqlite-users-boun...@sqlite.org on behalf of Pavel Ivanov >> Sent: Thu 5/13/2010 6:40 AM >> To: General Discussion of SQLite Database >> Subject: Re: [sqlite] multi processes,so many errores of SQLITE_BUSY and >> SQLITE_MISUSE >> >> >> >>> I assume you want the sqllite3_stmt to work -- so you need to loop that >>> while it's busy. >> >> Michael, don't give bad advices. >> The most general advice when one gets SQLITE_BUSY is to reset/finalize >> all statements and rollback current transaction. It's only in certain >> type of transactions and certain type of statements one can loop while >> sqlite3_stmt returns SQLITE_BUSY. But even in this case one must call >> sqlite3_reset on the statement that returned SQLITE_BUSY. And this >> call to sqlite3_reset will return SQLITE_BUSY again. >> >> >> Pavel >> >> On Thu, May 13, 2010 at 7:20 AM, Black, Michael (IS) >> <michael.bla...@ngc.com> wrote: >>> It also means you're not handling the SQLITE_BUSY from the sqlite3_stmt() >>> before it. >>> I assume you want the sqllite3_stmt to work -- so you need to loop that >>> while it's busy. >>> >>> Michael D. Black >>> Senior Scientist >>> Northrop Grumman Mission Systems >>> >>> >>> ________________________________ >>> >>> From: sqlite-users-boun...@sqlite.org on behalf of liubin liu >>> Sent: Thu 5/13/2010 2:07 AM >>> To: sqlite-users@sqlite.org >>> Subject: Re: [sqlite] multi processes, so many errores of SQLITE_BUSY and >>> SQLITE_MISUSE >>> >>> >>> >>> >>> I see many SQLITE_BUSY returned from sqlite3_finalize(). Are they memory >>> leak >>> because it don't succeed in finalizing the sqlite3_stmt pointer? >>> >>> >>> >>> >>> Black, Michael (IS) wrote: >>>> >>>> SQLITE_BUSY is not an error...just a fact. >>>> >>>> All your processes cannot work on the database at the same time...at least >>>> not when one of them is doing an insert. You could be changing the table >>>> while you're scanning it. EXXCLUSIVE doesn't change that idea. >>>> >>>> Somebody please correct me if I'm wrong on this one... >>>> I think sqlite can work with multiple processes just doing read-onliy >>>> operations (like SELECT). It's just the write operations >>>> (INSERT/UPDATE) which will cause SQLITE_BUSY to occur. >>>> >>>> Michael D. Black >>>> Senior Scientist >>>> Northrop Grumman Mission Systems >>>> >>>> >>>> ________________________________ >>>> >>>> From: sqlite-users-boun...@sqlite.org on behalf of liubin liu >>>> Sent: Tue 5/11/2010 9:20 PM >>>> To: sqlite-users@sqlite.org >>>> Subject: Re: [sqlite] multi processes, so many errores of SQLITE_BUSY and >>>> SQLITE_MISUSE >>>> >>>> >>>> >>>> >>>> Thank you very much! >>>> >>>> It may be because my system's resource is limited. It's a embedded system >>>> containing 32M RAM, ARM9 CPU. >>>> >>>> My "reiterating 20 times" is already using usleep(). >>>> >>>> After I add the loop in the prepare statements, the system performance is >>>> still very bad... And there are still many errores of SQLITE_BUSY. >>>> >>>> The only improvement is the disappear of the error of SQLITE_MISUSE. >>>> >>>> And I tried to use the "BEGIN EXCLUSIVE TRANSACTION". The things are same >>>> with them without using it. >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> Black, Michael (IS) wrote: >>>>> >>>>> Your "reiterating 20 times" is not using a usleep so you'll blow by this >>>>> most every time it's busy. >>>>> >>>>> Do this instead in all your proc's >>>>> >>>>> ret = sqlite3_step (p_stmt); >>>>> if (SQLITE_BUSY == ret) >>>>> { >>>>> int n=0; >>>>> usleep(100000); // try one more time before error >>>>> while ((ret=sqlite3_step(p_stmt))==SQLITE_BUSY) { >>>>> printf("proc1 ret==BUSY %d\n",++n); >>>>> usleep(100000); >>>>> } >>>>> } >>>>> >>>>> And you'll also need to handle "database is locked" coming from your >>>>> prepare statements. I saw that error too. >>>>> You'll need to loop there too. >>>>> >>>>> The more you drop the usleep time the more times it will show as busy. >>>>> 1/10th or 1/100th of second is about all you want I would think. >>>>> >>>>> And get rid of the usleep at the bottom of each proc -- it's pretty >>>>> useless at 100 microseconds. You don't need to sleep unless you're busy. >>>>> >>>>> I tested your code with this and got no errors at all -- just a bunch of >>>>> BUSY messages. >>>>> >>>>> >>>>> Not sure what your purpose is in sqlrun.c with looping and killing. >>>>> Looks >>>>> pretty squirrely to me. You're not waiting for the forks to finish so >>>>> what is your logic here? >>>>> >>>>> Michael D. Black >>>>> Senior Scientist >>>>> Northrop Grumman Mission Systems >>>>> >>>>> >>>>> ________________________________ >>>>> >>>>> From: sqlite-users-boun...@sqlite.org on behalf of liubin liu >>>>> Sent: Tue 5/11/2010 4:57 AM >>>>> To: sqlite-users@sqlite.org >>>>> Subject: [sqlite] multi processes, so many errores of SQLITE_BUSY and >>>>> SQLITE_MISUSE >>>>> >>>>> ... >>>>> >>>>> -- >>>>> View this message in context: >>>>> http://old.nabble.com/multi-processes%2C-so-many-errores-of-SQLITE_BUSY-and-SQLITE_MISUSE-tp28522127p28522127.html >>>>> Sent from the SQLite mailing list archive at Nabble.com. >>>>> >>>>> _______________________________________________ >>>>> 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 >>>>> >>>>> >>>> >>>> -- >>>> View this message in context: >>>> http://old.nabble.com/multi-processes%2C-so-many-errores-of-SQLITE_BUSY-and-SQLITE_MISUSE-tp28522127p28531394.html >>>> Sent from the SQLite mailing list archive at Nabble.com. >>>> >>>> _______________________________________________ >>>> 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 >>>> >>>> >>> >>> -- >>> View this message in context: >>> http://old.nabble.com/multi-processes%2C-so-many-errores-of-SQLITE_BUSY-and-SQLITE_MISUSE-tp28522127p28544420.html >>> Sent from the SQLite mailing list archive at Nabble.com. >>> >>> _______________________________________________ >>> 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 >>> >>> >> _______________________________________________ >> 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 >> >> > _______________________________________________ > 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 > > _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users