• 你了解MySQL中的锁吗?


    MySQL中的锁,分为全局锁、表级锁、行锁

    全局锁

    全局锁的意思就是,对整个数据库实例加锁,它的命令是FTWRL

    Flash tables with read lock

    这个命令的语义是,使整个库处于一种只读的状态,使用这个命令后,以下语句会被阻塞:数据的更新、数据结构的定义、更新类事务的提交。
    全局锁通常被用于全库逻辑备份,但是让整个库只读,会有两个问题:

    1. 主库上的备份,会使整个业务停摆。
    2. 从库上的备份,会造成备份期间,从库无法执行主库同步过来的bin log而造成主从延迟。

    官方自带的逻辑是mysqldump,导数据之前,会开启一个事务,目的是拿到一致性视图,由于MVCC(数据多版本并发控制),备份的过程中,数据是可以正常更新的。但是由于只有InnoDB支持事务,所以只有InnoDB可以使用mysqldump来对数据库进行逻辑备份。这也是为什么现在都建议使用InnoDB的原因之一。

    表级锁

    MySQL里面的表级锁有两种,一种是表锁,一种是MDL元数据锁。(Meta data lock)
    表锁的语法是:

    lock tables ...read/write

    整张表上锁,不仅限制其他线程的操作,同时也限制本线程的操作。
    MDL是一种隐式锁。他的所用是保证读写操作的正确性,MDL是MySQL5.5版本之后引入的,当对一个表进行增删改查的时候,会加MDL读锁。对表结构进行修改的时候,会加MDL写锁。读写锁之间、写锁之间是互斥的。(所以写锁也叫排它锁,读锁也叫共享锁)。
    锁只有在事务提交的时候,才会释放。所以长事务会一致占用锁。所以修改表结构的时候,要注意,不要阻塞线上正在执行的增删改查操作。

    行锁

    行锁是存储引擎层实现的,所以这也是为什么要用InnoDB引擎来代替MyISAM引擎的原因之一。
    有两个事务都在更改同一条热点数据。这个时候,会出现阻塞现象。
    在InnoDB引擎中,行锁是需要的时候加上的,但是释放锁的时候,却是事务结束的时候才释放。所以如果一个事务要锁多个行,要把最可能造成锁冲突的语句放到后面,这样可以减少阻塞的时间。

    死锁和死锁检测

    并发系统中,不同线程出现循环依赖资源,涉及到的线程都在等待其他线程释放资源,导致无限等待的状态,称为死锁。
    有两种思路可以解决死锁问题:

    1. 设置超时等待,innodb_lock_wait_timeout,默认是50s,显然这个时间太长了,但是这个值的大小很难确定,会误伤正常的锁等待。
    2. 发起死锁检测,发生死锁后,主动回滚死锁链条中的某一事务,让其他事务可以正常执行。参数是innodb_deadlock_detect

    但是死锁检测是需要额外负担的,我们可以做并发控制,减少共享资源的争抢。

  • 相关阅读:
    LUOGU P4113 [HEOI2012]采花
    LUOGU P4251 [SCOI2015]小凸玩矩阵
    bzoj 3230 相似子串——后缀数组
    bzoj 4453 cys就是要拿英魂!——后缀数组+单调栈+set
    洛谷 5061 秘密任务——二分图染色
    bzoj 4104 [Thu Summer Camp 2015]解密运算——思路
    bzoj 4319 cerc2008 Suffix reconstruction——贪心构造
    poj 3415 Common Substrings——后缀数组+单调栈
    CF 504E Misha and LCP on Tree——后缀数组+树链剖分
    bzoj 4278 [ONTAK2015]Tasowanie——后缀数组
  • 原文地址:https://www.cnblogs.com/nedulee/p/11832036.html
Copyright © 2020-2023  润新知