问题描述
具有数十亿行的表。我正在使用MysqL 5.7 当我尝试向表中添加索引时,它会花费很长时间,并且也会锁定表。 结果,许多查询在队列中等待,服务器负载增加。
我不明白在向表添加索引时会创建表锁,这就是元数据锁。 您能解释一下为什么会这样吗,并提供解决方案吗?
创建表
CREATE TABLE `user_log` (
`id` bigint(14) NOT NULL AUTO_INCREMENT,`user_id` int(11) NOT NULL,`latitude` decimal(10,6) NOT NULL,`longitude` decimal(10,`created_date` date DEFAULT NULL,PRIMARY KEY (`id`),) ENGINE=InnoDB AUTO_INCREMENT=20000000000 DEFAULT CHARSET=latin1
更改命令
ALTER TABLE `user_log` ADD INDEX (`user_id`,`created_date`);
解决方法
为什么mysql为什么需要锁表
首先,mysql中有许多DDL
操作,例如alter table
,drop table
...这些语句不同于DML
操作,例如insert
,{ {1}},update
。select
操作将更改表架构,而DDL
操作仅影响行。
其次,innodb中有多个众所周知的锁,例如行锁,下一键锁。但是MetaData锁很少有人知道。DML
操作将获取专有的MetaData锁以保证数据的一致性,这将阻止DDL
操作。在什么情况下DML
操作会导致没有MetaData锁定的数据异常,您可以参考bug#989。
如何无障碍地进行DDL
如今,mysql支持在线ddl进行DDL
操作而没有锁定。
在线ddl中没有任何魔术,只需创建具有相同结构的新表,并对新表进行DDL
语句,然后使用旧表重命名新表即可。
要向表中添加索引而不会在UPDATE / INSERT上导致锁定,可以使用以下语句格式:
DDL