Re: [sqlite] Database is locked error

2010-02-22 Thread Trainor, Chris
Thanks for the response Pavel.  The order that the events were getting
logged wasn't accurate enough so I increased the timing precision for my
logging.  I didn't leave anything out, but some commands were logged
slightly out of order.

 

Thread1 is doing reads and writes for a while, with Thread2 attempting
to insert.  Thread2 ends up in the BusyHandler for a while and then the
following occurs in this order:

 

Thread  Command   LockStep

1  RELEASE SAVEPOINT Thread1None1

2  INSERT INTO TableA
Exclusive   2

2  RELEASE SAVEPOINT Thread2None3

2  SAVEPOINT Thread2  None
4

2  INSERT INTO TableA
Exclusive   5

1  SAVEPOINT Thread1 None
6

2  RELEASE SAVEPOINT Thread2None7

1  SELECT FROM TableA
Shared  8

2  SAVEPOINT Thread2  None
9

1  SELECT FROM TableB
Shared  10

2  INSERT INTO TableA
Reserved? 11

1  INSERT INTO TableB
*   12

  

 

Step 1 - The transaction is closed on thread1, so it no longer has a
lock.

Step 2 - This is the insert that was failing, with Thread2 ending up in
the busyhandler.  When thread2 first tried to insert, it obtained a
reserved lock.  Now that thread1 released its lock, thread2 gets an
exclusive lock and the insert finally succeeds at this point.

 

I think what is going wrong is this:

Step 11 - Thread2 tries to do an insert.  Since Thread1 has a shared
lock, thread2 acquires a reserved lock but it cannot be promoted to
Exclusive.

Step 12 - BusyHandler is not called.  Database is locked error is
returned.  Thread1's shared lock cannot be promoted to a reserved lock,
since Thread2 already has one.

 

Does that seem correct?

 

If so, my options are:

1)  rollback/commit one of the transactions

2)  use begin exclusive

 

I don't think the second one will work, since I need nested transactions
and the savepoint syntax doesn't seem to support the exclusive option.

 

Thanks,

Chris

 



The information contained in this email message and its attachments
is intended
only for the private and confidential use of the recipient(s) named
above, unless the sender expressly agrees otherwise. Transmission
of email over the Internet
 is not a secure communications medium. If you are requesting or
have requested
the transmittal of personal data, as defined in applicable privacy
laws by means
 of email or in an attachment to email you must select a more
secure alternate means of transmittal that supports your
obligations to protect such personal data. If the reader of this
message is not the intended recipient and/or you have received this
email in error, you must take no action based on the information in
this email and you are hereby notified that any dissemination,
misuse, copying, or disclosure of this communication is strictly
prohibited. If you have received
this communication in error, please notify us immediately by email
and delete the original message.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Database is locked error

2010-02-19 Thread Trainor, Chris
I am running into a database is locked error and I don't quite
understand what is going on. If someone could explain what is happening,
I'd appreciate it.  (I am using sqlite version 3.6.17 on Windows XP.)

A busy handler callback has been set up with sqlite3_busy_handler().  In
addition to some logging, the callback simply checks the number of
retries and either gives up (by returning 0) if it reaches the max retry
count or sleeps for 50 msecs then returns 1.

I have two threads (each with their own connection) that are trying to
access the database.  The 1st thread is doing some reads and writes and
the other one is just writing.  For a while, things work as expected.
Thread1 does some reads and writes within explicit transactions (using
Savepoint and Release Savepoint syntax).  Thread2 attempts to write to
the database and can't, so the busyhandler callback is called.
Eventually, Thread2 is able to get the exclusive lock and write to the
database (again within an explicit transaction).  Thread1 does some more
reads and writes, etc.

Here's where it stops making sense.  I'm paraphrasing what is logged out
by our app.  The first column is the number of msecs since the process
started.  The second obviously is the active thread.  3rd is the query
(simplified for easy reading).  The 4th indicates success or failure.
The 5th contains notes as to what appears to be happening.


13875   Thread2 SAVEPOINT Thread2   success
(No locks acquired)
13875   Thread1 SAVEPOINT Thread1   success
(No locks acquired)
13880   Thread2 INSERT INTO TableB  success
(exclusive lock)
13890   Thread2 RELEASE SAVEPOINT Thread2   fail
(the busyhandler callback is called here)
13890   Thread1 SELECT blah FROM TableB success
(shared lock???)
13906   Thread1 SELECT blah FROM TableC success
(shared lock???)
13906   Thread1 INSERT INTO TableD  fail
(busyhandler is NOT called - database is locked)

