全局锁和表锁
全局锁
- 加全局读锁:Flush tables with read lock(FTWRL),做全库逻辑备份
- mysqldump -single-transaction 会启动一个事务,确保拿到一致性视图(适用于所有的表使用事务引擎的库)
为什么不用 set global readonly = true ?
- readonly 可能会被用来判断一个库是主库还是从备库
异常处理机制有差异
- FTWRL 命令,若客户端异常断开,MYSQL 会自动释放这个全局锁
- 客户端异常断开时,readonly 会一直保持该状态,导致库长时间不可写。
- readonly 对 super 权限无效
表级锁
表级锁
- lock tables ... read/write
元数据锁(meta data lock, DML)
行锁
- 需要时才加上
- 不需要时,不会立即释放,事务结束时才会释放
概要: 读锁之间不互斥,读写锁,写锁之间互斥,用来保证变更表结构操作的安全性
如何安全的给小表加字段?
- 解决长事务
- information_schema 库中的 innodb_trx 表中,可以查询到当前执行中的事务。
- 请求很频繁的表,在 alter table 语句中设定等待时间,等待时间内拿到 MDL 写锁就执行添加,没拿到就先放弃,之后再重试
ALTER TABLE tbl_name NOWAIT add column ...
ALTER TABLE tbl_name WAIT N add column ...
死锁解决策略
- 直接进入等待,直到超时,通过 innodb_lock_wait_timeout 来设置超时时间(默认 50s)。
- 发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。innodb_deadlock_detect 参数设置为 on,开启此逻辑
死锁: 当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致几个线程都进入无线等待的状态,称为死锁
热点行更新导致的 CPU 性能问题 解决策略
- 若业务一定不会出现死锁情况,那就可以把死锁检测关掉
- 控制并发度(客户端不太可行,做在数据库服务端)
- 对于相同行的更新,在进入引擎之前排队。
- 从设计上优化,将一行改成逻辑上的多行来减少锁冲突
本文为Larwas原创文章,转载无需和我联系,但请注明来自larwas博客 https://larwas.com
最新评论