我有一张包含10,000条记录precommit_tags_change_lists
的表格,对此的选择查询需要永远。
我尝试添加一个索引,如下所示,也挂起......
ALTER TABLE `precommit_tags_change_lists` ADD INDEX `change_list_id` (`change_list_id`)
以下是该表的结构,有关如何调试此问题以及可能导致此问题的任何指导?
一个观察结果是相当多的进程陷入了状态"等待表元数据锁定"在表precommit_tags_changelists
由于上述原因,数据库连接因错误Can't connect to MySQL server on '10.xx.xxx.xxx' ((1040, u'Too many connections'))")
答案 0 :(得分:1)
10k记录的表格不是很大。 ALTER TABLE最多应该在几秒钟内完成。我认为您的ALTER TABLE可能正在等待锁定表。所有其他SELECT查询也在等待,因为它们排在ALTER TABLE后面。
ALTER TABLE需要对表的独占访问权限。当ALTER TABLE完成其工作时,没有其他查询可以运行(嗯,某些类型的更改可以完成"在线"在MySQL 5.6或更高版本中,但通常没有)。此独占访问是使用元数据锁实现的。许多SELECT查询可以共享元数据锁,但ALTER TABLE无法共享。
所以我认为你真正的问题是你有一些长时间运行的查询阻碍了ALTER TABLE。您还没有显示这个长时间运行的查询。
即使在小桌子上也可以进行长时间运行的查询。它与查询的逻辑有关。您应该在流程列表中查找引用precommit_tags_change_lists
的查询,但不等待元数据锁定。它将处于某种其他状态(例如"发送数据"或"写入临时表"等),并且运行时间超过任何其他查询。
当您找到该查询时,kill it。如果它已经运行了几个小时,那么任何人都不可能仍在等待其结果。一旦您终止该查询,就会破坏logjam,并且ALTER TABLE和所有其他查询将能够完成。
根据经验,这是我的猜测。但是我必须对你的情况作出一些假设,因为你还没有提供所有相关信息。
答案 1 :(得分:0)
当连接达到配置文件中定义的最大限制时,可能会发生此错误。保存此值的变量是max_connections 要检查此变量的当前值,请以root用户身份登录并运行以下命令: 显示全局变量,如max_connections;
使用root用户登录MySQL并将max_connections变量增加到更高的值。 SET GLOBAL max_connections = 100;
为了使max_connection值持久化,请修改配置文件中的值。
永久保留更改
Stop the MySQL server:
Service mysql stop
Edit the configuration file my.cnf.
vi /etc/my.cnf
Find the variable max_connections under mysqld section.
[mysql]
max_connections = 100
Set into higher value and save the file.
Start the server.
Service mysqld start