LINUX.ORG.RU

[sqlite, C] Ожидание разблокирования базы данных


0

1

Вот такой вопрос: как наиболее правильно сделать, чтобы CGI, обращающийся к БД, которую уже открыл кто-то другой, ожидал, пока база не будет разблокирована?

Сейчас делаю так:

try_exec:
	rc = sqlite3_exec(db, q_str, callback, NULL, &zErrMsg);
	if(rc){
		if((rc == SQLITE_BUSY || rc == SQLITE_LOCKED) && Ntry < Ntry_max){ // база заблокирована другим вызовом
			Ntry++;
			DBG("ooops, DB is busy, try number %d", Ntry);
			usleep(50); // ждем .05с
			goto try_exec; // пробуем снова
		}
		fprintf(stderr, "SQL error: %s, %d\n", zErrMsg, rc);
		die(SQL_ERR);
	}

Но пока к базе обращаются одновременно 2-3 клиента, все ОК, если же клиентов будет очень много, такой способ может привести к длительному ожиданию (смотря какое ограничение на Ntry_max поставить), в конце которого все равно к базе данных CGI не сможет обратиться.

☆☆☆☆☆

Ответ на: комментарий от o

Та не, просто если я правильно понял, то там лочится вся БД? Ничего себе... Челябинские мужики настолько суровы, что им пулы соединений и транзакции ни по чем

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

> Та не, просто если я правильно понял, то там лочится вся БД

гораздо проще «понимать», чем пройти по ссылке и почитать как оно есть, да

aho
()

если же клиентов будет очень много

... то значит cgi-скриптам не место.

Ну и тут явно без goto можно было обойтись простым циклом do..while.

В доках этот вопрос не раскрыт? Например, сдесь: http://www.sqlite.org/lockingv3.html

Там написано что сначала нужно блокировки получить а не тупо пытаться запросо послать.

Короче, плохой код.

true_admin ★★★★★
()
Ответ на: комментарий от vertexua

sqlite блокирует весь файл, пока пишет в БД. Вариант с sqlite3_unlock_notify у меня не сработал (даже после ручного перекомпилирования sqlite).

Понятия не имею, как сделать по-человечески, чтобы sqlite ждал в течение некоторого времени, пока БД не будет разблокирована...

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Таки да, значит все-таки блокируется. Я подумал что не блокируется (еще чего, по ссылке ходить и читать там что-то). Но я рад, что свалил на нормальную встраиваемую базу в свое время.

vertexua ★★★★★
()
Ответ на: комментарий от Reset

На чтение оно вроде как не лочит. Вообще я не думаю, что ТС-у нужна какая-то серьезная параллельность.

dizza ★★★★★
()
Ответ на: комментарий от Reset

Не использовать cgi и обрабатывать все запросы к sqlite из одного процесса и одного потока.

Не годится.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от dizza

Я пилю CGI аутентификации/авторизации. Работать будет при малых нагрузках, но для аутентификации на некоторых сервисах нужно сохранить несколько кук (по одной для каждого сервиса), и тут-то иногда возникала проблема с блокировкой: CGI, запускаемый с первого POST-запроса, еще не успевает отработать, как к БД обращаются CGI, запущенные другими запросами.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Все делается очень просто — берешь evhttpd и заполняешь callback'и. Если нужен тяжелый веб-сервер типа апача, то можно сделать его как прокси к evhttpd.

Reset ★★★★★
()
Ответ на: комментарий от Eddy_Em

Зачем ты вообще стал это делать на Си да еще и с sqlite?

Есть тривиальное решение --

#!/usr/bin/perl

use CGI;
use CGI::Session;

и задача уже решена без всяких sqlite'ов и прочего траха

Reset ★★★★★
()
Ответ на: комментарий от vertexua

Есть oracle berkeleydb в которой есть всё, в том числе поддержка многопоточности и умных блокировок. Единственное что там нет это sql :)

Reset ★★★★★
()
Ответ на: комментарий от Reset

А как сохранять логины, хеши паролей, уровни доступа и пути доступа?

Так что, без БД не обойтись. И не надо мне всякую перловку рекомендовать: я уже почти закончил свою сишную CGI-библиотечку, так что, все довольно просто будет.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Ну все правильно, тебе нужно просто защититься, а так как нагрузка не большая, то и параллельность не нужна. Не знаю как там у вас в сях, но я бы каким-нибудь flock делал блокировку на специальном файле.

dizza ★★★★★
()
Ответ на: комментарий от Eddy_Em

А как сохранять логины, хеши паролей, уровни доступа и пути доступа?

Для этого достаточно файла, тем более у тебя нагрузка маленькая.

