我们在用户在 Drupal 中运行查询/视图时遇到问题,这有时会导致我们的网站冻结。发生冻结是因为查询导致数据库连接数上升到 400+,并且基本上只要站点超过 100 个数据库连接,站点就会非常慢并且没有响应。
我们正在使用 MySQL Red Hat Linux 运行 Amazon RDS
我们在前端应用服务器上有足够大的EC2,以及足够大的RDS。
我们现在解决这个问题的方法是找到有问题的查询,并杀死它。一旦查询被终止...我们的数据库连接将下降到大约 20,这是您在监视站点统计信息时看到的正常数量。
有没有办法停止有问题的查询并在它运行太长时间并消耗连接之前将其杀死?我试图在错误查询发生之前自动终止它,或者至少在 30 秒后意识到它是一个错误查询并终止它。
这是一个杀死长时间运行的 SELECT 的存储过程
DELIMITER $$
DROP PROCEDURE IF EXISTS `test`.`Kill_Long_Running_Selects` $$
CREATE PROCEDURE `test`.`Kill_Long_Running_Selects` (time_limit INT,display INT)
BEGIN
DECLARE ndx,lastndx INT;
DROP TABLE IF EXISTS test.LongRunningSelects;
CREATE TABLE test.LongRunningSelects
(
id INT NOT NULL AUTO_INCREMENT,
idtokill BIGINT,
PRIMARY KEY (id)
) ENGINE=MEMORY;
INSERT INTO test.LongRunningSelects (idtokill)
SELECT id FROM information_schema.processlist
WHERE user<>'system user' AND info regexp '^SELECT' AND time > time_limit;
SELECT COUNT(1) INTO lastndx FROM test.LongRunningSelects;
SET ndx = 0;
WHILE ndx < lastndx DO
SET ndx = ndx + 1;
SELECT idtokill INTO @kill_id
FROM test.LongRunningSelects WHERE id = ndx;
CALL mysql.rds_kill(@kill_id);
END WHILE;
IF lastndx > 0 THEN
IF display = 1 THEN
SELECT GROUP_CONCAT(idtokill) INTO @idlist FROM test.LongRunningSelects;
SELECT @idlist IDs_KIlled;
SELECT CONCAT('Processes Killed : ',lastndx) Kill_Long_Running_Selects;
END IF;
END IF;
END $$
Run Code Online (Sandbox Code Playgroud)
要杀死运行时间超过 30 秒的 SELECT,请运行以下命令
CALL test.Kill_Long_Running_Selects(30,0);
Run Code Online (Sandbox Code Playgroud)
如果你想看到连接被杀死,你运行这个
CALL test.Kill_Long_Running_Selects(30,1);
Run Code Online (Sandbox Code Playgroud)
也许你可以创建一个 MySQL 事件来每分钟调用这个存储过程。
如果 Amazon 不让您拥有EVENT权限,您将必须在 EC2 服务器上编写外部 shell 脚本以连接到数据库并运行存储过程。该 shell 脚本可以放入 crontab 中。
如果 Amazon 不允许您拥有PROCESS和SUPER权限,您可能需要将数据库从 RDS 移到另一个运行 MySQL 的 EC2 实例中来完成此操作。然后,您可以创建不受 Amazon 托管限制的 MySQL 事件。
归档时间: |
|
查看次数: |
26063 次 |
最近记录: |