The call to sqlite3_step succeeds for the query INSERT INTO TableB at
13880 msecs.  I believe this means that an exclusive lock must have been
obtained for the connection on thread2.  Thread2 attempts to release the
savepoint right around the same time as thread1 attempts to read from
TableB (at 13890 msecs).  Thread1 is able to read from TableB, then is
able to read from TableC.  This seems to indicate that the connection on
thread1 acquired a shared lock.  I don't see how this is possible, since
thread2 should have had an exclusive lock at that point.  I am assuming
that sqlite thinks that a deadlock will occur when thread1 tries to
write to the database at 13906 msecs and that is why the busyhandler
callback is not invoked.

Also I'm not sure if it matters, but I am using sqlite3_exec to execute
the SAVEPOINT and RELEASE SAVEPOINT statements.  All other queries are
executed using prepared statements and calls to sqlite3_step.  Note that
there are NO nested transactions created.

Can anyone shed some light on this?

Thanks,
Chris
The information contained in this email message and its attachments
is intended
only for the private and confidential use of the recipient(s) named
above, unless the sender expressly agrees otherwise. Transmission
of email over the Internet
 is not a secure communications medium. If you are requesting or
have requested
the transmittal of personal data, as defined in applicable privacy
laws by means
 of email or in an attachment to email you must select a more
secure alternate means of transmittal that supports your
obligations to protect such personal data. If the reader of this
message is not the intended recipient and/or you have received this
email in error, you must take no action based on the information in
this email and you are hereby notified that any dissemination,
misuse, copying, or disclosure of this communication is strictly
prohibited. If you have received
this communication in error, please notify us immediately by email
and delete the original message.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Slow performance with Sum function

2009-03-11 Thread Trainor, Chris
 Do not be tempted by the incremental vacuum feature.  Incremental  
 vacuum will reduce the database size as content is deleted, but it  
 will not reduce fragmentation.  In fact, incremental vacuum will  
 likely increase fragmentation.  Incremental vacuum is just a variation

 on auto_vacuum.  It is designed for flash memory with zero seek
latency.

 D. Richard Hipp
 d...@hwaci.com

Thanks for the reply, but I am confused again.  Is incremental vacuum
different from the vacuum command?  It seems like vacuum would
defragment the database according to the description here:
http://www.sqlite.org/lang_vacuum.html 

The VACUUM command cleans the main database by copying its contents to
a temporary database file and reloading the original database file from
the copy. This eliminates free pages, aligns table data to be
contiguous, and otherwise cleans up the database file structure.

If incremental vacuum and vacuum are the same, then I am still uncertain
of what to do about my original problem.  Any ideas on why the sum
function is slow on my existing table, but it is fast on a copy of the
table?  Also, after calling vacuum, sum is fast on the original table.

Here's my original question:

I am trying to use the Sum function on a column in a table with ~450K
rows in it.  

Select sum(Col4) from Table1

Where Table1 looks like this:

Create TABLE Table1 (
Col1 INTEGER NOT NULL,
Col2 INTEGER NOT NULL,
Col3 INTEGER NOT NULL,
Col4 BIGINT NOT NULL,
Col5 BIGINT NOT NULL,
Col6 BLOB NOT NULL,
Col7 CHAR(1) DEFAULT '0',
Col8 NUMERIC(2) NOT NULL,
Col9 NUMERIC(2) NOT NULL,
Col10 INTEGER NOT NULL,
Col11 INTEGER NOT NULL,
CONSTRAINT FK_1 FOREIGN KEY (Col1) REFERENCES Table2 (Col1)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT PK_1 PRIMARY KEY (Col10, Col11, Col1, Col3 DESC) );


It takes over 2 minutes to execute when using the original table.  I
created an exact copy of the table with the same indices and constraints
and inserted all the data from the original table into it.  Summing that
column on the copied table only takes a few seconds.

I am guessing that using the copied table is faster because it has all
of its data arranged contiguously, but that is just a guess.

Can anyone shed some light on this?  Making a copy of the table is not
an option, so is there anything I can do to get better performance from
the original table?

Thanks
The information contained in this email message and its attachments
is intended
only for the private and confidential use of the recipient(s) named
above, unless the sender expressly agrees otherwise. Transmission
of email over the Internet
 is not a secure communications medium. If you are requesting or
have requested
the transmittal of personal data, as defined in applicable privacy
laws by means
 of email or in an attachment to email you must select a more
secure alternate means of transmittal that supports your
obligations to protect such personal data. If the reader of this
message is not the intended recipient and/or you have received this
email in error, you must take no action based on the information in
this email and you are hereby notified that any dissemination,
misuse, copying, or disclosure of this communication is strictly
prohibited. If you have received
this communication in error, please notify us immediately by email
and delete the original message.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Slow performance with Sum function

