Re: [sqlite] Locking in 3.0.5

2004-09-01 Thread Darren Duncan
At 6:06 PM -0400 9/1/04, D. Richard Hipp wrote:
I fear that your patch has been overcome by events.
A subtle bug has been uncovered in another area
of locking which is going to require reworking large
sections of the commit/rollback logic.  It is very
doubtful that your patch will survive this rework.

I am assuming, then, that the next release of SQLite will also 
officially be beta status, even though the web site says the current 
one is probably the last.  Staying beta is really the only option 
when making such a large change, as I see it.  That is, unless 'beta' 
simply means that the API is not frozen yet. -- Darren Duncan


[sqlite] PATCH Re: [sqlite] Locking in 3.0.5

2004-09-01 Thread Christian Smith
On Wed, 1 Sep 2004, D. Richard Hipp wrote:

>Christian Smith wrote:
>> Created ticket #884, with patch against latest cvs:
>> http://www.sqlite.org/cvstrac/tktview?tn=884
>>
>
>I fear that your patch has been overcome by events.
>A subtle bug has been uncovered in another area
>of locking which is going to require reworking large
>sections of the commit/rollback logic.  It is very
>doubtful that your patch will survive this rework.


No problem. As I said, it was mainly a RFC, for such things as the SQL
syntax. The implementation was broken anyway, just enough to get the
desired semantics in a single session. I was hoping it *wouldn't* go into
the release code as is:)

My patch was mainly at the parser/vdbe level. I've not got in to the
details of the btree code or where I could plug such read only transaction
functionality in, so I hacked it in around the vdbe. Hence my comments
earlier about it being broken.

Could more robust read only transaction support be done as part of this
work? In the meantime, I've attached the final patch I'll do for now, for
people to play with, as well as updated the now closed ticket 884.


>
> 
>

Christian

-- 
/"\
\ /ASCII RIBBON CAMPAIGN - AGAINST HTML MAIL
 X   - AGAINST MS ATTACHMENTS
