Hello Heikki,

Thank you for your reply and your explanation.  It clarifies things and explains some 
of the
unexpected behavior I've observed (such as my own inability to insert to the gap after 
locking it).

In general, is there a place where I can find a good discussion on the various locks 
used by InnoDB?
I've seen references to various locks in InnoDB status output, but wasn't sure what 
each kind was
(S-locks, X-locks, etc.).  This would be a great aid for helping troubleshoot these 
kinds of
problems.

Thank you for your time,

Alex Zeltser

============================================================

List: MySQL General Discussion < Previous MessageNext Message > 
From: Heikki Tuuri Date: January 21 2004 4:32am 
Subject: Re: InnoDB locking 'non-existence' of a row

Alex,

diagram:

record1 'gap' record2
(User A holds a next-key lock on record2)

InnoDB can lock the non-existence of a row in the 'gap'. But it cannot
presently make another user B to wait before B acquires a lock on the gap.
The reason is that B's cursor has already passed the gap when B ends up
waiting for a next-key lock on record2. If we would allow user A to insert
to the gap, then the cursor of B should be moved backwards, so that B's
cursor would see the inserted record when A commits. Currently, InnoDB does
not move a cursor backwards when a lock wait ends.

Locks on gaps are purely inhibitive. That is, you can prevent other users
from inserting to the gap, but you cannot guarantee that you yourself will
be able to insert. In the general case, we cannot prevent 2 users acquiring
conflicting locks on the same gap:

gap1 delete_marked_record gap2

If A holds an X-lock on gap1 and B holds an X-lock on gap2, and purge
removes the delete_marked_record, then the gaps merge, and both A and B hold
an X-lock on the gap.

Best regards,

Heikki Tuuri
Innobase Oy
http://www.innodb.com
Foreign keys, transactions, and row level locking for MySQL
InnoDB Hot Backup - a hot backup tool for InnoDB which also backs up MyISAM
tables

Order MySQL technical support from https://order.mysql.com/


----- Original Message ----- 
From: ""Zeltser, Alex"" <[EMAIL PROTECTED]>
Newsgroups: mailing.database.myodbc
Sent: Tuesday, January 20, 2004 9:20 PM
Subject: RE: InnoDB locking 'non-existence' of a row


