- MySQL的锁分类?
- 根据锁的范围分为全局锁、表级锁、行级锁
- 全局锁
- MySQL提供了一个对整个数据库加读锁的操作,当需要做全库逻辑备份时使用,在备份过程中,数据库为只读状态
- 全局锁的问题
- 在主库备份,备份期间业务停摆,无法进行更新操作
- 在从库备份,备份期间不能执行主库过来的binlog,导致主从延迟
- 如果备份不加锁呢?比如用户使用会员余额买了一门课,首先用户课程表+1其次扣除用户余额,如果先备用余额表,那么出现不花钱买书的情况。反过来就会出现花钱没买到课程的情况 结论就是不加锁备份的数据库的数据不一致的情况
- 全局锁的问题解决
- 在隔离级别为可重复读的情况下,备份数据时会开启一个新的事务,能够得到一致性视图,而由于MVCC的支持,用户也能够支持更新操作 称之为一致性读
- 但并不是索引的引擎都支持事务,比如MyISAM,在备份的过程中总是能够拿到最新的数据,所以需要有全局锁的存在
- 全局锁的问题
- MySQL提供了一个对整个数据库加读锁的操作,当需要做全库逻辑备份时使用,在备份过程中,数据库为只读状态
- 表级锁
- MySQL的表级锁分为 表锁和元数据锁(MDL)
- 表锁(读锁(共享锁)和写锁(排他锁)) --显示使用
- 线程A对T1加了读锁,其它线程可以加读锁,但不能加写锁,如果对T1加写锁,则其它线程不能加读锁和写锁
- 表锁的缺点,锁的粒度太大
- 元数据锁(防止DML语句和DDL语句冲突) --隐式使用,默认执行
- 涉及增删改查的操作时会加MDL读锁,涉及修改表结构操作时,会加MDL写锁
- 多事务启动,都是读操作(MDL读锁),那么正常执行不阻塞,涉及修改表结构的操作,此时该事务申请的是MDL写锁,请求阻塞(之后的事务也将被阻塞,不可读写)事务中的MDL锁,在语句执行开始时申请,事务结束之后不会马上释放,这样会使得库的线程很快爆满
- 基于以上考虑如何安全的给表增加字段?
- 1、解决长事务,否则会一直占着MDL锁,可以等长事务执行完也可以kill掉长事务
- 2、请求频繁,kill掉之后马上又有新连接进来,设置 alter table 语句的等待时间,之后DBA手动重试,避免没拿到MDL写锁而阻塞其它业务
- 表锁一般只有在数据库引擎不支持行锁的时候才使用,这时解决方法可以是将MyIsAM引擎升级
- MDL会直到事务执行结束才释放,线上注意在做表结构变更时,不要因为锁住导致锁住查询和更新操作
- 表锁(读锁(共享锁)和写锁(排他锁)) --显示使用
- MySQL的表级锁分为 表锁和元数据锁(MDL)
- 全局锁
- 根据锁的范围分为全局锁、表级锁、行级锁
全局锁和表级锁
最新推荐文章于 2024-08-31 09:30:00 发布