MySQL锁
本文最后更新于4 天前,其中的信息可能已经过时,如有错误请发送邮件到1169063119@qq.com

MySQL的锁主要分为全局锁、表锁和行锁

全局锁

全局锁是针对整个数据库的锁。最常用的全局锁是读锁和写锁

读锁(共享锁)

它阻止其他用户更新数据,但允许他们读取数据。这在你需要在一段事件内保持数据一致性时很有用

写锁(排他锁)

它阻止其他用户读取和更新数据。这在你需要修改一些大量的数据,并且不希望其他用户在这段时间内干扰时很有用。

全局锁的使用场景

进行一下举要去报整个数据库一致性的操作,例如全库备份、全库导出等

在MySQL中,可以使用FLUSH TABLES WITH READ LOCK(FTWRL)语句来添加全局读锁,这将阻止其他线程进行更新操作。使用UNLOCK TABLES语句来释放锁定

缺点

全局锁的开销非常大,因为它会阻止其他所有的数据修改操作,并且在高并发情况下可能导致大量的线程等待锁定,因此,应该尽量避免在生产环境中使用全局锁,或者尽量减少全局锁的持有时间

表级锁

表级锁是MySQL中最基本的锁策略,是MySQL最早采用的锁策略。表级锁的特点是开销小,加锁快,不会出现死锁;锁定力度大,发生所冲突的概率最高,并发度最低。

表共享读锁

又称为表读锁,允许一个事务锁定的表进行读取操作,不允许其他事务对其进行写操作,但是可以进行读操作。读锁之间是不会相互阻塞的。

表独占写锁

又称为表写锁,允许一个事务锁定的表进行读取和写入操作,但是其他任何事务都不能再对该表进行任何操作,必须等待表写锁结束。写锁会阻塞其他所有表,包括读锁和写锁。

表级锁有哪些使用场景

读密集型应用

如果你的应用主要是进行读取操作,很少进行写操作,那么使用表级锁可能是一个好选择。因为表记读锁不会阻塞其他的车读锁,所以这种场景下表级锁能够提供很高的性能

写操作不频繁的场景

表级锁对写操作的处理并不高效,因为一个写锁会阻塞所有其他的锁,无论他们是读锁还是写锁。但是吐过你的应用不需要频繁的进行写操作,或者可以容忍写操作的延迟,那么使用表级锁可能是可行的

数据量不大的简单应用

如果数据库的数据量不大,那么即使在写操作中,由于锁定整张表,对性能的影响也不大

全表更新或者删除

在哪些情况下,可能需要对一张表进行全表的更新或者删除操作,例如,删除表中的所有记录,或者更新表中所有记录的某个字段的值。在这种情况下,使用表级锁的合适的。

缺点

虽然表级锁的开销很小,但由于其锁粒度大,可能导致并发度下降,特别是在写操作较多或者并发度较高的场景下。所以,如果应用的并发度较高,或者需要频繁进行写操作,那么可能需要考虑使用更精细粒度的锁。

表锁风险点

性能下降

因为表锁会锁定整个表,所以在高并发的环境中,他可能导致大量的请求阻塞,从而降低性能。对于读取和写入混合密集的负载,表锁可能会成为一个性能瓶颈

并发性能差

表锁的最大问题在于其并发性能差。一旦一个线程对表获得了写锁,其他线程的任何读写操作都会被阻塞,直到写锁被释放。同样的,如果一个读锁被持有,那么其他的写操作将被阻塞。这就使得并发性能大大降低。

可能导致锁等待和超时

在高并发环境中,由于表级锁的粒度较大,可能会有很对线程在等待锁,如果等待的时间过长,可能会导致锁超时,进一步影响应用的性能和可用性。

写操作影响大

如果一个长时间运行的写操作获取了写锁,那么会阻塞所有其他的读操作和写操作,知道这个写操作完成

死锁的可能性

虽然表锁本身不会出现死锁,但在多表操作中,如果没有按照一定的顺序获得锁,可能会导致死锁

为了避免这些问题,我们通常会选择InooDB存储引擎,它主要使用行级锁,可以提供更好的并发性能,并且在一定上减少了锁争用的问题。而且InooDB还支持事务,可以保证数据的一致性和完整性。在实际应用中,我们应该根据具体的业务需求和系统负载,选择合适的存储引擎和锁策略

行锁

行锁是MySQL中的一种锁定机制,它可以对数据库表中的单独一行进行锁定。相比于表级锁和页锁,行级锁的粒度跟小,因为在处理高并发事务时,能提供更好的并发性能和更少的所冲突。然而,行级锁也需要更多的内存和cpu资源。因为需要对每一行都进行管理。

共享锁

共享锁也称为读锁,它允许一个事务读取一行数据。当一行数据被共享锁锁定时,其他事务可以读取这行数据,但不能对其进行修改

排他锁

排他锁也称为写锁,它允许一个事务读取和修改一行数据。当一行数据被排他锁锁定时,其他事务不能读取也不能修改这行数据。

在实际使用中,InooDB还提供了一种名为“间隙锁”的特性。间隙锁不仅锁定一个具体的行,还锁定他前后的“间隙”,即这一行之前和之后的行之间的空间。间隙锁可以防止其他事务插入新的行到已锁定行的前后,从而可以解决一些并发问题。

缺点

行级锁旨在事务中有效,也就是说,只有一个事务开始后并在事务提交或回滚之前,才能对数据行进行锁定。如果在非事务环境中执行SQL语句,那么InooDB会在语句执行结束后立即释放所有的锁。

行锁有哪些使用场景

高并发读写操作

在需要高并发读写操作的场景下,行级锁可以提高性能和并发性,因为它运行多个事务并发地操作不同地行。

单行操作

对于需要操作单行数据地SQL语句,行级锁可以提供较好地并发性和性能。

短期锁

在需要对数据进行短时间锁定的情况下,行级锁可以防止长时间阻塞其他事务。

实现并发控制

在需要确保数据一致性和隔离性的事务中,行级锁是实现并发控制的重要机制

复杂的事务处理

在需要对多行数据进行复杂处理的事务中,可以使用行级锁来锁定这些行,防止在事务处理过程中数据被其他事务修改

使用行级锁需要注意,由于行级锁的锁定粒度较小,可能会消耗更多的系统资源,特别是在处理大量数据时。此外,使用行级锁也可能导致死锁,需要使用合适的策略来避免死锁,例如在事务中按照一定的顺序锁定行。

行锁风险点

死锁

当两个或更多的事务相互等待对方释放资源时,就会发生死锁。MySQL会检测到死锁并终止其中一个事务,但这仍可能导致性能问题和事务失败。

锁升级

如果一个事务试图锁定的行过多,InooDB可能会将锁从行级升级为表级,这就可能导致更多的锁冲突

锁等待

如果一个事务已经锁定了某行,其他试图访问这行的事务就必须等待,这可能导致性能下降。如果有大量的事务在等待锁,就可能导致系统出现性能瓶颈。

资源消耗

行级锁需要更多的内存来存储锁信息,而且需要更多的cpu时间来处理锁请求和释放锁。如果数据库中的行数非常多,或者并发事务的数量非常多,这可能会导致显著的资源消耗

难以调查和排查

由于行级锁的粒度较小,如果出现性能问题或锁冲突,可能需要复杂的调试和排查工作来找出问题的原因

事务隔离级别

不同的事务隔离级别会影响锁的性能和行为,可能需要根据具体的应用场景来调整事务隔离级别。

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