MySQL的锁主要分为全局锁、表锁和行锁
全局锁
全局锁是针对整个数据库的锁。最常用的全局锁是读锁和写锁
读锁(共享锁)
它阻止其他用户更新数据,但允许他们读取数据。这在你需要在一段事件内保持数据一致性时很有用
写锁(排他锁)
它阻止其他用户读取和更新数据。这在你需要修改一些大量的数据,并且不希望其他用户在这段时间内干扰时很有用。
全局锁的使用场景
进行一下举要去报整个数据库一致性的操作,例如全库备份、全库导出等
在MySQL中,可以使用FLUSH TABLES WITH READ LOCK(FTWRL)语句来添加全局读锁,这将阻止其他线程进行更新操作。使用UNLOCK TABLES语句来释放锁定
缺点
全局锁的开销非常大,因为它会阻止其他所有的数据修改操作,并且在高并发情况下可能导致大量的线程等待锁定,因此,应该尽量避免在生产环境中使用全局锁,或者尽量减少全局锁的持有时间
表级锁
表级锁是MySQL中最基本的锁策略,是MySQL最早采用的锁策略。表级锁的特点是开销小,加锁快,不会出现死锁;锁定力度大,发生所冲突的概率最高,并发度最低。
表共享读锁
又称为表读锁,允许一个事务锁定的表进行读取操作,不允许其他事务对其进行写操作,但是可以进行读操作。读锁之间是不会相互阻塞的。
表独占写锁
又称为表写锁,允许一个事务锁定的表进行读取和写入操作,但是其他任何事务都不能再对该表进行任何操作,必须等待表写锁结束。写锁会阻塞其他所有表,包括读锁和写锁。
表级锁有哪些使用场景
读密集型应用
如果你的应用主要是进行读取操作,很少进行写操作,那么使用表级锁可能是一个好选择。因为表记读锁不会阻塞其他的车读锁,所以这种场景下表级锁能够提供很高的性能
写操作不频繁的场景
表级锁对写操作的处理并不高效,因为一个写锁会阻塞所有其他的锁,无论他们是读锁还是写锁。但是吐过你的应用不需要频繁的进行写操作,或者可以容忍写操作的延迟,那么使用表级锁可能是可行的
数据量不大的简单应用
如果数据库的数据量不大,那么即使在写操作中,由于锁定整张表,对性能的影响也不大
全表更新或者删除
在哪些情况下,可能需要对一张表进行全表的更新或者删除操作,例如,删除表中的所有记录,或者更新表中所有记录的某个字段的值。在这种情况下,使用表级锁的合适的。
缺点
虽然表级锁的开销很小,但由于其锁粒度大,可能导致并发度下降,特别是在写操作较多或者并发度较高的场景下。所以,如果应用的并发度较高,或者需要频繁进行写操作,那么可能需要考虑使用更精细粒度的锁。
表锁风险点
性能下降
因为表锁会锁定整个表,所以在高并发的环境中,他可能导致大量的请求阻塞,从而降低性能。对于读取和写入混合密集的负载,表锁可能会成为一个性能瓶颈
并发性能差
表锁的最大问题在于其并发性能差。一旦一个线程对表获得了写锁,其他线程的任何读写操作都会被阻塞,直到写锁被释放。同样的,如果一个读锁被持有,那么其他的写操作将被阻塞。这就使得并发性能大大降低。
可能导致锁等待和超时
在高并发环境中,由于表级锁的粒度较大,可能会有很对线程在等待锁,如果等待的时间过长,可能会导致锁超时,进一步影响应用的性能和可用性。
写操作影响大
如果一个长时间运行的写操作获取了写锁,那么会阻塞所有其他的读操作和写操作,知道这个写操作完成
死锁的可能性
虽然表锁本身不会出现死锁,但在多表操作中,如果没有按照一定的顺序获得锁,可能会导致死锁
为了避免这些问题,我们通常会选择InooDB存储引擎,它主要使用行级锁,可以提供更好的并发性能,并且在一定上减少了锁争用的问题。而且InooDB还支持事务,可以保证数据的一致性和完整性。在实际应用中,我们应该根据具体的业务需求和系统负载,选择合适的存储引擎和锁策略
行锁
行锁是MySQL中的一种锁定机制,它可以对数据库表中的单独一行进行锁定。相比于表级锁和页锁,行级锁的粒度跟小,因为在处理高并发事务时,能提供更好的并发性能和更少的所冲突。然而,行级锁也需要更多的内存和cpu资源。因为需要对每一行都进行管理。
共享锁
共享锁也称为读锁,它允许一个事务读取一行数据。当一行数据被共享锁锁定时,其他事务可以读取这行数据,但不能对其进行修改
排他锁
排他锁也称为写锁,它允许一个事务读取和修改一行数据。当一行数据被排他锁锁定时,其他事务不能读取也不能修改这行数据。
在实际使用中,InooDB还提供了一种名为“间隙锁”的特性。间隙锁不仅锁定一个具体的行,还锁定他前后的“间隙”,即这一行之前和之后的行之间的空间。间隙锁可以防止其他事务插入新的行到已锁定行的前后,从而可以解决一些并发问题。
缺点
行级锁旨在事务中有效,也就是说,只有一个事务开始后并在事务提交或回滚之前,才能对数据行进行锁定。如果在非事务环境中执行SQL语句,那么InooDB会在语句执行结束后立即释放所有的锁。
行锁有哪些使用场景
高并发读写操作
在需要高并发读写操作的场景下,行级锁可以提高性能和并发性,因为它运行多个事务并发地操作不同地行。
单行操作
对于需要操作单行数据地SQL语句,行级锁可以提供较好地并发性和性能。
短期锁
在需要对数据进行短时间锁定的情况下,行级锁可以防止长时间阻塞其他事务。
实现并发控制
在需要确保数据一致性和隔离性的事务中,行级锁是实现并发控制的重要机制
复杂的事务处理
在需要对多行数据进行复杂处理的事务中,可以使用行级锁来锁定这些行,防止在事务处理过程中数据被其他事务修改
使用行级锁需要注意,由于行级锁的锁定粒度较小,可能会消耗更多的系统资源,特别是在处理大量数据时。此外,使用行级锁也可能导致死锁,需要使用合适的策略来避免死锁,例如在事务中按照一定的顺序锁定行。
行锁风险点
死锁
当两个或更多的事务相互等待对方释放资源时,就会发生死锁。MySQL会检测到死锁并终止其中一个事务,但这仍可能导致性能问题和事务失败。
锁升级
如果一个事务试图锁定的行过多,InooDB可能会将锁从行级升级为表级,这就可能导致更多的锁冲突
锁等待
如果一个事务已经锁定了某行,其他试图访问这行的事务就必须等待,这可能导致性能下降。如果有大量的事务在等待锁,就可能导致系统出现性能瓶颈。
资源消耗
行级锁需要更多的内存来存储锁信息,而且需要更多的cpu时间来处理锁请求和释放锁。如果数据库中的行数非常多,或者并发事务的数量非常多,这可能会导致显著的资源消耗
难以调查和排查
由于行级锁的粒度较小,如果出现性能问题或锁冲突,可能需要复杂的调试和排查工作来找出问题的原因
事务隔离级别
不同的事务隔离级别会影响锁的性能和行为,可能需要根据具体的应用场景来调整事务隔离级别。




