大家都知道Innodb采用的是行级锁机制,因此,很多人在编写程序时往往会忽视它的表锁,从而导致系统性能低下。要不掉进Innodb行级锁的陷阱,只需简单记住“Innodb行级锁只对Where条件为主键时有效,其他非主键时全都为表锁”即可。为了更好的感知这一过程,你也可以按照下面测试步骤测试下。
测试数据:
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`role` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
)ENGINE=InnoDB;
+----+--------+------------------+------+
| id | name | email | role |
+----+--------+------------------+------+
| 1 | zhangs | zhangs@gmial.com | 1 |
| 2 | lis | lis@gmail.com | 1 |
| 3 | wange | wange@gmail.com | 2 |
| 4 | zhaoq | zhaoq@gmail.com | 1 |
| 5 | sunz | sunz@gmail.com | 2 |
+----+--------+------------------+------+
测试过程:
linux中登录三个mysql客户端,分别为session1、session2、session3,前两个用于交替输入SQL语句观察锁的存在,后一个用于查看锁时mysql的相关参数。
0、session1和session2中关闭自动提交
mysql> set autocommit = off;
一、条件为主键:
同记录的修改:
1、session1——修改主键值为1的记录
mysql> update t_user set email=replace(email, '@', '#') where id=1;
2、session2——修改主键值同样为1的记录
A、mysql> update t_user set email=replace(email, '#', '@') where id=1;
输入该命令回车后,将进入等待的状态。
B、通过session3查看:
mysql> show status like '%lock%';
+-------------------------------+-----------+
| Variable_name | Value |
+-------------------------------+-----------+
| Com_lock_tables | 0 |
| Com_unlock_tables | 0 |
| Innodb_row_lock_current_waits | 1 |
| Innodb_row_lock_time | 1283052 |
| Innodb_row_lock_time_avg | 1 |
| Innodb_row_lock_time_max | 51645 |
| Innodb_row_lock_waits | 645438 |
| Key_blocks_not_flushed | 2 |
| Key_blocks_unused | 7244 |
| Key_blocks_used | 8 |
| Qcache_free_blocks | 0 |
| Qcache_total_blocks | 0 |
| Table_locks_immediate | 136234099 |
| Table_locks_waited | 6645 |
+-------------------------------+-----------+
C、在session1中输入提交命令。
mysql> commit;
输入commit回车后,可以看到session2中的等待结束,并打印相关提示信息,如下:
Query OK, 0 rows affected (27.04 sec)
Rows matched: 1 Changed: 0 Warnings: 0
从A、B、C三个步骤不难看出,主键值为1的记录处于编辑状态时,其他用户想修改该记录需要排队等待。
修改不同记录:
1、session1——修改主键值为1的记录
mysql> update t_user set email=replace(email, '@', '#') where id=1;
2、session2——修改主键值为2的记录
A、mysql> update t_user set email=replace(email, '#', '@') where id=2;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0
未出现等待,直接显示提示信息和输入提示符。
B、mysql> commit;
提交后,数据被修改。
C、在session1中输入提交命令。
mysql> commit;
D、session3中查看:
mysql> select * from t_user;
+----+--------+------------------+------+
| id | name | email | role |
+----+--------+------------------+------+
| 1 | zhangs | zhangs#gmial.com | 1 |
| 2 | lis | lis#gmail.com | 1 |
| 3 | wange | wange@gmail.com | 2 |
| 4 | zhaoq | zhaoq@gmail.com | 1 |
| 5 | sunz | sunz@gmail.com | 2 |
+----+--------+------------------+------+
二、条件为非主键
1、session1——修改role为1的记录
mysql> update t_user set email=replace(email, '@', '#') where role=1;
2、session2
mysql> update t_user set email=replace(email, '#', '@') where role=2;
或
mysql> update t_user set email=replace(email, '#', '@') where id=3;
当session1中以非主键为条件编辑记录时,不管执行上面的哪一条都会进入等待状态。由此可见,在条件为非主键时,innodb用的是全表锁。
你也可以用以下命令,查看innodb锁时的相关数据
mysql> show innodb status\G;
分享到:
相关推荐
行级锁仅在InnoDB引擎中支持,且依赖于索引,只有通过索引条件检索数据时才会使用行级锁,否则会升级为表级锁。 表级锁是对整个表进行锁定,锁定粒度最大,实现简单,资源消耗少,但并发度最低,容易产生锁冲突。表...
InnoDB存储引擎既支持行级锁也支持表级锁。行级锁是通过索引项加锁实现的,这意味着只有通过索引检索数据时才会使用行级锁,否则会使用表级锁。行级锁依赖于索引,无索引的查询会导致全表锁定。行级锁的缺点是可能...
1. **行级锁(Row-Level Locks)**:InnoDB支持行级锁定,这是其相对于其他存储引擎的一个主要优点,因为行级锁能减少锁定的数据量,从而提高并发性能。行级锁包括共享锁(S锁)和独占锁(X锁)。 - 共享锁(S锁)...
- **多粒度锁定:** InnoDB支持在同一事务中同时使用行级锁和表级锁。这种能力增强了系统的并发性和灵活性。 #### 第三节:算法 虽然原文未详细介绍具体的锁算法,但从上述内容中我们可以推断出InnoDB中涉及的关键...
##### InnoDB行级锁的特点 - **高并发**:由于锁定的范围较小,可以更好地支持并发操作。 - **死锁检测**:InnoDB具有内置的死锁检测机制,可以在发生死锁时自动回滚其中一个事务,从而避免长时间的等待。 #### 六...
这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB 才使用行级锁,否则,InnoDB 将使用表锁! 在实际应用中,要特别注意 InnoDB 行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。 ...
InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁 各种锁特点 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生冲突的概率最高,并发度最低 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小...
在InnoDB引擎中,一般不推荐使用表锁,而是倾向于使用行级锁。 行锁(Row Lock)是MySQL中最细粒度的锁,只锁定特定行。在InnoDB引擎中,行锁通过行ID进行定位,可以实现高并发环境下的并行处理。行锁分为共享锁...
行级锁是通过对索引项加锁实现的,这意味着只有通过索引检索数据时才会使用行级锁,否则将使用表锁。 **事务与并发问题:** 事务的并发处理会导致不可重复读、更新丢失、脏读和幻读等问题。为解决这些问题,存在四...
在MySQL的InnoDB引擎中,支持行级锁(Row Locks)、表级锁(Table Locks),以及共享锁(Shared Locks)和排他锁(Exclusive Locks)。行级锁通过索引实现,如果SQL语句没有利用索引,则会升级为表锁。 行锁具有...
### MySQL事务与锁机制详解 #### 一、锁概念简介 ...而InnoDB则提供了更复杂的锁机制,支持行级锁、Next-Key锁等,更适合高并发的场景。在实际应用中,根据具体的需求选择合适的存储引擎和锁机制至关重要。
InnoDB锁机制是并发控制的关键,主要包括行锁、表锁、自增序列锁、半一致读和隐式锁等。 - **锁结构/类型/功能:** InnoDB的锁能够锁定资源,防止其他事务并发访问造成的数据不一致问题。锁类型主要包括共享锁和...
InnoDB的行级锁类型包括记录锁、间隙锁和临键锁等,主要用来减少锁争用,提高并发性。InnoDB支持多版本并发控制(MVCC),可以实现非阻塞的读操作。 在解决MySQL锁问题时,需要注意选择合适的事务隔离级别,因为...
特别地,在MySQL中,经常使用的InnoDB存储引擎支持行级锁,并且利用多版本并发控制(MVCC)机制来提高并发性能。在MVCC机制下,读操作通常会读取数据的快照版本,而不是当前版本,从而避免了读写操作之间的冲突。...
- InnoDB与MyISAM存储引擎的区别:InnoDB支持行级锁和事务,而MyISAM主要支持表级锁。 在使用过程中,应该根据实际的应用场景和性能需求,合理选择存储引擎和锁策略,以达到最优的并发控制效果。对于可能出现的锁争...
行级锁是InnoDB的默认锁策略,它允许更高的并发性,因为它只锁定操作的具体行,而不是整个表。 1. **行级锁**: - **共享锁(Shared Locks, S)**:用于读取一行数据,多个共享锁可以同时存在于同一行,允许事务...
- InnoDB 支持行级锁和表级锁,默认使用行级锁。 - MyISAM 使用表级锁。 - BDB 使用页面锁,也可用表级锁。 二、行锁 行级锁分为共享锁(读锁)和排他锁(写锁): A. 共享锁: - 允许读取数据,但不允许修改...
InnoDB支持行级锁,MyISAM只支持表锁; InnoDB支持崩溃后的恢复,MyISAM不支持; InnoDB支持外键,MyISAM不支持; InnoDB不支持全文索引,MyISAM支持全文索引; 7. MySQL索引的类型有哪些 普通索引:最基本的索引...
InnoDB引擎则提供了事务处理、行级锁定以及外键约束,这使得它在处理复杂的数据操作和并发性方面更为强大。InnoDB是MySQL的默认存储引擎,特别适用于需要高并发读写操作的在线交易处理(OLTP)系统。行级锁定极大地...