MySQL各种锁详细介绍

数据库锁


为什么需要数据库锁呢?其实就是为了解决并发的一些问题;锁保证了并发下数据访问的规则性和合理性!

根据加锁的范围,MySQL里面的锁大致可以分为全局锁、表级锁、行锁

1. 全局锁

加全局锁命令:flush table with read lock;(FTWRL

mysql> flush table with read lock;
Query OK, 0 rows affected (0.05 sec)

释放全局锁命令:unlock tables;

mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

1. 全局锁的特点

  • 全局锁让整个数据库(所有表)处于只读状态,使用这个命令后,数据库表的增删改(DML)、表结构的更改(DDL)、更新类事物的提交都会被阻塞

    例如下面,前面我已经给该数据库加上了全局锁,此时对其中一个表进行查询和插入操作:

    mysql> select * from test;
    +----+------+-----------+
    | id | name | adress    |
    +----+------+-----------+
    |  1 | yy   | ChongQing |
    |  2 | lch  | XiAn      |
    +----+------+-----------+
    2 rows in set (0.00 sec)
    
    mysql> insert into test values('yyg','zhongxian');
    ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock
    

    可以看到,查询是允许的,而插入是禁止的;

2. 全局锁的作用(全库逻辑备份)

上面看到了全局锁会让数据库只处于可读的状态,这种状态会使数据库处于一个多么低效率的状态,那么为什么还需要它呢?

低效率的原因:

  • 如果你在主库上备份,那么在备份期间都不能执行更新,业务基本上就得停摆;
  • 如果你在从库上备份,那么备份期间从库不能执行主库同步过来的binlog,会导致主从延迟;

因为在以前,全局锁的主要作用就是:做全库逻辑备份;
即在备份的时候,加上全局锁,让表只处于可读状态,处于这种

那么为什么这么做呢?即为什么需要在备份的时候加全局锁呢,这里用反证法来证明:

案例: 假如一个商城里有两张表,一张用户所购商品表,一张是用户余额表,假如在备份商品表刚完成还没开始备份用户余额表的时候,一位用户购买了某个产品,此时它的余额扣除成功,然后备份了用户余额表,这时造成的现象就是:备份的商品表没有用户买的那个商品,但备份的余额表却扣除了钱;

假如是备份完余额表,用户下单,再备份商品表的话,结果就是:用户的余额没扣,却多了商品;

上面的案例说明了,在做全库逻辑备份的时候,如果不加锁,会造成备份得到的库里面的表不是一个逻辑时间点 ,这个视图是逻辑不一致的;那么提到这,对于视图一致性,事物的可重复读这个隔离性不就能够实现吗;所以官方自带逻辑备份工具是mysqldump。当mysqldump使用参数-single-transaction的时候,导数据之前就会启动一个事物,来确保拿到一致性视图。而由于MVCC的支持,这个过程中数据是可以正常更新的;

那么,有了mysqldump这个功能,为什么还需要FTWRL?(⭐)
因为mysqldump是基于事物的,而有些引擎不支持事物,比如MyISAM,这种引擎在做全库逻辑备份的时候就只能使用全局锁了;

对于全库只读,还有一种方式可以实现:

set global readonly = true

那么到底使用set的方式还是使用FTWRL的方式来进行全库逻辑备份呢?这里有两个原因推荐使用FTWRL:

  • 1.在有些系统里,readonly的值会被用来做其他逻辑,比如用来判断一个库是主库还是备库,因此修改global变量的影响比较大,不建议使用;
  • 2.两者在异常处理机制上有差异
    • 执行FTWRL命令之后由于客户端的发生异常断开,那么MySQL会自动释放这个全局锁,整个库可以回到正常更新的状态;
    • 执行set global这个方式的话,如果客户端发生异常,则数据库还是一直会保持只读状态,这样会导致整个库长时间处于不可写状态,风险较高;

2. 表级锁

MySQL里面表级别的锁分两种:

  • 表锁
  • 元数据锁(mete data lock,MDL)

1. 表锁

加锁命令: lock table 表名 read/write

mysql> lock table test read;
Query OK, 0 rows affected (0.00 sec)

释放锁的命令:unlock tables;

1. 特点
  • 当还没有出现更细粒度的锁时,表锁是常用的处理并发问题的方式,而对于InnoDB这种支持

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值