我需要你的帮助我有一个大约有 7 年历史的 Django 应用程序,现在一直在降级..每次网站关闭和备份时,问题都出在 mysql 服务器上
通常我只需要重新启动 mysql 服务器,它就会恢复正常。我已经这样做了 2 年了,我准备一劳永逸地解决这个问题,需要你的帮助来做到这一点
这些django_session
表有3,512,729,600
数据长度和24,152,301
行我猜这是问题的来源以及为什么网站有时会在 mysql 无法处理查询和导致应用程序终止的几次超时时死掉。如果是别的,请赐教。
无论如何,我尝试删除django_session
表格但没有运气我得到以下错误
查询错误 (1451):无法删除或更新父行:外键约束失败(
font_database
.fonts_fontfile
,CONSTRAINTsession_id_refs_session_key_37e5d4124e1e319f
FOREIGN KEY (session_id
) REFERENCESdjango_session
(session_key
))
我在这里做什么?这里需要认真的帮助
MySQL版本是5.7.23
如果您需要更多信息,请问我,我会尝试将其添加到这个问题中。
谢谢
更新:
刚刚注意到问题是 MySQL 服务器上的连接总数最大为 152
mysql> show status where `variable_name` = 'Threads_connected';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_connected | 152 |
+-------------------+-------+
1 row in set (0.74 sec)
此外,当我检查连接时,它们都来自 django_sessions,这就是为什么当我重新启动服务器时它工作正常但随后又回到相同的问题,因为会话表太高且行太多
mysql> show processlist;
+------+--------------------+-----------+--------------------+---------+------+--------------+----------------------------------------------------------------------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+------+--------------------+-----------+--------------------+---------+------+--------------+----------------------------------------------------------------------------------------------------+
| 3709 | font_database | localhost | font_database | Query | 3164 | Sending data | SELECT COUNT(*) FROM `django_session` WHERE `django_session`.`last_login` >= '2019-02-23 13:00:37' |
| 3710 | font_database | localhost | font_database | Query | 3162 | Sending data | SELECT COUNT(*) FROM `django_session` WHERE `django_session`.`last_login` >= '2019-02-23 13:00:39' |
| 3711 | font_database | localhost | font_database | Query | 3161 | Sending data | SELECT COUNT(*) FROM `django_session` WHERE `django_session`.`last_login` >= '2019-02-23 13:00:41' |
| 3714 | font_database | localhost | font_database | Query | 3133 | Sending data | SELECT COUNT(*) FROM `django_session` WHERE `django_session`.`last_login` >= '2019-02-23 13:01:09' |
| 3716 | font_database | localhost | font_database | Query | 3131 | Sending data | SELECT COUNT(*) FROM `django_session` WHERE `django_session`.`last_login` >= '2019-02-23 13:01:11' |
| 3717 | font_database | localhost | font_database | Query | 3129 | Sending data | SELECT COUNT(*) FROM `django_session` WHERE `django_session`.`last_login` >= '2019-02-23 13:01:13' |
...
...
till maxed to 152 connections
同样,如果您需要任何其他信息,请询问,我会提供。这就是我认为可以帮助您了解问题所在的所有内容
更新:(来自评论中的请求)
EXPLAIN SELECT COUNT(*) FROM django_session WHERE django_session.last_login >= '2019-02-23 13:00:37'
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE django_session NULL ALL NULL NULL NULL NULL 24200442 33.33 Using where
显示创建表 django_session
Table Create Table
django_session CREATE TABLE `django_session` (
`session_key` varchar(40) NOT NULL,
`session_data` longtext NOT NULL,
`expire_date` datetime NOT NULL,
`created` datetime NOT NULL,
`last_login` datetime NOT NULL,
PRIMARY KEY (`session_key`),
KEY `django_session_c25c2c28` (`expire_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
更新 v2:(运行后ALTER TABLE django_session ADD KEY (last_login)
)
EXPLAIN SELECT COUNT(*) FROM django_session WHERE django_session.last_login >= '2019-03-04 13:00:37'
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE django_session NULL range last_login last_login 5 NULL 1 100.00 Using where; Using index
问题是这
SELECT COUNT(*) FROM django_session WHERE django_session.last_login >= '2019-02-23 13:00:37'
是一个缓慢的查询。您的进程列表显示到目前为止这需要 3133 秒并且尚未完成。如果 django_session 中的列有索引,
last_login
这可能会更快。您还应该检查此查询在 django 中提供的内容。这似乎是一个毫无意义的数字。
我怀疑 2M 行可能覆盖了旧数据并且可能可以删除。试试这个答案中的清除方法。
建议在添加索引之前至少清除一些行。