#python #mysql #django
#python #mysql #django
Вопрос:
Я запускаю сайт django с MySQL в качестве серверной части базы данных. Наконец, у меня есть 3 миллиона строк в таблице django_session. Срок действия большинства из них истек, поэтому я хочу их удалить. Но если я запускаю вручную delete from django_session where expire_date < "2011-04-18"
, кажется, что весь сайт зависает — к нему невозможно получить доступ через браузер.
Почему возможен такой вид блокировки? Как этого избежать?
Ответ №1:
Если ваша таблица MyISAM
, DELETE
операции блокируют таблицу, и она недоступна для параллельных запросов.
Если требуется удалить много записей, таблица заблокирована слишком надолго.
Разделите свой DELETE
оператор на несколько более коротких пакетов.
Ответ №2:
Я не эксперт по MySQL, но я предполагаю, что MySQL блокирует таблицу для удаления, и это может быть связано с транзакцией MySQL / серверной частью. Когда выполняется удаление, MySQL блокирует доступ к таблице из других подключений. Поведение серверной части MyISAM и InnoDB может отличаться. Я предлагаю вам изучить руководство по MySQL, связанное с этим: проблема не ограничивается доменом Django, но в целом, как удалить строки MySQL, не блокируя доступ к таблице.
Для дальнейшего использования я предлагаю вам настроить задачу очистки сеанса, которая будет очищать сеансы, скажем, один раз в день, из cron, чтобы у вас не получилось такой огромной таблицы.
Комментарии:
1. Да, в будущем не позволяйте этому расти так сильно. Существует команда управления, которую вы можете периодически запускать (возможно, с помощью cron), которая удалит строки с истекшим сроком действия.
Ответ №3:
Вы могли бы попробовать пример команды очистки — http://docs.djangoproject.com/en/dev/topics/http/sessions/?from=olddocs#clearing-the-session-table — который удаляет все сеансы с истекшим сроком действия, я думаю.
Ответ №4:
Если я правильно помню, в столбце expire_date нет индекса Работа с большим количеством строк займет некоторое время. Пока это происходит, это также сохранит блокировку таблицы (по крайней мере, в MyISAM).
Возможно, вам было бы лучше удалять на основе первичного ключа (например, id), пока у вас не останется меньше строк в таблице django_session. Как только у вас останется меньше строк, вы можете добавить индекс в expire_date и убедиться, что вы регулярно запускаете команду cleanup.
Вам нужно будет оценить, с чего начать удаление, но предполагая, что вы знаете, что все строки с идентификатором менее 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;
Конечно, вам, вероятно, следует создать скрипт для этого.
В общем, вы хотите удалять меньше строк за раз. В целом это займет больше времени, но это не должно блокировать ваш сайт слишком надолго за один раз.