前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL的锁

MySQL的锁

作者头像
张申傲
发布2020-09-03 16:31:48
5500
发布2020-09-03 16:31:48
举报
文章被收录于专栏:漫漫架构路漫漫架构路

MySQL的锁

数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则。而锁就是用来实现这些访问规则的重要数据结构。根据加锁的范围,MySQL 里面的锁大致可以分成全局锁、表级锁和行锁三类。

一. 全局锁

  1. Flush tables with read lock (FTWRL)
    1. 让整个库处于只读状态,所有更新操作都会被阻塞。
    2. **全局锁的典型使用场景是,做全库逻辑备份。**如果在做数据的时候不加锁,就可能出现备份的数据和原数据不一致的情况。
  2. mysqldump –single-transaction
    1. 官方自带的逻辑备份工具,在备份数据之前就会启动一个事务,来确保拿到一致性视图。而由于 MVCC 的支持,这个过程中数据是可以正常更新的。
    2. 只适用于所有的表都使用了事务引擎的库。如果有的表使用了不支持事务的引擎,那么备份就只能通过 FTWRL 方法。这往往是 DBA 要求业务开发人员使用 InnoDB 替代 MyISAM 的原因之一。
  3. set global readonly=true 该方式可以让整个库进入只读状态,但是有两个问题:
    1. 在有些系统中,readonly 的值会被用来做其他逻辑,比如用来判断一个库是主库还是备库。因此,修改 global 变量的方式影响面更大,不建议使用。
    2. 在异常处理机制上,如果执行 FTWRL 命令之后由于客户端发生异常断开,那么 MySQL 会自动释放这个全局锁,整个库回到可以正常更新的状态。而将整个库设置为 readonly 之后,如果客户端发生异常,则数据库就会一直保持 readonly 状态,这样会导致整个库长时间处于不可写状态,风险较高。

二. 表级锁

  1. 表锁
    1. 表锁的语法是 lock tables … read/write
    2. 需要注意,lock tables 语法除了会限制别的线程的读写外,也限定了本线程接下来的操作对象。比如一个线程A对表T1加了读锁,那么在线程A执行 unlock tables 之前,它对T1的写操作是不允许的。
    3. 在还没有出现更细粒度的锁的时候,表锁是最常用的处理并发的方式。而对于 InnoDB 这种支持行锁的引擎,一般不使用 lock tables 命令来控制并发,毕竟锁住整个表的影响面还是太大。
  2. 元数据锁(meta data lock,MDL)
    1. MDL 的作用是,控制对表结构的修改,保证读写的正确性。
    2. MDL 不需要显式使用,在访问一个表的时候会被自动加上。
    3. 在 MySQL 5.5 版本中引入了 MDL,当对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结构变更操作的时候,加 MDL 写锁。
    4. **事务中的 MDL 锁,在语句执行开始时申请,但是语句结束后并不会马上释放,而会等到整个事务提交后再释放。**因此最好避免长事务,且在执行 alter table 语句里面设定等待时间,如果在这个指定的等待时间里面能够拿到 MDL 写锁最好,拿不到也不要阻塞后面的业务语句,先放弃。之后开发人员或者 DBA 再通过重试命令重复这个过程。 ALTER TABLE tbl_name NOWAIT add column ... ALTER TABLE tbl_name WAIT N add column ...

三. 行级锁

  1. MySQL 的行锁是在引擎层由各个引擎自己实现的。比如 InnoDB 引擎支持行级锁,而 MyISAM 引擎就不支持。
  2. 两阶段锁: 在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。

四. 死锁与死锁检测

  1. 当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,称为死锁。
  2. 解决死锁的方式
    1. 出现死锁后,直接进入等待,直到超时。这个超时时间可以通过参数 innodb_lock_wait_timeout 来设置。
    2. 发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑。

    一般默认采用方式2,且innodb_deadlock_detect 的默认值本身就是 on。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-08-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MySQL的锁
    • 一. 全局锁
      • 二. 表级锁
        • 三. 行级锁
          • 四. 死锁与死锁检测
          相关产品与服务
          云数据库 SQL Server
          腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档