/ \Index: src/build.c
===
RCS file: /sqlite/sqlite/src/build.c,v
retrieving revision 1.250
diff -c -p -r1.250 build.c
*** src/build.c 31 Aug 2004 13:45:11 -  1.250
--- src/build.c 1 Sep 2004 22:49:59 -
*** void sqlite3FinishCoding(Parse *pParse){
*** 74,81 
int iDb;
sqlite3VdbeChangeP2(v, pParse->cookieGoto-1, sqlite3VdbeCurrentAddr(v));
for(iDb=0, mask=1; iDbnDb; mask<<=1, iDb++){
  if( (mask & pParse->cookieMask)==0 ) continue;
! sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
  sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
}
sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
--- 74,83 
int iDb;
sqlite3VdbeChangeP2(v, pParse->cookieGoto-1, sqlite3VdbeCurrentAddr(v));
for(iDb=0, mask=1; iDbnDb; mask<<=1, iDb++){
+ int wr;
  if( (mask & pParse->cookieMask)==0 ) continue;
! wr = ( (mask & pParse->writeMask)!=0 && 0==db->roTrans );
! sqlite3VdbeAddOp(v, OP_Transaction, iDb, wr);
  sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
}
sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
*** void sqlite3BeginTransaction(Parse *pPar
*** 2418,2423 
--- 2420,2441 
  }
  
  /*
+ ** Begin a read only transaction
+ */
+ void sqlite3BeginReadOnlyTransaction(Parse *pParse){
+   sqlite *db;
+   Vdbe *v;
+ 
+   if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
+   if( pParse->nErr || sqlite3_malloc_failed ) return;
+   if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;
+ 
+   v = sqlite3GetVdbe(pParse);
+   if( !v ) return;
+   sqlite3VdbeAddOp(v, OP_AutoCommit, -1, 0);
+ }
+ 
+ /*
  ** Commit a transaction
  */
  void sqlite3CommitTransaction(Parse *pParse){
Index: src/parse.y
===
RCS file: /sqlite/sqlite/src/parse.y,v
retrieving revision 1.135
diff -c -p -r1.135 parse.y
*** src/parse.y 25 Aug 2004 04:07:02 -  1.135
--- src/parse.y 1 Sep 2004 22:49:59 -
*** explain ::= .   { sqlite3BeginPa
*** 82,87 
--- 82,88 
  //
  
  cmd ::= BEGIN trans_opt.  {sqlite3BeginTransaction(pParse);}
+ cmd ::= BEGIN trans_opt FOR READ ONLY.  {sqlite3BeginReadOnlyTransaction(pParse);}
  trans_opt ::= .
  trans_opt ::= TRANSACTION.
  trans_opt ::= TRANSACTION nm.
Index: src/sqliteInt.h
===
RCS file: /sqlite/sqlite/src/sqliteInt.h,v
retrieving revision 1.318
diff -c -p -r1.318 sqliteInt.h
*** src/sqliteInt.h 1 Sep 2004 03:06:35 -   1.318
--- src/sqliteInt.h 1 Sep 2004 22:49:59 -
*** struct sqlite {
*** 389,394 
--- 389,395 
int errCode;  /* Most recent error code (SQLITE_*) */
u8 enc;   /* Text encoding for this database. */
u8 autoCommit;/* The auto-commit flag. */
+   u8 roTrans;   /* Read-only transaction in progress */
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
void *pCollNeededArg;
*** void sqlite3Randomness(int, void*);
*** 1283,1288 
--- 1284,1290 
  void sqlite3RollbackAll(sqlite*);
  void sqlite3CodeVerifySchema(Parse*, int);
  void sqlite3BeginTransaction(Parse*);
+ void sqlite3BeginReadOnlyTransaction(Parse*);
  void sqlite3CommitTransaction(Parse*);
  void sqlite3RollbackTransaction(Parse*);
  int 

Re: [sqlite] Locking in 3.0.5

2004-09-01 Thread Christian Smith
Created ticket #884, with patch against latest cvs:
http://www.sqlite.org/cvstrac/tktview?tn=884

Minimal testing done, tested only within sqlite3 shell on Linux. A bit of
a hack. Mainly a RFC.

Quick transcript:

[EMAIL PROTECTED] sqlite]$ ./sqlite3 db
SQLite version 3.0.5
Enter ".help" for instructions
sqlite> begin for read only;
sqlite> create table t (a,b);
SQL error: access permission denied
sqlite> commit;
sqlite> begin ;
sqlite> create table t (a,b);
sqlite> insert into t values (1,2);
sqlite> commit;
sqlite> .dump
BEGIN TRANSACTION;
CREATE TABLE t (a,b);
INSERT INTO "t" VALUES(1, 2);
COMMIT;
sqlite>

Already found first bug:( "DELETE FROM ;" doesn't use OpenWrite,
which I updated to enforce the read only nature of a transaction. I'll
need to update OP_Clear and OP_Destroy as well. This could get messy
quickly, hence the implementation is considered a hack:)

Copyright disclaimed, etc.

Christian

On Wed, 1 Sep 2004, Christian Smith wrote:

>OK, how about this suggestion.
>
>Add a new "BEGIN [TRANSACTION] FOR READONLY" statement, which begins the
>transaction with a read lock only and doesn't allow the transaction to
>even try to promote to a write lock.
>
>Then, the default behaviour for (default) non-readonly transactions is the
>same as 2.8.x, ie. only one writer. The second thread beginning a new
>writeable transaction blocks immediately. The benefits of concurrent
>readers will not be lost if using auto-transactions or the new read-only
>transactions.
>
>No rollback. Consistent busy behaviour. Job's a good'un.
>
>Christian
>
>On Wed, 1 Sep 2004, Miguel Angel Latorre wrote:
>
>>I agree.
>>Applications shouldn't worry about locking and timeouts. That would be the
>>job for the db core engine, returning as few (none ideally) busy status code
>>as possible.
>>
>>Also, it is not always possible to decide which thread is better to rollback
>>since no info is provided about the status of what it is performing (commit,
>>update, etc).
>>
>>----- Original Message -
>>From: "Rob Groves" <[EMAIL PROTECTED]>
>>To: <[EMAIL PROTECTED]>
>>Sent: Wednesday, September 01, 2004 12:34 AM
>>Subject: RE: [sqlite] Locking in 3.0.5
>>
>>
>>> >>So, Rob, are you go to tell us if you think the change
>>> >>is an improvement or not?
>>>
>>> It seems that with either of the new schemes, when using
>>> sqlite3_busy_timeout() one thread is going to timeout sooner
>>> or later. That being the case I prefer the new version on
>>> efficiency grounds.
>>>
>>> Being a lazy programmer, I like the behaviour of 2.8.15
>>> where both threads can get to complete their update, timeouts
>>> allowing. This is behaviour that I am also used to with
>>> MS SQL Server.
>>>
>>> I agree with you that many programmers (myself included)
>>> don't want to have to worry about this stuff too much
>>> when using SQLite.
>>>
>>> Rob.
>>>
>>
>
>

-- 
/"\
\ /ASCII RIBBON CAMPAIGN - AGAINST HTML MAIL
 X   - AGAINST MS ATTACHMENTS
/ \


Re: [sqlite] Locking in 3.0.5

2004-09-01 Thread Christian Smith
On Wed, 1 Sep 2004, Matt Wilson wrote:

>On Wed, Sep 01, 2004 at 02:46:39PM +0100, Christian Smith wrote:
>>
>> Add a new "BEGIN [TRANSACTION] FOR READONLY" statement, which begins the
>> transaction with a read lock only and doesn't allow the transaction to
>> even try to promote to a write lock.
>
>Why do you need a transaction at all if you're not going to commit?
>
>In my code, readers never use BEGIN, only writers do.


A transaction gives you a snapshot in time of the database. You may need
to do more than one query, and require a consistent snapshot for the
duration of the multiple queries.


>
>Cheers,
>
>Matt
>

-- 
/"\
\ /ASCII RIBBON CAMPAIGN - AGAINST HTML MAIL
 X   - AGAINST MS ATTACHMENTS
/ \


Re: [sqlite] Locking in 3.0.5

2004-09-01 Thread Christian Smith
OK, how about this suggestion.

Add a new "BEGIN [TRANSACTION] FOR READONLY" statement, which begins the
transaction with a read lock only and doesn't allow the transaction to
even try to promote to a write lock.

Then, the default behaviour for (default) non-readonly transactions is the
same as 2.8.x, ie. only one writer. The second thread beginning a new
writeable transaction blocks immediately. The benefits of concurrent
readers will not be lost if using auto-transactions or the new read-only
transactions.

No rollback. Consistent busy behaviour. Job's a good'un.

Christian

On Wed, 1 Sep 2004, Miguel Angel Latorre wrote:

>I agree.
>Applications shouldn't worry about locking and timeouts. That would be the
>job for the db core engine, returning as few (none ideally) busy status code
>as possible.
>
>Also, it is not always possible to decide which thread is better to rollback
>since no info is provided about the status of what it is performing (commit,
>update, etc).
>
>- Original Message -
>From: "Rob Groves" <[EMAIL PROTECTED]>
>To: <[EMAIL PROTECTED]>
>Sent: Wednesday, September 01, 2004 12:34 AM
>Subject: RE: [sqlite] Locking in 3.0.5
>
>
>> >>So, Rob, are you go to tell us if you think the change
>> >>is an improvement or not?
>>
>> It seems that with either of the new schemes, when using
>> sqlite3_busy_timeout() one thread is going to timeout sooner
>> or later. That being the case I prefer the new version on
>> efficiency grounds.
>>
>> Being a lazy programmer, I like the behaviour of 2.8.15
>> where both threads can get to complete their update, timeouts
>> allowing. This is behaviour that I am also used to with
>> MS SQL Server.
>>
>> I agree with you that many programmers (myself included)
>> don't want to have to worry about this stuff too much
>> when using SQLite.
>>
>> Rob.
>>
>

-- 
/"\
\ /ASCII RIBBON CAMPAIGN - AGAINST HTML MAIL
 X   - AGAINST MS ATTACHMENTS
/ \


Re: [sqlite] Locking in 3.0.5

2004-09-01 Thread Miguel Angel Latorre
I agree.
Applications shouldn't worry about locking and timeouts. That would be the
job for the db core engine, returning as few (none ideally) busy status code
as possible.

Also, it is not always possible to decide which thread is better to rollback
since no info is provided about the status of what it is performing (commit,
update, etc).

- Original Message - 
From: "Rob Groves" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Wednesday, September 01, 2004 12:34 AM
Subject: RE: [sqlite] Locking in 3.0.5


> >>So, Rob, are you go to tell us if you think the change
> >>is an improvement or not?
>
> It seems that with either of the new schemes, when using
> sqlite3_busy_timeout() one thread is going to timeout sooner
> or later. That being the case I prefer the new version on
> efficiency grounds.
>
> Being a lazy programmer, I like the behaviour of 2.8.15
> where both threads can get to complete their update, timeouts
> allowing. This is behaviour that I am also used to with
> MS SQL Server.
>
> I agree with you that many programmers (myself included)
> don't want to have to worry about this stuff too much
> when using SQLite.
>
> Rob.
>



RE: [sqlite] Locking in 3.0.5

2004-08-31 Thread Rob Groves
>>So, Rob, are you go to tell us if you think the change
>>is an improvement or not?

It seems that with either of the new schemes, when using
sqlite3_busy_timeout() one thread is going to timeout sooner
or later. That being the case I prefer the new version on
efficiency grounds.

Being a lazy programmer, I like the behaviour of 2.8.15
where both threads can get to complete their update, timeouts
allowing. This is behaviour that I am also used to with
MS SQL Server.

I agree with you that many programmers (myself included)
don't want to have to worry about this stuff too much
when using SQLite.

Rob.



Re: [sqlite] Locking in 3.0.5

2004-08-31 Thread D. Richard Hipp
Rob Groves wrote:
I have just read the archive mailing list from 16/08/2004,
and it looks like this behaviour is on purpose (checkin 1879).
So, Rob, are you go to tell us if you think the change
is an improvement or not?
--
D. Richard Hipp -- [EMAIL PROTECTED] -- 704.948.4565


RE: [sqlite] Locking in 3.0.5

2004-08-31 Thread Rob Groves
I have just read the archive mailing list from 16/08/2004,
and it looks like this behaviour is on purpose (checkin 1879).

My mistake,

Rob.

-Original Message-
From: Rob Groves [mailto:[EMAIL PROTECTED]
Sent: 31 August 2004 22:17
To: [EMAIL PROTECTED]
Subject: [sqlite] Locking in 3.0.5


Hi,

I have observed different behaviour between 3.0.3 and 3.0.5. I didn't
download 3.0.4 so can't comment on that.

I am using two threads and setting a busy timeout on each with
sqlite3_busy_timeout().

In 3.0.3 two threads trying to update the same row(s) would both retry until
the one with the shortest busy timeout
expired, and SQLITE_BUSY is returned.

In 3.0.5, the 2nd thread trying to obtain the lock returns SQLITE_BUSY
immediately.

Any ideas?

Rob.