0%

mysql45-2

锁机制

  • mysql 里面的锁可以大致分成全局锁,表级锁和行锁

全局锁

全局锁对整个数据库实例加锁
Flush tables with read lock(FTWRL)
当使用这个命令后,其他线程的一下语句会被阻塞:数据更新语句,数据定义语句和更新类事务的提交语句
典型使用场景是做全局逻辑备份

  • 主库上备份,业务会停摆
  • 从库上备份,备份期间不能执行主库同步过来的 binlog,导致主从延迟
    官方自带的逻辑备份工具是 mysqldump,当使用参数-single-transaction 的时候,导数据之前就会启动一个事务,确保拿到一致性视图
  • myisam 不支持事务的引擎,这时就需要使用 FTWRL
  • 不建议使用 set global readonly = true

表级锁

lock tables … read/write
可以使用 unlock 主动释放,也可以在客户端断开的时候自动释放

count(*)

  • MyiSAM 把表的总行数存在了磁盘上,因此效率很高
  • innodb 需要一行一行统计
  • 在保证逻辑正确的前提下 尽量减少扫描的数据量 是数据库系统设计的通用法则之一
  • show table status 返回很快 但是不准确
  • innodb 可以将计数保存到一张表中,使用事务,保持了一致性
  • count(id) innodb 会遍历整张表,把每一行的 id 都取出来,返回给 server 层,server 层拿到 id 后,判断是不可能为空的,就按行累加
  • count(1) innodb 引擎便利整张表,但不取值,server 层对返回的每一行,放一个数字 1 进去,判断是不可能为空的,按行累加
  • count(字段)
    • 如果是 not null 就一行行独读出,判断不能为 null,按行累加
    • 如果允许为 null,不是 null 才累加
  • count(*)做了优化,按行累加

答疑 1

  • insert on duplicate 确保了在事务内部,执行 SQL 后占住了这个行锁