mysql锁机制学习笔记,持续记录

mysql锁的分类

Mysql中锁的分类按照不同类型的划分可以分成不同的锁,按照「锁的粒度」划分可以分成:表锁、页锁、行锁;按照思想的划分:「乐观锁」和「悲观锁」。

1.表锁

行级锁定最大的特点就是锁定对象的粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的。由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力而提高一些需要高并发应用系统的整体性能。

mysql中使用行级锁定的主要是InnoDB存储引擎。

InnoDB的行级锁定按使用方式同样分为两种类型,共享锁排他锁,而在锁定机制的实现过程中为了让行级锁定和表级锁定共存,InnoDB也同样使用了意向锁(表级锁定)的概念,也就有了意向共享锁和意向排他锁这两种。

对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);

对于普通SELECT语句,InnoDB不会加任何锁;事务可以通过以下语句显示给记录集加共享锁或排他锁。

共享锁(S):SELECT*FROM table_name WHERE ... LOCK IN SHARE MODE

排他锁(X):SELECT*FROM table_name WHERE ... FORUPDATE

2.共享锁

共享锁又称读锁 (read lock),是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。当如果事务对读锁进行修改操作,很可能会造成死锁。

3.排它锁

排他锁 exclusive lock(也叫 writer lock)又称写锁,排它锁是悲观锁的一种实现。FORUPDATE仅适用于Innodb, 且必须在事务处理模块(BEGIN/COMMIT)中才能生效 。

提示
若某个事物对某一行加上了排他锁,只能这个事务对其进行读写,在此事务结束之前,其他事务不能对其进行加任何锁,其他进程可以读取,不能进行写操作,需等待其释放。

排它锁细分种类:https://zhuanlan.zhihu.com/p/420761461

InnoDB行锁优化建议

1.表操作优化

  • 尽可能让所有的数据检索都通过索引来完成,从而避免InnoDB因为无法通过索引键加锁而升级为表级锁定;
  • 合理设计索引,让InnoDB在索引键上面加锁的时候尽可能准确,尽可能的缩小锁定范围,避免造成不必要的锁定而影响其他Query的执行;
  • 尽可能减少基于范围的数据检索过滤条件,避免因为间隙锁带来的负面影响而锁定了不该锁定的记录;
  • 尽量控制事务的大小,减少锁定的资源量和锁定时间长度;
  • 在业务环境允许的情况下,尽量使用较低级别的事务隔离,以减少MySQL因为实现事务隔离级别所带来的附加成本。

2.减少死锁产生概率?

  • 类似业务模块中,尽可能按照相同的访问顺序来访问,防止产生死锁;
  • 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
  • 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率。
提示
innodb 的行锁是在有索引的情况下,没有索引的表是锁定全表的。

发生死锁如何解决?

1. 查看当前运行的所有事务

SELECT * FROM  information_schema.innodb_trx

2.停止事务

KILL 165667 ;   KILL 后面的数字指的是 trx_mysql_thread_id 值。

问题记录

1.Mysql在哪些情况下会自动加锁

  • 更新操作时:在执行更新操作时,MySQL 会自动对被更新的表加上读写锁,以确保其他用户不能同时更新该表。
  • 插入操作时:在执行插入操作时,MySQL 会自动对被插入的表加上写锁,以确保其他用户不能同时插入数据。
  • 查询操作时:在执行查询操作时,MySQL 会自动对查询的表加上读锁,以确保其他用户不能同时读取该表。
  • 连接时:在创建连接时,MySQL 会为每个连接自动加上共享锁,以确保其他连接不能访问该连接正在使用的表或数据库。
  • 需要注意的是,MySQL 的自动锁机制是为了保证数据库的一致性和并发性能,但并不是万能的。在一些复杂的场景下,如并发插入、更新、删除操作时,MySQL 的自动锁机制可能会出现问题。因此,在设计数据库架构时,需要根据实际情况合理配置并发控制参数,并进行充分的测试和优化,以确保数据库的稳定性和并发性能。

2.Mysql在什么情况下需要手动加锁

  • 更新操作时:如果多个用户同时更新同一张表,则需要手动加写锁来保证数据的一致性。
  • 插入操作时:如果多个用户同时插入数据,则需要手动加写锁来保证数据的一致性。
  • 删除操作时:如果多个用户同时删除同一张表的数据,则需要手动加写锁来保证数据的一致性。
  • 并发访问敏感数据时:对于一些敏感数据,如用户信息、订单信息等,如果并发访问会导致数据不一致,则需要手动加锁来保证数据的一致性。
  • 需要注意的是,手动加锁会增加系统的并发成本和处理时间,因此应该根据实际需要进行加锁操作,并且应该尽量避免频繁进行加锁操作。同时,在手动加锁时,应该遵循“先进先出”的原则,以确保锁的公平分配。

3.Mysql会自动加锁,为什么还需要手动加锁

  • 虽然 MySQL 会自动加锁,但在一些复杂场景下,自动锁机制可能会出现问题,因此需要手动加锁来保证数据的一致性和并发性能。
  • 例如,在并发插入操作时,MySQL 的自动锁机制可能不会及时检测到同时进行的插入操作,从而导致数据不一致的问题。此时,需要手动加写锁来保证数据的一致性。
  • 此外,手动加锁也可以提高并发性能,因为手动加锁可以避免 MySQL 的自动锁机制导致的锁等待和并发处理成本。但是,手动加锁也会增加系统的并发成本和处理时间,因此应该根据实际需要进行加锁操作,并且应该尽量避免频繁进行加锁操作。