MySQL& django挂起了巨大的会话删除

时间:2011-04-18 13:03:03

标签: python mysql django

我正在使用MySQL作为数据库后端运行django站点。 最后我在django_session表中有3百万行。他们中的大多数都已过期,因此我想删除它们。 但如果我手动运行delete from django_session where expire_date < "2011-04-18"整个网站似乎被绞死 - 它无法通过浏览器访问。

为什么会出现这种阻塞?如何避免呢?

4 个答案:

答案 0 :(得分:5)

如果您的表格为MyISAM,则DELETE操作会锁定表格,并发查询无法访问该表格。

如果要删除的记录很多,表格会被锁定太长时间。

将您的DELETE语句拆分为几个较短的批次。

答案 1 :(得分:1)

我不是MySQL专家,但我猜MySQL会锁定表以进行删除,这可能与MySQL事务/后端相关。当删除正在进行时,MySQL阻止从其他连接访问该表。 MyISAM和InnoDB后端行为可能有所不同。我建议你学习与此相关的MySQL手册:问题不仅限于Django域,而且一般如何删除MySQL行而不阻止访问表。

为了将来的参考,我建议你设置一个会话清理任务,它将清除会话,让我们说一天一次,从cron开始,这样你就不会得到如此巨大的表格。

答案 2 :(得分:0)

您可以尝试使用示例清理命令 - http://docs.djangoproject.com/en/dev/topics/http/sessions/?from=olddocs#clearing-the-session-table - 它会删除我认为的所有过期会话。

答案 3 :(得分:0)

如果我没记错,expire_date列上没有索引在很多行上运行需要一段时间。虽然这种情况正在发生,但它也会锁定桌面(至少在MyISAM中)。

您可能最好根据主键(例如id)删除,直到django_session表中的行数较少为止。行数较少后,可以向expire_date添加索引,并确保定期运行cleanup命令。

您必须估计从哪里开始删除,但假设您知道ID小于2,900,000的所有行都需要删除:


delete from django_session where id < 29000000;

为了避免长时间锁定表,您可能希望一次删除几千行,每行都在他们自己的事务中,例如


begin;
delete from django_session where id < 10000;
commit;
begin;
delete from django_session where id < 20000;
commit;
...
begin;
delete from django_session where id < 29000000;
commit;

当然你应该创建一个脚本来执行此操作。

通常,您希望一次删除较少的行。它总体上需要更长时间,但它不应该一次性锁定您的网站太久。