Проблема со связкой MySQL+SPHINX при больших объемах возвращаемых данных

5 Сен
2011

В одном очень интересном проекте у нас использовался MySQL и Sphinx. Первый в качестве сервера баз данных, а второй — в качестве поискового сервера по этим данным. Вот только не нужно снобизма. Многие веб проекты его используют. Работает и ладно. Мы поддерживаем все базы данных, которые поддерживает Django. У нас уровень доступа к данным (ORM) взят из этого проекта.
Гром, как это часто случается, прогремел среди ясного неба. Перестала индексироваться база событий с ошибкой, ноги которой растут из MySQL.
indexer --all --rotate -c /home/vs/app/sphinx.conf
Sphinx 0.9.9-rc2 (r1785)
Copyright © 2001-2009, Andrew Aksyonoff
using config file '/home/vs/app/sphinx.conf'...
indexing index 'events_eventssphinx'...
ERROR: index 'events_eventssphinx': sql_query: Incorrect key file for table
'/tmp/#sql_15e2_1.MYI';
try to repair it (DSN=mysql://root:***@localhost:3306/scrapy).
total 0 docs, 0 bytes
total 368.361 sec, 0 bytes/sec, 0.00 docs/sec
total 0 reads, 0.000 sec, 0.0 kb/call avg, 0.0 msec/call avg
total 0 writes, 0.000 sec, 0.0 kb/call avg, 0.0 msec/call avg

Вроде бы все понятно. Надо «полечить» таблицу и все встанет на свои места. Только вот таблица – временная. Создается она во время выполнения запроса и после его окончания – удаляется. Так что просто решить проблему таким «лечением» не получится. Если честно, то за то время, которое я потратил на то, чтобы разобраться с этой проблемой, я перепробовал множество изменений настройки и даже переносил все данные в другую базу, которая расположена на совершенно другой физической машине (первоначальный источник проблемы «живет» в виртуальной машине).
Описание проблемы нашлось и в багтрекере MySQL: bugs.mysql.com/bug.php?id=12291. Правда, только описание. Решения там нет. Проблема в нашем случае исходила из того, что при индексации Sphinx выкачивает из MySQL огромное количество информации. MySQL отдавал все нормально пока объемы выдаваемой информации были небольшими, но решил «поломаться» когда ее размер превысил некоторую критическую величину.
Решение нашлось простое и эффективное. Вместо того, чтобы запрашивать у MySQL данные «одним куском» в Sphinx есть настройка, которая позволяет определить по сколько записей брать за один раз. В итоге, в нашем файле конфигурации Sphinx добавились следующие строчки:
sql_query_range = SELECT MIN(id),MAX(id) FROM events_events
sql_range_step = 5000
Запрос в параметре sql_query был изменен и к нему добавились параметры $start и $end, например «…and ee.id >=$start and ee.id <=$end». Именно в таком виде, а то некоторые записи могут «потеряться» при индексации.
Более подробно о настройке Sphinx для работы с «порционной закачкой» можно прочитать в документации: www.sphinxsearch.com/docs/current.html#ranged-queries
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх