我的场景中有两个表
table1, which has about 20 tuples
table2, which has about 3 million tuples
table2 has a foreign key referencing table1 "ID" column.
当我尝试执行以下查询时:
ALTER TABLE table1 MODIFY vccolumn VARCHAR(1000);
它需要永远。为什么要花这么长时间?我读过它不应该,因为它只有20个元组。
有什么方法可以在不导致服务器停机的情况下加快速度吗?因为查询也锁定表。
我猜ALTER TABLE正在等待元数据锁定,并且它实际上尚未开始更改任何内容。
什么是元数据锁定?
对表运行任何查询(如SELECT / INSERT / UPDATE / DELETE)时,它必须获取元数据锁。这些查询不会互相阻塞。该类型的任何数量的查询都可以具有元数据锁定。
但是,诸如CREATE / ALTER / DROP / TRUNCATE / RENAME之类的DDL语句或事件CREATE TRIGGER或LOCK TABLES,必须获得独占的元数据锁。如果任何事务仍然保留元数据锁,则DDL语句等待。
您可以证明这一点。打开两个终端窗口,然后在每个窗口中打开mysql客户端。
CREATE TABLE foo ( id int primary key );
START TRANSACTION;
窗口1:SELECT * FROM foo;
-表格没有数据没关系
窗口2:DROP TABLE foo;
-请注意
视窗1: SHOW PROCESSLIST;
+-----+------+-----------+------+---------+------+---------------------------------+------------------+-----------+---------------+
| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined |
+-----+------+-----------+------+---------+------+---------------------------------+------------------+-----------+---------------+
| 679 | root | localhost | test | Query | 0 | starting | show processlist | 0 | 0 |
| 680 | root | localhost | test | Query | 4 | Waiting for table metadata lock | drop table foo | 0 | 0 |
+-----+------+-----------+------+---------+------+---------------------------------+------------------+-----------+---------------+
您可以看到放置表正在等待表元数据锁定。等一下 等待多长时间?直到窗口1中的事务完成为止。最终它将在lock_wait_timeout
几秒钟后超时(默认情况下,它设置为1 year)。
视窗1: COMMIT;
窗口2:请注意,它停止等待,并立即放下桌子。
所以,你可以做什么?确保没有长时间运行的事务阻塞您的ALTER TABLE。即使是对您的表进行了快速SELECT的事务,也将保持其元数据锁定,直到事务提交。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句