2009-03-03 Thread Trainor, Chris
I am trying to use the Sum function on a column in a table with ~450K
rows in it.  

Select sum(Col4) from Table1

Where Table1 looks like this:

Create TABLE Table1 (
Col1 INTEGER NOT NULL,
Col2 INTEGER NOT NULL,
Col3 INTEGER NOT NULL,
Col4 BIGINT NOT NULL,
Col5 BIGINT NOT NULL,
Col6 BLOB NOT NULL,
Col7 CHAR(1) DEFAULT '0',
Col8 NUMERIC(2) NOT NULL,
Col9 NUMERIC(2) NOT NULL,
Col10 INTEGER NOT NULL,
Col11 INTEGER NOT NULL,
CONSTRAINT FK_1 FOREIGN KEY (Col1) REFERENCES Table2 (Col1)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT PK_1 PRIMARY KEY (Col10, Col11, Col1, Col3 DESC)
);


It takes over 2 minutes to execute when using the original table.  I
created an exact copy of the table with the same indices and constraints
and inserted all the data from the original table into it.  Summing that
column on the copied table only takes a few seconds.

I am guessing that using the copied table is faster because it has all
of its data arranged contiguously, but that is just a guess.

Can anyone shed some light on this?  Making a copy of the table is not
an option, so is there anything I can do to get better performance from
the original table?

Thanks
The information contained in this email message and its attachments
is intended
only for the private and confidential use of the recipient(s) named
above, unless the sender expressly agrees otherwise. Transmission
of email over the Internet
 is not a secure communications medium. If you are requesting or
have requested
the transmittal of personal data, as defined in applicable privacy
laws by means
 of email or in an attachment to email you must select a more
secure alternate means of transmittal that supports your
obligations to protect such personal data. If the reader of this
message is not the intended recipient and/or you have received this
email in error, you must take no action based on the information in
this email and you are hereby notified that any dissemination,
misuse, copying, or disclosure of this communication is strictly
prohibited. If you have received
this communication in error, please notify us immediately by email
and delete the original message.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Slow performance with Sum function

2009-03-03 Thread Trainor, Chris
After running vacuum, sum is fast on the original table.  However,
running vacuum took a long time, so I'm not sure if that is a feasible
solution.  Is there any way to prevent fragmentation in the first place?
If not for the whole database, then for a specific table?  (e.g. is it
possible to preallocate space for a table?)

Thanks

-Original Message-
From: sqlite-users-boun...@sqlite.org
[mailto:sqlite-users-boun...@sqlite.org] On Behalf Of Igor Tandetnik
Sent: Tuesday, March 03, 2009 2:00 PM
To: sqlite-users@sqlite.org
Subject: Re: [sqlite] Slow performance with Sum function

Trainor, Chris chris.trai...@ironmountain.com
wrote:
 I am trying to use the Sum function on a column in a table with ~450K
 rows in it.

 Select sum(Col4) from Table1

 It takes over 2 minutes to execute when using the original table.  I
 created an exact copy of the table with the same indices and
 constraints and inserted all the data from the original table into
 it.  Summing that column on the copied table only takes a few seconds.

Try running VACUUM on your database. Your original table is probably 
badly fragmented and results in excessive disk seeking.

Igor Tandetnik 



___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
The information contained in this email message and its attachments
is intended
only for the private and confidential use of the recipient(s) named
above, unless the sender expressly agrees otherwise. Transmission
of email over the Internet
 is not a secure communications medium. If you are requesting or
have requested
the transmittal of personal data, as defined in applicable privacy
laws by means
 of email or in an attachment to email you must select a more
secure alternate means of transmittal that supports your
obligations to protect such personal data. If the reader of this
message is not the intended recipient and/or you have received this
email in error, you must take no action based on the information in
this email and you are hereby notified that any dissemination,
misuse, copying, or disclosure of this communication is strictly
prohibited. If you have received
this communication in error, please notify us immediately by email
and delete the original message.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Slow performance with Sum function

2009-03-03 Thread Trainor, Chris
I'm not sure how much we can do about preventing adds and deletes.  It *may* be 
possible to replace them with updates, but I am not sure yet.  These adds and 
deletes are happening in a different table than the one being summed.  This 
other table contains a large blob column.  Would changing to updates help or 
will updates fragment the database as much as adds and deletes?

The second option is the one I am considering.  It looks like there might be a 
good time to run vacuum.  I need to do some more timings to tell for sure.

