innodb使用的是行锁,原来一直以为InnoDB不是只在最终符合where条件的行上加锁,而是在被扫描过的所有行上加锁.见
http://kabike.iteye.com/blog/1698478
最近看 <<high performance mysql>>,里面提到
引用
InnoDB locks rows only when it accesses them, and an index can reduce the number
of rows InnoDB accesses and therefore locks. However, this works only if InnoDB can
filter out the undesired rows at the storage engine level. If the index doesn’t permit
InnoDB to do that, the MySQL server will have to apply a WHERE clause after InnoDB
retrieves the rows and returns them to the server level. At this point, it’s too late to
avoid locking the rows: InnoDB will already have locked them, and they will remain
locked for some period of time. In MySQL 5.1 and newer, InnoDB can unlock rows
after the server filters them out; in older versions of MySQL, InnoDB doesn’t unlock
the rows until the transaction commits
按这里的说法,innodb可以实现只在最终匹配的row上加锁,而不是扫描的所有行上都有锁.
仔细看了下mysql文档,发现mysql5.1自己官方文档也有好多不清楚的地方,
比如它在
14.6.7.6. Locks Set by Different SQL Statements in InnoDB
里说
引用
For SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE, locks are acquired for scanned rows, and expected to be released for rows that do not qualify for inclusion in the result set (for example, if they do not meet the criteria given in the WHERE clause).
但是这种情况的发生是有条件的,比如其中一个条件就是事务隔离级别是READ COMMITTED
http://dev.mysql.com/doc/refman/5.1/en/set-transaction.html#isolevel_read-committed里说
引用
In MySQL 5.1, if the READ COMMITTED isolation level is used or the innodb_locks_unsafe_for_binlog system variable is enabled, there is no InnoDB gap locking except for foreign-key constraint checking and duplicate-key checking. Also, record locks for nonmatching rows are released after MySQL has evaluated the WHERE condition.
而且行锁的释放不仅仅局限于blocking read(SELECT ... FOR UPDATE 和 SELECT ... LOCK IN SHARE MODE),还包括了update和delete语句
做个试验验证一下
CREATE TABLE `20130312t1` (
`id` int(11) NOT NULL,
`a` int(11) NOT NULL,
`b` int(11) NOT NULL,
`c` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `a` (`a`),
KEY `b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
select * from 20130312t1
1 1 2 1
2 1 1 2
3 2 1 3
update 20130312t1 set c=2 where a=1 and c=1; | |
| update 20130312t1 set c=2 where b=1 and c=3; |
| [Err] 1205 - Lock wait timeout exceeded; try restarting transaction |
delete from 20130312t1 where a=1 and c=1; | |
| delete from 20130312t1 where b=1 and c=3; |
| [Err] 1205 - Lock wait timeout exceeded; try restarting transaction |
select * from 20130312t1 where a=1 and c=1 for UPDATE; | |
| select * from 20130312t1 where b=1 and c=3 for UPDATE; |
| [Err] 1205 - Lock wait timeout exceeded; try restarting transaction |
上面的第二个事务被block住,因为innodb没有把"record locks for nonmatching rows"释放
两个session中分别执行
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
就没有block了,不过如果分别执行
select * from 20130312t1 where a=1 and c=1 for UPDATE;
select * from 20130312t1 where a=1 and c=2 for UPDATE;
还是会block,我想因为它只是release了"record locks for nonmatching rows",而没有释放index上的锁,
这样猜测innodb在index和row上都是有锁的么?
欢迎大家讨论.
分享到:
相关推荐
本文档将介绍MySQL中InnoDB引擎事务隔离级别与锁之间的关系,并结合美团技术团队的经验分享,为大家提供一份详细的教程。 事务隔离级别是数据库事务处理的一个重要概念,它定义了事务与事务之间的隔离程度,主要...
MySQL通过InnoDB存储引擎实现了事务处理,并支持四种隔离级别。可以通过`SET TRANSACTION ISOLATION LEVEL`语句来设置当前会话的事务隔离级别。此外,InnoDB还提供了一些特定的特性,如Next-Key Locks,以帮助解决幻...
接下来,我们通过一个具体的示例来演示不同事务隔离级别下事务与事务之间的影响。假设有一个名为`account`的表,其结构如下: ```sql CREATE TABLE `account` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `VACCOUNT...
MySQL的InnoDB存储引擎默认使用可重复读隔离级别,通过多版本并发控制(MVCC)来实现,以减少锁的竞争,提高并发性能。 然后是锁机制,它是实现不同隔离级别的关键手段: 1. **共享锁(S锁/读锁)**:允许一个事务...
InnoDB默认的隔离级别是可重复读(Repeatable read),在此级别下,InnoDB使用Next-Key Locks来消除幻读,这是一种行锁与间隙锁的组合,不仅锁定查询涉及的具体行,还会锁定索引范围内的空隙,以防止其他事务插入...
【MySQL InnoDB 事务隔离级别详解】 在数据库管理系统中,事务是确保数据一致性的重要机制,而InnoDB存储引擎则是MySQL中支持事务的主要引擎。事务的四大特性,即原子性(Atomicity)、一致性(Consistency)、隔离...
事务的主要功能包括快照读和当前读,前者通过创建ReadView来实现不同隔离级别的查询,后者则会在读取或修改数据时加锁。 InnoDB支持XA事务,这是分布式事务的一种标准,目的是保证跨多个数据库节点的操作一致性。在...
事务隔离级别是控制并发操作时,不同事务对数据可见性的策略。Spring 提供了四种隔离级别: 1. **Isolation.DEFAULT**:使用数据库默认的隔离级别,不同的数据库有不同的默认设置。 2. **Isolation.READ_...
InnoDB存储引擎实现了这四种隔离级别,每种级别通过不同的锁定策略来保障数据的一致性和并发性。 1. 读未提交(Read Uncommitted) 在这个级别下,事务可以读取到其他事务未提交的数据,即存在“读脏”的风险。这...
《深入理解MySQL锁与事务隔离级别》 在数据库管理中,锁和事务隔离级别是确保数据一致性与并发控制的重要概念。本文将详细阐述MySQL中的锁机制以及事务的四种隔离级别,以帮助读者更好地理解和应用这些关键概念。 ...
3. **可重复读(REPEATABLE READ)**:InnoDB的默认隔离级别,防止脏读和不可重复读,但可能出现幻读,即在同一事务中多次执行同样的查询可能会看到不同的行。 4. **串行化(SERIALIZABLE)**:最严格的隔离级别,...
在MySQL的InnoDB存储引擎中,有四种不同的事务隔离级别: 1. **读未提交(READ-UNCOMMITTED)**:在这个级别,一个事务可以读取到其他未提交事务的修改。这意味着脏读是可能的,即一个事务能看到另一个事务未提交的...
而事务对象则存储了事务的ID、XID(事务标识)、所属的ReadView(用于实现隔离级别的快照读)、持有的锁(trx_locks)以及当前等待的锁(wait_lock)。在实现事务时,InnoDB采用了“mini-transaction”(微事务)的...
MySQL数据库的事务隔离级别是数据库管理系统中用于控制事务处理中并发操作的重要机制。在多用户同时访问数据库的情况下,事务隔离级别能够确保数据的一致性和完整性,避免并发操作带来的各种问题,如脏读、不可重复...
如果多个事务相互等待对方释放锁,就会产生死锁。InnoDB通过检测死锁循环来解决死锁问题。 - **自增序列锁(autoinclock):** 用于保护自增列值的生成,确保在多事务环境下自增列值的唯一性。 - **半一致读(semi-...
而在其他隔离级别下,事务1可能会看到事务2的不同状态,取决于隔离级别的设定。 总结来说,MySQL InnoDB的事务和锁机制是数据库管理系统的核心组成部分,它们确保了数据的准确性和一致性,同时处理多用户并发访问的...
MySQL锁和事务、InnoDB架构分析.zipMySQL锁和事务、InnoDB架构分析.zipMySQL锁和事务、InnoDB架构分析.zipMySQL锁和事务、InnoDB架构分析.zipMySQL锁和事务、InnoDB架构分析.zipMySQL锁和事务、InnoDB架构分析....
事务隔离级别是数据库系统用来解决并发控制问题的关键策略,它定义了事务之间的隔离程度,以防止数据不一致的情况发生。以下是对MySQL数据库事务隔离级别的详细解释。 1. **丢失更新**:在并发环境下,一个事务的...