MySQL 锁

作者: 一生逍遥一生 | 来源:发表于2020-02-03 12:43 被阅读0次

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

全局锁

全局锁就是对整个数据库实例加锁。
MySQL提供了一个加全局读锁的方法:Flush tables with read lock。执行这个命令之后,之后其他线程的以下语句就会被阻塞:
数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。

全局锁的典型使用场景是做全裤逻辑备份。

风险:

  • 如果在主库备份,在备份期间不能更新,业务停摆
  • 如果在从库备份,备份期间不能执行主库同步过来的binlog导致主从延迟。

mysqldump 使用参数single-transaction的时候,导数据之前就会启动一个事务,来确保拿到一致性视图。由于MVVC的支持,这个过程中数据是可以正常更新的。

single-transaction只适用于所有的表使用事务引擎的库。

如果想要让数据库进入只读模式,建议使用FTWRL,有以下原因:

  • 在有些系统中,readonly的值会被用来做其他的逻辑,比如用来判断一个库是主库还是备库。因此,修改global变量的方式影响面更大,不建议使用。
  • 在异常处理机制上有差异。执行FTWRL命令之后由于客户端发生异常断开,MySQL会自动释放这个全局锁,整个库回到可以正常更新的状态。
    如果将整个库设置为readonly,客户端发生异常,数据库就会一直保持在readonly状态。导致整个库处于不可写状态,风险较高。

表级锁

MySQL里面表级别的锁有两种,一种是表锁,一种是元数据锁。
表锁的语法是lock tables ... read/write。可以使用unlock tables主动释放锁,也可以在客户端断开的时候自动释放。
lock tables语法除了会限制别的线程的读写外,也限定了本线程接下来的操作对象。
InnoDB这种支持行锁的引擎,一般不使用lock tables命令来控制并发,毕竟锁住整个表的影响还是太大。

MDL不需要显示使用,在访问一个表的时候会被自动加上。MDL的作用是保证读写的正确性。

MySQL5.5版本中引入了MDL,当对一个表做增删改查操作的时候,加MDL读锁,当要对表结构变更操作的时候,加MDL写锁。
读锁之间不互斥,读写锁之间、写锁之间是互斥的,用来保证变更表结构的安全性。
MDL会直到事务提交才会释放,在做表结构变更的时候,一定要小心不要导致锁住线上查询和更新。

表锁一般是在数据库引擎不支持行锁的时候才会被使用的,如果在应用程序中出现lock tables的语句需要注意以下情况:

  • 如果使用的引擎不支持事务,需要升级换引擎。
  • 如果引擎升级,代码没有做修改,可以将lock tables和unlock tables 改成begin和commit,问题就解决了。

行锁

MySQL的行锁是在引擎层有各个引擎自己实现的。但不是所有的引擎都支持行锁(MyISAM)。InnoDB是支持行锁的。
行锁是针对数据库中行记录的锁。

在InnoDB事务中,行锁是在需要的时候才加上的,但并不是不需要了就立即释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。

如果事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。

死锁:当并发系统中不同线程出现线程资源依赖,设计的线程都在等待别的线程释放资源时,就会导致这几个线程都会进入无限等待的状态。

修改方案:
通过修改innodb_lock_wait_timeout根据实际业务需要设置超时时间,InnoDB引擎默认值是50s。
发起死锁检测,发现死锁后,主动回滚死锁链中的某一个事务,让其他事务得以继续执行。将参数innodb_deadlock_detect设置为on,默认为开启状态。

如何解决热点行更新导致的性能问题?
1.如果能确保业务一定不会导致死锁,可以临时将死锁检测取消。不建议使用。
2.控制并发度,对应向同行的更新,在进入引擎之前排列。在InnoDB内部就不会有大量的死锁检测工作了。
3.将热更新的行数据拆分成逻辑上的多行来减少锁冲突,但是业务复杂度可能会大大提高。

InnoDB行级锁是通过锁索引记录实现的,如果更新的列没有索引会锁住整个表。

相关文章

  • Mysql的锁

    MySql锁的分类 Mysql里的锁大致可以分为全局锁、表级锁和行锁三类。 全局锁 Mysql 增加全局锁的方法:...

  • MySQL二进制日志

    MySQL-day10 MySQL存储引擎-锁 1)什么是“锁”? 2)“锁”的作用是什么? 3)MySQL中的锁...

  • MySQL的锁机制

    mysql的锁机制 1、MySQL锁的基本介绍 MyISAM:MySQL的表级锁有两种模式:表共享读锁(Table...

  • MS汇总

    数据库相关[MS-关于锁(乐观锁,悲观锁,行锁、表锁,共享锁,排他锁)Mysql索引优化Mysql查询优化Mysq...

  • Mysql 之 锁表与解表

    Mysql 之 锁表与解表 Mysql 查看锁表语句 mysql>show open tables where i...

  • rails中乐观锁和悲观锁的使用

    MySQL乐观锁和悲观锁的介绍可以参考之前的一篇文章MySQL中的锁(行锁,表锁,乐观锁,悲观锁,共享锁,排他锁)...

  • 秒杀随笔

    方法: mysql悲观锁 mysql乐观锁 PHP+redis分布式锁 PHP+redis乐观锁(redis wa...

  • 共享 + 排他锁

    mysql锁机制分为表级锁和行级锁 ,mysql中行级锁中的共享锁与排他锁进行分享交流。 测试语法 begin; ...

  • (4)头条mysql

    1、MySQL有哪些锁,乐观锁和悲观锁实现 如果避免、减少锁等待、团队中如何监控MySQL的锁等待的情况 锁监控:...

  • MySQL锁篇

    1 MySQL锁介绍 2 MySQL表级锁 2.1 表级锁介绍 ​ 表级锁由SQL layer实现。M...

网友评论

      本文标题:MySQL 锁

      本文链接:https://www.haomeiwen.com/subject/mjrhxhtx.html