本文的总结源于林晓斌在极客时间里面的课程,为避免产生商业问题,我只是用于个人学习总结。
原文地址:https://time.geekbang.org/column/article/69862

小结

根据加锁范围:MySQL里面的锁可以分为:全局锁、表级锁、行级锁

全局锁

  1. 对整个数据库实例加锁
  2. MySQL提供全局读锁的方法:flush tables with read lock(FTWRL)
  3. 这个命令可以使整个库处于只读状态,使用该命令之后,数据更新语句、数据定义语句和更新类事务的提交语句等操作都会被阻塞。
  4. 使用场景:全库逻辑备份
  5. 风险:
  • 如果在主库备份,在备份期间不能更新,业务停摆
  • 如果在从库备份,备份期间不能执行主库同步的binlog,导致主从延迟
  1. 官方自带的逻辑备份工具Mysqldump,当Mysqldump使用参数--single-transaction的时候,会启动一个书屋,确保拿到一致性视图。而由于MVCC的支持,这个过程中数据是可以正常更新的。
  2. 一致性读是好,但是前提是引擎要支持这个隔离级别。
  3. 如果要全库只读,为什么不使用set global readonly=true的方式?
  • 在某些系统中,readonly的值会被用来做其他逻辑,比如判断主备库。所以修改global变量的方式影响太大
  • 在异常处理机制上有差异,如果执行FTWRL命令之后由于客户端发生一长段凯,那么MySQL会自动释放这个全局锁,整个库回到可以正常更新的状态。而将整个库设置为readonly之后,如果客户端发生异常,则数据库就会一直保持readonly状态,这样会导致整个库长时间处于不可写状态,风险较高。

表级锁

  1. MySQL里面表级锁有两种,一种是表锁,一种是元数据锁(metadata lock,MDL)
  2. 表锁的语法是:lock tables ... read/write
  3. 可以用unlock tables主动释放锁,也可以在客户端断开的时候自动释放。lock tables语法除了会限制别的现成的读写外,也限定了本现成接下来的操作对象
  4. 对于InnoDB这种支持行锁的引擎,一般不使用lock tables命令来控制并发,毕竟锁住整个表的影响面还是太大
  5. MDL:不需要显示使用,在访问一个表的时候会被自动加上
  6. MDL的作用:保证读写的正确定
  7. 在对一个表做增删改查操作的时候,加MDL读锁;当要对表结构变更操作的时候,加MDL写锁。读锁之间不互斥,读写锁之间,写锁之间是互斥的,用来保证变更表结构操作的安全性。
  8. MDL会直接到事务提交才会释放,在做表结构变更的时候,一定要小心导致锁住线上查询和更新。

上周问题解答

上期的问题是关于对联合主键索引和InnoDB索引组织表的解释。忘记问题了,见上一篇《05 | 深入浅出索引(下)》
表记录:

a b c d
1 2 3 d
1 3 2 d
1 4 3 d
2 1 3 d
2 2 2 d
2 3 4 d

主键a,b的聚簇索引组织顺序相当于order by a,b,也就是先按a排序,再按b排序,c无序。
索引ca的组织是先按c排序,再按a排序,同时记录主键

c a 主键部分b
2 1 3
2 2 2
3 1 2
3 1 4
3 2 1
4 2 3

这个跟索引c的数据是一模一样的。
索引cb的组织是先按c排序,再按b排序,同时记录主键

c b 主键部分a
2 2 2
2 3 1
3 1 2
3 2 1
3 4 1
4 3 2

所以,结论是ca可以去掉,cb需要保留

本期问题

备份一般都会在备库上执行,你再用--single-transaction方法做逻辑备份的过程中,如果主库上的一个小表做了一个DDL,比如给一个表加上一列。这时候,从库上会看到什么现象呢?

© 2019·蜀ICP备18036663号-1 · 本页总阅读量 · 本站总访问量 · 本站总访客数