向MySQL表添加INDEX时的CPU使用率问题

问题描述

具有数十亿行的表。我正在使用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 tabledrop table ...这些语句不同于DML操作,例如insert,{ {1}},updateselect操作将更改表架构,而DDL操作仅影响行。
其次,innodb中有多个众所周知的锁,例如行锁,下一键锁。但是MetaData锁很少有人知道。DML操作将获取专有的MetaData锁以保证数据的一致性,这将阻止DDL操作。在什么情况下DML操作会导致没有MetaData锁定的数据异常,您可以参考bug#989

如何无障碍地进行DDL

如今,mysql支持在线ddl进行DDL操作而没有锁定。 在线ddl中没有任何魔术,只需创建具有相同结构的新表,并对新表进行DDL语句,然后使用旧表重命名新表即可。

要向表中添加索引而不会在UPDATE / INSERT上导致锁定,可以使用以下语句格式:

DDL