MySQL实战45讲 第六、七讲笔记

数据库的锁

按范围划分,mysql里面的锁大致分为全局锁,表级锁和行级锁

全局锁

Flush tables with read lock;

使用命令FTWRL后,整个库处于只读状态.

全局锁的典型使用场景是,做全库逻辑备份.
当 mysqldump 使用参数–single-transaction的时候,导数据之前就会启动一个事务,来确保拿到一致性视图。而由于 MVCC 的支持,这个过程中数据是可以正常更新的.如果直接使用mysqldump的话,会导致加上全局锁,业务基本不可用.
开启事务(可重复读)即可得到一致性视图.但是需要引擎支持
当引擎不支持的情况下,FTWRL就很有必要了.

表级锁

表锁一般是在数据库引擎不支持行锁的时候才会被用到的。

表锁

lock tables … read/write
unlock tables

元数据锁

meta data lock,MDL

MDL 不需要显式使用,在访问一个表的时候会被自动加上。MDL 的作用是防止DDL和DML并发引发冲突.
事务中的 MDL 锁,在语句执行开始时申请,但是语句结束后并不会马上释放,而会等到整个事务提交后再释放。

如何安全地给小表加字段?
资源首先我们要解决长事务,事务不提交,就会一直占着 MDL 锁。在 MySQL 的information_schema 库的 innodb_trx 表中,你可以查到当前执行中的事务。如果你要
做 DDL 变更的表刚好有长事务在执行,要考虑先暂停 DDL,或者 kill 掉这个长事务。

行级锁

mysql的行锁是在引擎层由各个引擎自己实现的.行级锁即InnoDB的行锁.

锁的释放

在事务当中,行锁在需要时加上,因为两阶段提交的缘故,在事务结束时释放.所以在事务当中,最可能造成锁冲突,最可能影响并发度的锁尽量往后放.

死锁和死锁检测

事务互相等待资源释放并持有资源时,会出现死锁.
死锁解决方案:

  • 设置等待超时,这个超时时间可以通过参数innodb_lock_wait_timeout 来设置。
  • 发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑
    热点行更新解决方案:

控制访问相同资源的并发事务量。

  • 关闭死锁检测,但要保证业务一定不会出现死锁(有风险)
  • 控制并发度,对于相同行的更新,在进入引擎之前排队.实现在数据库服务端/中间件上.
  • 逻辑行拆分,一行拆为多行,然后进行上层逻辑随机命中物理行.

你可能感兴趣的:(MySQL实战45讲 第六、七讲笔记)