Python / SQLite - база данных заблокирована, несмотря на большие таймауты - PullRequest
7 голосов
/ 08 апреля 2010

Я уверен, что упускаю что-то довольно очевидное, но я не могу на всю жизнь остановить сбой моих сценариев pysqlite с базой данных - ошибка блокировки. У меня есть два сценария, один для загрузки данных в базу данных и один для чтения данных, но оба будут часто и мгновенно зависать в зависимости от того, что другой делает с базой данных в любой момент времени. Время ожидания обоих сценариев установлено на 30 секунд:

cx = sqlite.connect("database.sql", timeout=30.0)

И мне кажется, что я вижу некоторые доказательства того, что тайм-ауты заключаются в том, что я получаю то, что выглядит как отметка времени (например, 0.12343827e-06 0.1 - и как мне остановить печать)? Время от времени сбрасывается в середине моих проклятий отформатированный выходной экран, но без задержки, которая когда-либо удаленно приближается к 30-секундному таймауту, но все равно один из других снова и снова падает из-за этого. Я использую RHEL 5.4 на 64-разрядном 4-процессорном блейд-сервере IBM HS21 и слышал некоторые упоминания о проблемах с многопоточностью, и я не уверен, что это может быть актуально. Используются пакеты sqlite-3.3.6-5 и python-sqlite-1.1.7-1.2.1, и обновление до новых версий за пределами официальных положений Red Hat не является для меня хорошим вариантом. Возможно, но не желательно из-за окружающей среды в целом.

У меня ранее было autocommit=1 в обоих сценариях, но с тех пор я отключил оба, и теперь я cx.commit() включаю сценарий вставки и не фиксирую сценарий выбора. В конечном итоге, поскольку у меня есть только один сценарий, который на самом деле вносит какие-либо изменения, я не понимаю, почему такая блокировка должна происходить. Я заметил, что это значительно хуже со временем, когда база данных стала больше. Недавно он составил 13 МБ с 3 одинаковыми таблицами, что дало данные за 1 день. Создание нового файла значительно улучшило это, что кажется понятным, но время ожидания в конечном итоге просто не соблюдается.

Любые указатели очень ценятся.

РЕДАКТИРОВАТЬ: после запроса я смог немного реструктурировать свой код и использовать сигнал для периодической записи от 0 до 150 обновлений в одной транзакции каждые 5 секунд. Это значительно уменьшило количество случаев блокировки до менее одного часа, а не раз в минуту или около того. Я думаю, я мог бы пойти дальше, обеспечив смещение времени записи данных на несколько секунд, когда я читаю данные в другом сценарии, но, по сути, я работаю над проблемой, когда я ее воспринимаю, поэтому время ожидания не требуется, что все еще не прав. Та.

Ответы [ 3 ]

3 голосов
/ 07 сентября 2010

В ранних версиях pysqlite параметр timeout для sqlite.connect явно интерпретируется как миллисекунды. Таким образом, ваш timeout=30.0 должен быть timeout=30000.

1 голос
/ 13 мая 2010

SQLite просто не оптимизирован для тяжелых рабочих нагрузок при записи, и при этом он не претендует на это (но он не против написать много в одной транзакции).Для меня это звучит так, как будто вы можете перейти к точке, где вам нужно переключиться на другую базу данных, такую ​​как MySQL, PostgreSQL, Oracle или DB2.Некоторые из этих вариантов действительно дороги, но для некоторых рабочих нагрузок это то, что вам нужно.(Также обратите внимание, что тяжелые при записи рабочие нагрузки, как правило, лучше выполнять с помощью выделенного сервера баз данных, несмотря на тот факт, что это увеличивает затраты и сложность развертывания. Некоторые вещи просто стоят .)

0 голосов
/ 08 апреля 2010

SQLite использует блокировку базы данных для каждой записи (обновление / вставка / удаление / ...). ИМХО, эта блокировка удерживается до завершения транзакции. Это одиночная блокировка для потоков / процессов, AFAIK.

Итак, я бы попытался явно завершить транзакцию и соединение для написания сценария и явно зафиксировать даже при чтении сценария и попытаться отладить проблемы параллелизма.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...