【MySQL】锁

1.锁的概念

  锁是计算机协调多个进程或线程并发访问同一资源的机制。数据库系统使用锁是为了支持对共享资源进行并发访问访问,提供数据的完整性和一致性

2.锁的作用

  在数据库中,除传统的资源(内存,cpu等)的争用外,数据也是一种供许多用户使用的数据,如何保证数据的一致性和有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问的一个重要因素,锁就解决上面这些问题

3.锁的分类

 按操作类型分为:

   读锁(共享锁): 针对同一份数据,多个读操作可以同时进行而不会影响
   写锁(排它锁): 针对同一份数据,多个写操作不可以同时进行,会发生进程堵塞情况

 按操作力度分为:

   页面锁: 对整个页面上锁
   表锁: 对整个表上锁,当表锁时,其他进程想读该表,必须等待锁的释放,程堵塞状态
   行锁: 对某条数据上锁,当该行锁住时,其它进程无法访问操作该条数据,但不影响其它进程访问别的数据

4.表锁

 4.1 表级锁的两种概念

   1.表共享锁
   2.表独占锁

  区别:读锁会阻塞写,但不会阻塞读;但写锁会阻塞读和写

 4.2 特点

   1.偏向在MyISAM存储引擎,开销小,加锁快
   2.无死锁
   3.锁力度大,发生冲突的概率高,并发度最低

 4.3 引发表锁条件

   1.手动加锁
   2.操作数据库时

 4.4 分析

命令:show status like ‘table%’
返回结果:
     在这里插入图片描述
结果分析:
  Table_locks_immediate:产生表锁定的次数,即表示立即获取锁的查询次数,每立即获取锁1次该值加1
  Table_locks_waited:出现表级锁定争用而发生等待的次数,即不能立即获取锁的次数,每等待1次该值加1,此值高则说明存在较严重的表级锁争用情况

  MyISAM 的读写锁调度是写有先,写锁后,其他线程不能做任何操作,大量的更新会时查询很难得到锁,从而造成用于的阻塞,所以MyISAM不适合做写为主的引擎

5.行锁

 5.1 特点

   1.偏向InnoDB存储引擎,开销大,加锁慢(存在Next-Key锁);
   2.会出现死锁;
   3.锁定力度最小,发生锁冲突的概率最低,并发度也最高

 5.2 引发表锁条件

   1.手动加锁
   2.操作数据库时

 5.3 行锁升级为表锁的条件

    1.无索引行锁升级为表锁
    举例:比如更新id为1的这条数据,如果id有索引,就会上把该对应的索引上锁,但是id没有索引,这时候就是表锁。这也想到我们公司建表的规定,id必须建索引,可能一方面也是出于这样的考虑( InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。并且该索引不能失效,否则都会从行锁升级为表锁)
    2.大量 更新或全表更新,行锁会升级为表锁
  MySQL 认为大量对一张表使用行锁,会导致事务执行效率低,从而可能造成其他事务长时间锁等待和更多的锁冲突问题,性能严重下降。所以MySQL会将行锁升级为表锁,即实际上并没有使用索引

 5.4 间隙锁

  我们用范围条件而不是相等条件检索时,并请求共享或排它锁时,InnoDB会给符合条件的已有数据记录的索引项加锁, 对符合条件的但并不存在的记录,叫“间隙”。InnoDB会对这个“间隙”加锁,这种机制即为“间隙锁” 。(比如查询id 在1到10的范围是,会对id在1到10的记录都加锁,但是数据库不存在id=2这条记录,这时想插入一条id=2的记录/是无法插入的,因为id=2这条数据已被加上了间隙锁)

 5.5 分析

命令:show status like ‘innodb_row_lock%’
返回结果:
     在这里插入图片描述
结果分析:
  Innodb_row_lock_current_waits:当前正在等待锁的数量;
  Innodb_row_lock_time:从系统启动到现在锁定总时间长度;
  Innodb_row_lock_time_avg:每次等待所花平均时间;
  Innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花的时间长度;
  Innodb_row_lock_waits:系统启动到现在总共等待的次数;
  当等待次数很高,而且每次等待时长也很大的时候,我们就要分析系统中为什么有这么多的等待,然后根据分析结果来制定优化

 5.5 优化

   1.让所有的数据通过索引来检索
   2.合理设计索引,尽量缩小锁的范围
   3.尽可能减少锁的条件,避免间隙锁
   4.控制事务大小,减少锁定资源量和时间的长度
   5.降低事务隔离级别

6.锁冲突

  锁冲突:是等待别人释放我需要的锁资源,即当操作这个资源时,此资源已上锁,我就需要等待释放次锁

7.死锁

 7.1 what

   死锁:互相等待对方持有的锁

 7.2 死锁举例

 7.3 死锁的原因

 7.4 发生死锁的必要条件

锁冲突和死锁不是一个概念,有本质区别,锁冲突会按顺序执行,死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象, 若无外力作用,它们都将无法推进下去。

事务的属性及级别

### 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; ``` --- ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值