我四处寻找锁定整个数据库的解决方案,到目前为止我发现的唯一一个是FLUSH TABLES WITH READ LOCK。
这对于备份来说很好,但不幸的是,当我使用模式更改修补数据库时,我无法使用它来阻止对数据库的其他访问。如果我运行ALTER TABLE
after FLUSH TABLES WITH READ LOCK
,我会收到以下消息:
无法执行查询,因为您有一个冲突的读锁
有没有办法在我修补数据库时暂时阻止其他数据库连接访问数据库?
我不想主动拒绝其他连接,我只想让它们“暂停”,直到修补完成(几秒钟)。
我怎样才能做到这一点?
您应该能够使用一条语句锁定您打算更改(或以其他方式想要隔离,以便修改触发器)的所有表,并且您的会话将在您进行更改时保持锁定,直到您释放锁定。
例如,我这里有 3 个表,t1、t2 和 t3。我将对 t2 和 t3 进行更改,并且我将使用 t1 来说明我是否实际上仍在对 t2 和 t3 持有锁。
在 t2 和 t3 上获得写锁。任何时候您lock table
隐式释放任何其他表锁,因此您必须将它们全部锁定。您的会话将阻塞,直到您获得所有锁,然后您的提示返回。
mysql> lock table t2 write, t3 write;
Query OK, 0 rows affected (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
表 t2 已锁定,我可以更改它。
mysql> alter table t2 add column foo int default 1;
Query OK, 25 rows affected (0.81 sec)
Records: 25 Duplicates: 0 Warnings: 0
Run Code Online (Sandbox Code Playgroud)
我也可以访问 t3(恰好是空的):
mysql> select * from t3;
Empty set (0.02 sec)
Run Code Online (Sandbox Code Playgroud)
但是,我没有锁定t1,所以我什至无法从中选择。当您持有一个或多个表锁时,您只能访问您拥有锁的表。
mysql> select * from t1;
ERROR 1100 (HY000): Table 't1' was not locked with LOCK TABLES
Run Code Online (Sandbox Code Playgroud)
现在,测试在 t2 上创建一个简单的触发器,它仍然被锁定。
mysql> create trigger t2_ai after insert on t1 for each row set @foo = now();
ERROR 1100 (HY000): Table 't1' was not locked with LOCK TABLES
Run Code Online (Sandbox Code Playgroud)
哈!这是一个错字:我错误地说“在 t1 上插入后”而不是“t2”,服务器阻止我触摸我没有锁定的桌子,而我持有其他锁。但是,如果我输入正确,我可以修改我实际锁定的表上的触发器。
mysql> create trigger t2_ai after insert on t2 for each row set @foo = now();
Query OK, 0 rows affected (0.08 sec)
Run Code Online (Sandbox Code Playgroud)
毕竟,我可以通过从中进行选择来确认我仍然锁定了 t2 和 t3,并且我还可以通过尝试触摸我知道我没有锁定的桌子来确认我锁定了“某物”,( t1 再次):
mysql> select * from t1;
ERROR 1100 (HY000): Table 't1' was not locked with LOCK TABLES
Run Code Online (Sandbox Code Playgroud)
更改完成,释放您最初获得的所有锁。
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
唯一想到的警告是,如果在更改表时出现相当严重的错误(不是语法错误,而是低级错误,如 IO 错误、数据损坏和操作系统权限),则该表可能会被隐式解锁。 . 以及正如我所提到的,您必须在单个语句中获取所有表锁,因为下一个语句LOCK TABLE
将解锁您已经锁定的任何内容。
尝试访问您锁定的表的其他线程应该阻塞,直到您完成或失去连接,这将隐式释放锁,因为它们与您的连接/会话相关联。