> Hi Joe,
>
> Thanks for your reply.  Actually, in my experience (and according to the =
> docs), if you select 'for
> update' or 'lock in share mode', you _can_ lock non-existence of a row =
> for inserts.  In that case I
> think the 'gap' where the row would be is locked, and attempts to insert =
> the row from another
> transaction will block or fail (until the first one does a commit or a =
> rollback).  Perhaps I'm
> misunderstanding what's happening?
>
> Unfortunately, what I'm trying to do is try to have one transaction =
> 'lock' the non-existence of a
> row with a select, and another wait until the lock is released--also =
> with a select.  I've considered
> doing what you propose with a separate lock table, and may still do just =
> that, but first wanted to
> see if I can accomplish the same thing with some clever DB manipulation.
>
> Thanks!
>
> Alex
>
> -----Original Message-----
> From: Joe Shear [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, January 20, 2004 11:00 AM
> To: Zeltser, Alex
> Cc: [EMAIL PROTECTED]
> Subject: RE: InnoDB locking 'non-existence' of a row
>
>
> hi,=20
> Selecting a non-existent row won't acquire any locks that prevents =
> inserts from happening.  One way
> to accomplish what you want is to create a separate insert lock table =
> consisting of a table name and
> a lock counter.  Add a row for each table that you want to have these =
> insert locks on, and before
> performing any inserts, either update the corresponding row in the =
> insert lock table or select it
> for an update.=20
>
> joe
>
> On Tue, 2004-01-20 at 10:01, Zeltser, Alex wrote:
> > Hi Chris,
> >=20
> > Thanks for the response and the suggestions.  Doesn't SERIALIZABLE=20
> > level just add 'LOCK IN SHARE MODE' to your SELECTs, but other than=20
> > that works just like the default REPEATABLE READ level?  I've tried by =
>
> > example below using 'LOCK IN SHARE MODE' instead of 'FOR UPDATE', but=20
> > the results were the same.
> >=20
> > Is there any way to make the second session block when both it and the =
>
> > first one are 'locking' non-existence of a row?
> >=20
> > Thanks in advance,
> >=20
> > Alex
> >=20
> > -----Original Message-----
> > From: Chris Nolan [mailto:[EMAIL PROTECTED]
> > Sent: Friday, January 16, 2004 4:55 PM
> > To: Zeltser, Alex
> > Cc: [EMAIL PROTECTED]
> > Subject: Re: InnoDB locking 'non-existence' of a row
> >=20
> >=20
> > Hi Alex!
> >=20
> > On Sat, 2004-01-17 at 05:50, Zeltser, Alex wrote:
> > > Hi,
> > >=20
> > > I wanted to take advantage of the InnoDB 'gap' locking to lock
> > > 'non-existence' of a row, the way the manual recommends.  I tried to =
>
> > > do this by using 'select ... for update', using the 'mysql' client=20
> > > from two separate sessions as shown below:
> > >=20
> > > Session 1:
> > > > set AUTOCOMMIT=3D0;
> > > > begin;
> > > > select * from T where A =3D 'NOT_THERE' for update;
> > >=20
> > > Session 2:
> > > > set AUTOCOMMIT=3D0;
> > > > begin;
> > > > select * from T where A =3D 'NOT_THERE' for update;
> > >=20
> > > What I'd hoped to see was the 'select' statement in Session 2 block
> > > until either a commit or a rollback was performed in Session 1. =20
> > > Unfortunately, it didn't work that way.  The 'select's in both=20
> > > sessions returned right away, and it was only the subsequent=20
> > > 'insert's, 'update's and 'delete's that blocked.  I can understand =
> the=20
> > > rationale behind this behavior, but unfortunately it doesn't help me =
>
> > > with my problem.  I'd like to be able to reliably check for =
> existence=20
> > > of a record from two concurrent sessions and have the 'select' in =
> the=20
> > > 'second' session block until the first session is either committed =
> or=20
> > > rolled back.  Is there a way to accomplish this somehow?
> > >=20
> > InnoDB's next-key locking is a bit different to this - it ensures that =
>
> > phantom rows do not appear. This is good for application writers and=20
> > for MySQL itself, as phantom rows appearing would break MySQL's=20
> > replication.
> >=20
> > Basically, InnoDB will place locks on the various index structures=20
> > involved in your query around the rows that have been returned bt a=20
> > SELECT ... FOR UPDATE. As your selects return nothing, InnoDB doesn't=20
> > find any index sections to place any locks on.
> >=20
> > Perhaps you should look at using the SERIALIZABLE level of transaction =
>
> > isolation.
> >=20
> > Regards,
> >=20
> > Chris
> >=20
> > > I know I can just try to insert the record and check for duplicates,
> > > but is there a way to accomplish it with 'select's?
> > >=20
> > > Thanks in advance,
> > >=20
> > > Alex Zeltser
> > >=20
> > > --
> > > MySQL General Mailing List
> > > For list archives: http://lists.mysql.com/mysql
> > > To unsubscribe:    =
> http://lists.mysql.com/mysql?unsub=1
> > >=20
> --=20
> Joe Shear <[EMAIL PROTECTED]>
>
>
> -- 
> MySQL General Mailing List
> For list archives: http://lists.mysql.com/mysql
> To unsubscribe:
http://lists.mysql.com/mysql?unsub=1
>


Thread
InnoDB locking 'non-existence' of a row - Zeltser, Alex, January 16 2004 8:06pm
Re: InnoDB locking 'non-existence' of a row - Chris Nolan, January 17 2004 1:55am
RE: InnoDB locking 'non-existence' of a row - Zeltser, Alex, January 20 2004 7:03pm
RE: InnoDB locking 'non-existence' of a row - Joe Shear, January 20 2004 8:03pm
RE: InnoDB locking 'non-existence' of a row - Zeltser, Alex, January 20 2004 8:20pm
Re: InnoDB locking 'non-existence' of a row - Heikki Tuuri, January 21 2004 4:32am
If you are having problems unsubscribing from the list, please check our 
troubleshooting page. 
 Copyright (c) 2003 MySQL AB. All rights reserved. 

--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:    http://lists.mysql.com/[EMAIL PROTECTED]

Reply via email to