06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍?
根据加锁的范围,MySQL 里面的锁大致可以分成全局锁、表级锁和行锁三类。
可以通过命令 flush tables with read lock(FTWRL) 开启全局锁,开启后整个库处于只读状态,开启后其它线程的以下操作会被阻塞:
全局锁的使用场景是做全库逻辑备份,即把整个库每个表 select 出来保存为文本。
如果做备份的时候,会引起多个表之间数据不一致,备份得到的库不是一个逻辑时间点。
官方自带的 mysqldump 工具可以使用参数 --single-transaction,导出数据的时候就会开启事务,确保导出的数据是一致的,而且由于有 MVCC 的支持,导出数据的时候其它线程可以执行更新操作。
为什么还要 FTWRL
使用 mysqldump 的 single-transaction 参数的前提是存储引擎要支持事务,而 MyISAM 引擎是不支持事务的,这时候只能用 mysqldump --single-transaction 的方法来确保导出的数据是一致的。
readonly 的方法也能使整个库进入只读状态,但是会有问题:
MySQL 中表级锁有两种:
表锁可以用 unlock tables 释放,也可以在客户端断开连接时候释放
使用举例:
sqllock tables t1 read, t2 write;
上面例子的作用是:

如上图,修改线上数据库的表结构是有风险的。
如何安全地给小表加字段?
解决长事务,事务不提交就会一直占着 MDL 锁。可以查询 information_schema 库的 innodb_trx 表看是否有长事务在执行,如果要修改结构的表正在有事务执行,要么等待完成,要么 kill 掉,再执行修改表结构的操作。
可以在 alter table 里设置等待时间
sqlALTER TABLE tbl_name NOWAIT add column ...
ALTER TABLE tbl_name WAIT N add column ...
本文作者:菜宝熊
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!