全局锁是对整个数据库实例加锁,整个库处于只读状态。
flushtableswithreadlock
适用场景
全局锁适用于做全库逻辑备份,但是整个库处于只读状态,在备份期间,所有的更新操作、DDL将会被阻塞,会对业务产生影响。
single-transaction
mysqldump备份时可以使用–single-transaction参数,在备份数据之前启动一个事务,借助于MVCC获取到一致性视图,保证在备份的过程中,还支持数据的更新操作。
但是single-transaction只能用于支持事务的引擎,比如MyISAM不支持事务,所以使用MyISAM引擎的时候,是无法使用single-transaction的。
表级锁表级锁分为表锁和元数据锁。
表锁表锁从名字上就可以看出锁的是数据库表(Table),语法为:
#锁住某张表locktables表名read/write#释放锁unlocktables表名
因为表锁的粒度太大,将整张表锁住,所以一般不使用表锁。
元数据锁MDL元数据锁(metadatalock)不需要显示的使用,访问表的时候会自动添加MDL锁,添加MDL锁的原因是防止表结构出现不一致,假设查询数据的过程中,突然表结构被修改了,与最开始拿到的表结构不一致,在某些场景下可能会影响非常大。
MDL读锁
在对表做增删改查的时候,添加的是MDL读锁。
为什么添加的是读锁?
因为读锁之间不互斥,可以保证多个线程同时对一张表进行增删改查。
MDL写锁
在对表结构做修改的时候,添加的是MDL写锁。
为什么是写锁?
因为写锁与读锁之间相互互斥,当然写锁和写锁之间更是互斥的,既然要保证数据修改的安全性,那么如果有读操作在进行,是不能进行表结构变更操作的,反之亦是如此,如果正在修改表结构,也是不能进行读操作的,必须要等待前一个操作完成才可以进行下一个操作。所以使用了写锁,通过互斥保证数据操作的安全性。
需要注意的是在事务中添加MDL锁的时候,直到整个事务提交后才会释放锁,如果此时遇到长事务,就会一直占用锁。如果在这种情况下需要修改表结构,可以通过以下两种方式:
通过innodb_trx查询事务的trx_mysql_thread_id,将事务kill掉:
mysqlSELECTtrx_id,trx_state,trx_started,trx_mysql_thread_id,trx_auto