MySQL 四 锁

四、MySQL 锁
1、 锁用于数据库并发控制
2、    死锁案例:
        1)将投资的钱拆封几份借给借款人,这时处理业务逻辑就要把若干个借款人一起锁住 select * from xxx where id in (xx,xx,xx) for update。
        2)批量入库,存在则更新,不存在则插入。解决方法 insert into tab(xx,xx) on duplicate key update xx='xx'。
3、 对待死锁常见的两种策略:
    1)通过 innodblockwait_timeout 来设置超时时间,一直等待直到超时;
        InnoDB 默认是使用设置死锁时间来让死锁超时的策略,默认 innodblockwait_timeout 设置的时长是 50s。
    2)发起死锁检测,发现死锁之后,主动回滚死锁中的某一个事务,让其它事务继续执行。
        设置 innodbdeadlockdetect 设置为 on 可以主动检测死锁,在 Innodb 中这个值默认就是 on 开启的状态。
4、 查看死锁
    使用命令 show engine innodb status 查看最近的一次死锁。
    InnoDB Lock Monitor 打开锁监控,每 15s 输出一次日志。使用完毕后建议关闭,否则会影响数据库性能。
5、 MySQL 提供了全局锁、表级锁、行级锁。
6、 InnoDB 支持表级锁和行级锁,MyISAM 只支持表级锁
7、 全局锁:对整个数据库实例加锁,它的典型使用场景就是做全库逻辑备份。 
    这个命令可以使整个库处于只读状态。使用该命令之后,数据更新语句、数据定义语句、更新类事务的提交语句等操作都会被阻塞。
8、 全局锁会导致的问题
    1)如果在主库备份,在备份期间不能更新,业务停摆,所以更新业务会处于等待状态
    2)如果在从库备份,在备份期间不能执行主库同步的 binlog,导致主从延迟
9、 如果使用全局锁进行逻辑备份就会让整个库成为只读状态,幸好官方推出了一个逻辑备份工具 MySQLdump 来解决了这个问题,只需要在使用 MySQLdump 时,
    使用参数 -single-transaction 就会在导入数据之前启动一个事务来保证数据的一致性,并且这个过程是支持数据更新操作的。
10、设置数据库为全局只读锁的两种方法:
    1)使用命令 flush tables with read lock(简称 FTWRL)就可以实现设置数据库为全局只读锁
    2)set global readonly=true 设置数据库为只读
11、两种方法的区别:FTWRL 和 set global readonly=true 都是设置整个数据库为只读状态,但他们最大的区别就是,当执行 FTWRL 的客户端断开之后,整个数据库会取消只读,
    而 set global readonly=true 会一直让数据处于只读状态。    
12、MySQL 里标记锁有两种:表级锁、元数据锁(meta data lock)简称 MDL。MDL不需要显式使用,在访问一个表的时候会被自动加上。
    表级锁的语法是 lock tables t read/write。可以用 unlock tables 主动释放锁,也可以在客户端断开的时候自动释放。
13、在对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结构变更操作的时候,加 MDL 写锁
14、MDL 会直到事务提交才会释放,在做表结构变更的时候,一定要小心不要导致锁住线上查询和更新
15、InnoDB行锁到底锁了什么?
    InnoDB的行锁是通过给索引上的索引项加锁来实现的。只有通过索引条件进行数据检索,InnoDB才使用行级锁,否则InnoDB将使用表锁,锁住索引的所有记录
16、表锁与行锁的区别:
    锁定粒度:表锁 > 行锁
    加锁效率:表锁 > 行锁
    冲突概率:表锁 > 行锁
    并发性能:表锁 < 行锁    
17、行锁的算法:
    记录锁 Record Locks        单个行记录上的锁。锁住具体的索引项
    间隙锁 Gap Locks        锁定一个范围,不包括记录本身。锁住索引不存在的区间(左开右开)。只在RR事务隔离级别存在
    临键锁 Next-key Locks    锁定一个范围,包括记录本身。锁住索引的记录+区间(左开右闭)。是 InnoDB默认的行锁算法
18、间隙锁是专门用于解决幻读问题的锁,它锁的了行与行之间的间隙,能够阻塞新插入的操作。 间隙锁的引入也带来了一些新的问题,比如:降低并发度,可能导致死锁。
19、自增锁 AUTO-INC Locks:针对自增列自增长的一个特殊的表级别锁。默认取值1,代表连续,事务未提交ID永久丢失
    show variables like 'innodb_autoinc_lock_mode';
20、共享锁:又称读锁 (read lock)。行锁。是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有的共享锁。
    如果事务对读锁进行修改操作,很可能会造成死锁。
    解决不可重复度问题
    加锁释锁方式:select * from users WHERE id=1 LOCK IN SHARE MODE;    commit/rollback
21、排它锁 exclusive lock:又称写锁(writer lock)。行锁。悲观锁。会阻塞所有的排它锁和共享锁。
    解决賍读问题
    加锁释锁方式:
        delete / update / insert 默认加上X锁
        SELECT * FROM table_name WHERE ... FOR UPDATE
        commit/rollback
22、悲观锁是由数据库自己实现了的,要用的时候,我们直接调用数据库的相关语句就可以了
23、共享锁和排它锁是悲观锁的不同的实现,它俩都属于悲观锁的范畴
24、乐观锁是用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值