mysql 锁

对于 MyIsam 引擎默认是“表”锁——偏“读”:

读锁会阻塞写,而不会影响读:例如一个表 table 被一个session(进程)加了读锁,则不影响其他的 session 读该表,但是会阻塞其他的session 写锁,所谓阻塞就是说必须要等加锁的 session 释放了该表上的锁,其他的 session 才会执行其写锁的命令,否则,该命令将一直等待下去(阻塞) 。

      另外一点,给表加读锁的 session 既不能写该表,也不能读取其他的表,就好比干一件事,你必须先把它干完,否则别想着干其他事

写锁会把读和写都阻塞:给表加写锁的 session,自己可以读该表,但是阻塞了其他的 session 对该表的读和写,而且该 session 也不能读其他的表,必须先干完这件事


由于 MyIsam 引擎读写锁的调度是“写”优先,所以 MyIsam 不适合做以写表为主的引擎,因为写锁后,其他线程很难做任何操作,大量的对表的更新会使得查询很难得到锁,从而造成永远阻塞

对于 innodb 引擎默认是“行”锁——偏“写”:

当查询条件中的 varchar 类型没有加单引号,而且该查询条件的字段为索引字段,如where name=2000(其中name字段为索引字段),mysql 内部会做一个自动类型的转换,索引失效,这时候的行锁会转换成表锁,这是一件非常可怕的事情

对于 innodb 引擎的“间隙锁”:

比如:update table user set username='hello' where age>20 and age<25;

假如此时在数据库表中,没有 age=22 的这条记录(也就是说没有年龄为22 的员工),那么 where 条件的值就是:21 23 24,在这条更新语句没有提交之前,此时,有另外一条sql 也在更新这张表,且就是插入 age =22 的这条记录,按理说 innodb 引擎是行锁,这两条 sql 所操作的行都是不同的行,所以第二条 sql 的 insert 操作也能添加到数据库中,但实际是该 sql 仍然被第一条没提交的 sql 阻塞,直到第一条 sql 执行 commit 操作,第二条 sql 才执行,这个锁叫做“间隙锁”,这也是间隙所的危害

给表的某一行加“行锁”方法:

select XXX for update;

就是在 select 后面加上 for update,其他线程就不能操作该行,表现为阻塞状态,直到该行执行 commit 命令,其他行才有权执行操作

在表上查看锁状态的方法:show status like 'user%';


对于行锁的优化建议:


MyIsam 和 innodb 的区别:


### MySQL 机制详解 MySQL 中的机制是为了保障数据库在高并发环境下的数据一致性和稳定性而设计的重要功能之一。以下是关于 MySQL 机制的具体解析: #### 1. 的分类 MySQL 主要分为两种类型的:表级和行级。 - **表级 (Table-Level Lock)** 表级是最简单的定策略,适用于 MyISAM 存储引擎。它会在整个表上施加,无论是读操作还是写操作都会影响到整张表。对于 `SELECT` 操作,MyISAM 会自动给涉及的所有表加上读;而对于 `UPDATE`, `INSERT`, 和 `DELETE` 则会自动加上写[^3]。 - **行级 (Row-Level Lock)** 行级由 InnoDB 存储引擎实现,提供更高的并发能力。只有涉及到具体记录的操作才会触发行级。例如,在执行 `SELECT ... FOR UPDATE` 或者 `SELECT ... LOCK IN SHARE MODE` 时,InnoDB 只会对符合条件的特定行加而不是封整个表[^2]。 #### 2. 不同存储引擎的特性 不同的存储引擎有不同的行为: - **MyISAM**: 默认使用的是表级别的,这意味着即使是一个小范围内的更新也会阻塞其他线程对该表任何部分的访问[^3]。 - **InnoDB**: 支持事务以及更细粒度的行级,这使得它可以更好地处理复杂的多用户场景下的并发请求[^4]。 #### 3. 常见类型及其作用 除了基本的表级与行级区分外,还有几种具体的形式用于满足不同需求: - **共享 (Shared Lock, S-Lock)** 当一个客户端通过命令如 `LOCK TABLES table_name READ` 获取了一个表上的共享之后,其它客户也可以获得该表上的共享,但不能再获取排他直到当前持有共享的所有连接释放它们为止[^2]。 - **排他 (Exclusive Lock, X-Lock)** 排他允许独占式的修改权限。如果某个事务已经获得了某条记录或者某些列上的排他,则在此期间不允许别的事务再对此同一组资源申请任何形式的新——既包括另外的排他也包括新的共享[^2]。 - **GAP ** 这种特殊的用来阻止新纪录插入到现有两条连续记录之间的空隙(gap)里去。比如当我们运行下面这条SQL语句的时候就会用到gap lock:`SELECT * FROM table_name WHERE id > 10 FOR UPDATE;` - **Next-Key Lock** 是一种组合了索引记录本身(record)和其前面那个区间(gap)两者一起保护起来的一种复合型模式。主要用于解决可重复读(repeatable read)隔离级别下可能出现的幻影问题(phantom problem)[^4]。 #### 4. 死现象及预防措施 死是指两个或更多事务相互等待对方持有的资源从而进入僵局的状态。为避免这种情况发生可以采取以下方法: - 尽量按照固定的顺序访问资源; - 减少单次事务持续时间; - 设置合理的超时参数让系统能够及时发现并终止潜在的死循环状况等等[^4]。 ```sql -- 示例:如何手动解表 UNLOCK TABLES; ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Micrle_007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值