全局锁就是对整个数据库实例加锁。全局锁的典型使用场景是,做全库逻辑备份。
-- 加全局锁 命令:Flush tables with read lock (FTWRL) -- 释放全局锁 命令:unlock tables -- 设置全局只读 set global readonly=true -- 设置全局读写 set global readonly=false
1. 全局锁在执行过程中由于客户端异常断开,会自动释放锁,而设置全库只读不会。
表锁的典型使用场景是,做读写分离,使读写分离失效。
-- 加表锁 命令:lock tables read/write table_name; -- 释放表锁 命令:unlock tables;
当对一个表进行增删改查操作时,加MDL读锁;当要对表结构进行变更操作时,加MDL写锁。
给一个小表加字段导致整个库挂掉的典型场景:
解决方案:
ALTER TABLE table_name ADD COLUMN column_name VARCHAR(50), ALGoRITHM=INPLACE, LOCK=NONE;
对于支持事务的存储引擎(如InnoDB),可以使用 single-transaction 参数来做备份,避免使用全局锁:
mysqldump --single-transaction -uroot -p database_name > backup.sql
在主从架构中使用single-transaction做备份可能会遇到的问题:
备份过程中如果主库执行了DDL:
解决方案:
全局锁主要用在逻辑备份过程中。对于全部是InnoDB引擎的库,我建议你选择使用–single-transaction参数,对应用会更友好。 表锁一般是在数据库引擎不支持行锁的时候才会被用到的。
是通过锁索引记录实现的。
在innodb中,行锁是在需要的时候加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。
两阶段锁协议:
1. 加锁阶段:事务可以获得除InnoDB外其他引擎支持的锁,InnoDB只支持行锁。
2. 解锁阶段:事务结束后,所有加的锁才会被释放。
1. 等待,直到超时。
2. 发起死锁检测,主动回滚死锁链条中的某一个事务,让其他事务继续执行。将参数innodb_deadlock_detect设置为on,表示开启这个逻辑。