mysql 全局锁和表锁

全局锁和表锁

全局锁

  • 加全局读锁: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
请先登录后发表评论
  • latest comments
  • 总共0条评论