Thanks for the suggestions.

 
-Original Message-
From: sqlite-users-boun...@sqlite.org [mailto:sqlite-users-boun...@sqlite.org] 
On Behalf Of P Kishor
Sent: Tuesday, March 03, 2009 7:41 PM
To: General Discussion of SQLite Database
Subject: Re: [sqlite] Slow performance with Sum function

On Tue, Mar 3, 2009 at 6:36 PM, Greg Palmer gregorylpal...@netscape.net wrote:
 Trainor, Chris wrote:
 After running vacuum, sum is fast on the original table.  However,
 running vacuum took a long time, so I'm not sure if that is a feasible
 solution.  Is there any way to prevent fragmentation in the first place?
 If not for the whole database, then for a specific table?  (e.g. is it
 possible to preallocate space for a table?)

 Thanks

 I'm not an expert on SQLite but generally speaking fragmentation in a
 database is usually a result of records being added and deleted. Are you
 doing a lot of these and if so, can you change your algorithm to cut
 down on this activity?

exactly the right approach. Even better, make your application do the
vaccuming when your users are away, much like housekeeping in a hotel.




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




-- 
Puneet Kishor http://www.punkish.org/
Nelson Institute for Environmental Studies http://www.nelson.wisc.edu/
Carbon Model http://carbonmodel.org/
Open Source Geospatial Foundation http://www.osgeo.org/
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
The information contained in this email message and its attachments
is intended
only for the private and confidential use of the recipient(s) named
above, unless the sender expressly agrees otherwise. Transmission
of email over the Internet
 is not a secure communications medium. If you are requesting or
have requested
the transmittal of personal data, as defined in applicable privacy
laws by means
 of email or in an attachment to email you must select a more
secure alternate means of transmittal that supports your
obligations to protect such personal data. If the reader of this
message is not the intended recipient and/or you have received this
email in error, you must take no action based on the information in
this email and you are hereby notified that any dissemination,
misuse, copying, or disclosure of this communication is strictly
prohibited. If you have received
this communication in error, please notify us immediately by email
and delete the original message.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Slow performance with Sum function

2009-03-03 Thread Trainor, Chris
The blob is fairly small but is referenced very often, so it wouldn't be
feasible to move it to another table.  Does the blob make a difference
in this case?  I thought that since the blob column is to the right of
the column being summed that it would never get read during the
summation.

Thanks

-Original Message-
From: sqlite-users-boun...@sqlite.org
[mailto:sqlite-users-boun...@sqlite.org] On Behalf Of John Machin
Sent: Tuesday, March 03, 2009 7:53 PM
To: General Discussion of SQLite Database
Subject: Re: [sqlite] Slow performance with Sum function

On 4/03/2009 5:52 AM, Trainor, Chris wrote:
 I am trying to use the Sum function on a column in a table with ~450K
 rows in it.  
 
   Select sum(Col4) from Table1
 
 Where Table1 looks like this:
 
 Create TABLE Table1 (
   Col1 INTEGER NOT NULL,
   Col2 INTEGER NOT NULL,
   Col3 INTEGER NOT NULL,
   Col4 BIGINT NOT NULL,
   Col5 BIGINT NOT NULL,
   Col6 BLOB NOT NULL,

What is the min/max/average size of this blob and how often do you need 
to access it? If the answer tends towards huge and rarely, consider 
putting it in a separate table.


   Col7 CHAR(1) DEFAULT '0',
   Col8 NUMERIC(2) NOT NULL,
   Col9 NUMERIC(2) NOT NULL,
   Col10 INTEGER NOT NULL,
 Col11 INTEGER NOT NULL,
   CONSTRAINT FK_1 FOREIGN KEY (Col1) REFERENCES Table2 (Col1)
   ON DELETE CASCADE
   ON UPDATE CASCADE,
   CONSTRAINT PK_1 PRIMARY KEY (Col10, Col11, Col1, Col3 DESC)
 );
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
The information contained in this email message and its attachments
is intended
only for the private and confidential use of the recipient(s) named
above, unless the sender expressly agrees otherwise. Transmission
of email over the Internet
 is not a secure communications medium. If you are requesting or
have requested
the transmittal of personal data, as defined in applicable privacy
laws by means
 of email or in an attachment to email you must select a more
secure alternate means of transmittal that supports your
obligations to protect such personal data. If the reader of this
message is not the intended recipient and/or you have received this
email in error, you must take no action based on the information in
this email and you are hereby notified that any dissemination,
misuse, copying, or disclosure of this communication is strictly
prohibited. If you have received
this communication in error, please notify us immediately by email
and delete the original message.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users