А если уж так приспичило на Си писать, то evhttpd поможет тебе во-первых уйти от рутины с обработкой протокола http, а также поможет мультиплексировать потоки данных от многих клиентов.

Reset ★★★★★
()

Вообще где тег [сипроблемы]?

vertexua ★★★★★
()
Ответ на: комментарий от Reset

Да нафига ему то? У него наверняка пара пользователей.

dizza ★★★★★
()
Ответ на: комментарий от Reset

> Единственное что там нет это sql

С какого-то релиза есть.

reader
()
Ответ на: комментарий от Reset

evhttpd поможет тебе во-первых уйти от рутины с обработкой протокола http

Что-то я там функций по работе с файлами не видел. Сейчас вот допиливаю сохранение переданного файла.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Если файл не большой, то просто пишешь/читаешь evbuffer. Если файл большой, то будет сложнее. Придется создавать поток чтения и по мере поступления данных отправлять нотификации в поток сети, относительно безгеморройно это делается только в libevent2.

Reset ★★★★★
()
Ответ на: комментарий от tensai_cirno

Чем не угодил mysql/postgres/nosql?

Громоздкостью. SQLite - простенькая легкая БД, как раз для веб-приложений. А mysql/postgresql - монстры тяжелые.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Которыми пользуются от силы пара человек.

Есть простенькие упругие nosql. Couchdb тот же, монго.

tensai_cirno ★★★★★
()
Ответ на: комментарий от Reset

> Есть oracle berkeleydb в которой есть всё, в том числе поддержка многопоточности и умных блокировок. Единственное что там нет это sql :)

SQL там тоже есть уже не менее полугода, с множественным доступом на запись и интерфейсом sqlite.

Так что если результаты разработки продаваться не будут, то BDB использовать - в самый раз. А если будут, то нарушение лицензии и всё такое.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

SQL там тоже есть уже не менее полугода, с множественным доступом на запись и интерфейсом sqlite.

фига себе, это они из key-value базы решили сделать монстра?

Так что если результаты разработки продаваться не будут, то BDB использовать - в самый раз. А если будут, то нарушение лицензии и всё такое.

лицензия требует открытия исходников программы которая использует bdb

Reset ★★★★★
()
Ответ на: комментарий от Eddy_Em

С sqlite феерия тебе гарантирована :)

Мы на прошлой работе использовали её в продакшен по-дефолту. В качестве альтернативы клиентам предлагался postgresql. Так вот, postgresql, естественно, всем было ставить лениво, поэтому это был просто лютый звиздец. Тормоза на пустом месте, потери данных, глюки, порча файла с базой ...

Поэтому, когда выпускали следующую версию софтины, то послали sqlite нафиг и сказали клиентам, что либо они ставят postgresql либо получают %%й.

Reset ★★★★★
()
Ответ на: комментарий от Reset

> фига себе, это они из key-value базы решили сделать монстра?

Это и так была не простая key-value база, а база с индексами и транзакциями. Они только припилили к ней возможность работы через интерфейс sqlite.

лицензия требует открытия исходников программы которая использует bdb

Ага. Но наверное можно изловчиться, продавая программу с общим интерфейсом для работы с БД без исходников, а плагин для bdb отдавать вместе с исходниками.

Sorcerer ★★★★★
()
Ответ на: комментарий от Reset

фига себе, это они из key-value базы решили сделать монстра?

Хватит уже вестись на этот форсед-мем, что отказ от SQL каким-то образом делает +100500 к производительности и, что самое чудесное, делает стор масштабируемым. Посмотри на VoltDB, к примеру.

dizza ★★★★★
()
Ответ на: комментарий от Reset

postgre же - жесть!

SQLite я изначально выбрал как наиболее простую БД. Раз уж по-человечески проблему блокировок решить не получается, оставлю все, как есть на данный момент: буду делать несколько попыток обращения к БД с перерывами, пока она не будет разблокирована или пока таймаут не выйдет.

Все равно рассчитывается это дело на 1-2 клиента.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Жесть это то что у тебя сейчас. usleep это одно из матерных слов в программировании :) и кстати спишь ты не 0.05c, а 0.00005 — читай внимательно man

Reset ★★★★★
()
Ответ на: комментарий от Reset

usleep это одно из матерных слов в программировании

И как же прикажете паузы делать?

спишь ты не 0.05c, а 0.00005 — читай внимательно man

Это у меня в комментарии очепятка. 50мкс жду, понятное дело (сначала ожидал 50мс, но этого оказалось многовато).

Eddy_Em ☆☆☆☆☆
() автор топика

В общем, смотрю я - толку от этой темы нет.

Удалить?

Eddy_Em ☆☆☆☆☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.