Форум » LetoDB, HbNetio. » Leto DB Server » Ответить

Leto DB Server

alkresin: Только что открыл на Sourceforge новый проект - Leto DB Server - https://sourceforge.net/projects/letodb Это мультиплатформенный ( Windows, Unix/Linux ) сервер баз данных, предоставляющий клиентским программам доступ к dbf/cdx файлам, находящимся на удаленном сервере ( можно и на локальном компьютере запускать - в отладочных целях ). В общем, как ADS :). Проект - на стадии разработки, не все даже базовые функции еще реализованы, до оптимизации дело еще не дошло. Но работает :). Крутится у меня на сервере несколько дней, подключал до 15 клиентов, пока не падает. Мои программы работают с ним нормально. Преимущества по сравнению с обычным файл-сервером: 1) Безопасность - базы могут быть в каталоге, недоступном для клиентских компьютеров - никто их случайно не удалит и не повредит. 2) Поскольку базы открываются серверной программой, а не клиентской, ее целостности ничего не грозит при случайном отключении клиентского компьютера. 3) значительное уменьшение сетевого траффика. 4) Должен быть, по идее, выигрыш в скорости. 5) Возможность контроля за пользователями с помощью утилиты manage ( можно придумать и другие формы контроля ). 6) Можно будет сделать транзакции, stored procedures на Харборе, ... и вообще все в наших руках :). Кто хочет участвовать в разработке, тестировании - пишите.

Ответов - 325, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 All

alkresin: Ставлю set deleted on, и удаленные записи видны. Не пойму, в чем дело Если устанавливаете после присоединения, то надо leto_Setdeleted() использовать.

Pasha: А Ads как делает ? Там дополнительной команды нет, используется текущая установка клиента Может все-таки добавим 1 байт к пакету передачи ? Из тех же соображений, что незначительное увеличение размера пакета лучше, чем дополнительный пакет. Да и совместимость с существующим кодом сохранится У меня к примеру сплошь и рядом встречаются такие конструкции: Function SeekPers(nTab) Local lSD := Set(_SET_DELETED, .f.), lR, no := persons->(IndexOrd()) persons->(dbSetOrder(2)) lR := persons->(dbSeek(nTab)) persons->(dbSetOrder(no)) Set(_SET_DELETED, lSD) Return lR Это приведет к 2-м дополнительным пакетам для 1-й операции поиска

alkresin: А Ads как делает ? В ADS RDD специальная технология используется, добавленная David G.Holm именно для таких целей в set-модуль. В нашем случае, согласен, стоит передать лишний байт, в нем можно, используя битовые функции, передавать и set exact ( сейчас оно вообще не передается ), а для seek поместить и bsoftseek,bfindlast ( сейчас это 2 отдельных байта ).


Pasha: alkresin пишет: передавать и set exact set exact нужен для вычисления выражений, а они вычисляются не только для фильтра (3 операции навиации), но и при создании индекса. Значит, надо передавать и для createindex Смотрим, какие еще установки могут понадобиться на сервере. _SET_PATH, _SET_DEFAULT - наверное, не нужны HB_SET_DECIMALS - тоже на сервере нафик не нужен SET_DATEFORMAT SET_EPOCH нужен для вычисления DTOC. Поскольку в битовой струкруре эти установки не помещаются, да и это глобальные установки, которые вряд-ли динамически будут изменяться, можно передать их на сервер отдельной командой Поскольку в основном то, что было запланировано в начале февраля, уже сделано, предлагаю обсудить дальнейшие направления работ Мне кажется, можно сделать вот что (перечисляю и малозначительные, и важные пункты) - загрузка сервером некой dll, в которую пользователь мог бы добавлять свои udf для индексных выражений. Для пользователя будет проще пересобрать специально предназначенную для таких целей dll, чем пересобрать сервер - укаазание в скрипте сборки сервера кодовых страниц, для которых надо выдать Request - поддержка дополнительных числовых полей: '2', '4', а также полей VFP - надо переделать PutValue для мемо-полей - оптимизация relations: передача состояния дочерних областей прямо в leto_rec, запись их на клиенте в некую область данных, и затем использование в SELF_RELEVAL вместо передачи на сервер запроса на seek/goto - сделать leto_CloseAll() - как делать транзакции ? Для каждого юзера заводить временный dbf/fpt файл для журнала транзакций, и в каждую таблицу добавлять служебное поле, поскольку флаг deleted использовать не удастся Какой уровень транзакций ? Только read commited ? - вычисляемые поля. Здесь возникает вопрос, как вычислять на сервере выражения, которые содержат имена алиасов клиента Ведь на сервере имена алиасов свои. Можно это разрешать имена алиасов поиском "->" и заменой - может быть стоит сделать возможность открытия таблицы с ограниченным количеством полей Для каких-то выборок понадобятся не все поля, которые присутствуют в таблице, а какой-то их набор. Это был бы такой суррогат sql-запросов

alkresin: Из базовой функциональности осталась ( если я не упустил еще что-то ) реализация orderListClear. Несмотря на кажущуюся простоту, там есть неприятные моменты. После этого можно делать поддержку ntx. Думаю, для этого надо прописывать в серверном ini [DATABASE] ( вот к ним и подобрались :) ) и там помечать ее как ntx. Из перечисленных вами пунктов интересными и приоритетными лично для меня являются транзакции и, в какой-то степени, вычисляемые поля. leto_closeAll() сделать просто: { sendrecv( "close;all';" ); // что-то вроде bNotSendClose = TRUE; // Глобальная переменная в leto1.c, чтоб метод close не слал запрос на сервер hb_rddCloseAll(); bNotSendClose = FALSE; } Кодовые страницы, наверное, надо указать в .h все - пусть если кто хочет уменьшить вес сервера, убирает ненужные ( а они не много-то и весят ). А важными для меня целями, кроме транзакций, являются дополнительные процессы, чтоб передавать им на исполнение некоторые задачи ( индексирование, ... ) и server side процедуры.

alkresin: Реализация транзакций мне видится следующим образом: leto_BeginTransaction() просто устанавливает в TRUE какой-нибудь bTransActive. leto_PutRec(), если bTransActive == TRUE, не посылает изменения на сервер, а добавляет в специальный буфер. leto_CommitTransaction() отправляет содержимое буфера на сервер и устанавливает bTransActive в FALSE. Сервер обрабатывает буфер, пишет изменения в таблицы, попутно сохраняя где-то содержимое измененных полей, чтобы в случае чего откатить изменения.

Pasha: Т.е. read commited Такая реализация транзакций будет работать очень быстро, надежно, но есть и недостатки 1. Внутри транзакции на клиенте операция seek не сможет учитывать измененные записи, которые еще не переданы на сервер Ограничение не такое уже и сильное, можно пойти на него Для операций skip/goto можно сделать просмотр буфера перед посылкой запроса на сервер 2. Как внутри транзакции в этом случае формировать значения ключевых полей, если с одна таблица будет учавствовать в 2-х транзакциях с разных клиентов ? Это уже более существенно

alkresin: Внутри транзакции на клиенте операция seek не сможет учитывать измененные записи, которые еще не переданы на сервер Я бы даже не назвал это ограничением. Надо просто корректно подготавливать выполнение транзакций: сначала найти все записи, которые будут изменены, заблокировать их, а потом выполнять транзакцию, иначе серверу относительно часто придется выполнять rollback ( если нужную запись не удалось заблокировать ). ADS, например, так и советует делать, они даже ограничивают выполнение блокировок во время транзакций и запрещают разблокировки. Как внутри транзакции в этом случае формировать значения ключевых полей, если с одна таблица будет учавствовать в 2-х транзакциях с разных клиентов ? Поясните на примере. Я пока не понял, в чем проблема.

alkresin: Кстати, учитывая то, что все команды доступа к данным выполняются в настоящий момент последовательно в одном потоке, правильнее определить уровень изоляции как serializable, т.е. самый высокий :).

Pasha: Я имел в виду одновременное получение значения ключа: dbGoBottom() nKey := Key + 1 begin transaction dbAppend() Field->Key := nKey ... Может случиться коллизия, когда 2-й клиент получит такое же значение ключа, пока 1-й не закончил транзакцию

Andrey: Не забудьте сделать еще запуск letodb.exe как службу !!! А то замучишься потом его запускать самостоятельно. А вообщето неплохо бы сделать прогу, которая занимая мало место в памяти на сервере, слушала бы Port = 2812 указанный в letodb.ini и при обращении к этому порту с любого клиента, поднимала бы сам letodb.exe А в самом letodb.exe предусмотреть выгрузку из памяти если все клиенты прекратили работу с БД. И тогда удаленно можно было бы редактировать letodb.ini

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

alkresin: Добавил поддержку DBFNTX. Чтобы сервер работал с этим драйвером, надо написать в letodb.ini: DEFAULT_DRIVER = NTX В самом ближайшем будущем добавлю в ini [DATABASE], чтобы устанавливать ntx не для всех данных, а для определенных каталогов.

alkresin: Теперь можно писать в ini: [DATABASE] DataPath = /some_db Driver = NTX чтобы определить каталог с данными /some_db, файлы в котором надо открывать через DBFNTX Сегодня, если не обнаружатся вдруг ошибки, выложу новый build.

gfilatov: alkresin пишет: выложу новый build Выложил готовую к использованию полную сборку LetoDB build 0.5 по адресу: http://minigui.mylivepage.ru/file/?fileid=4909 Результаты тестов для этой сборки: Test 1 Finished in 83.43 seconds Test 2 Finished in 0.55 seconds Test 3 Finished in 8.08 seconds Test 4 Finished in 7.96 seconds Расшифровка тестов: 1) добавление 200 000 записей и их заполнение произвольными данными 2) индексирование по числовому полю 3) позаписное перемещение через всю базу без использования индексов 4) позаписное перемещение через всю базу с использованием индекса Итоговый размер базы: 11,2 МБ Все тесты проводились на виртуальном (RAM) диске

alkresin: Фантастика! У вас там робот автоматом отслеживает релизы и делает сборки ? Я только несколько минут назад файлы выложил ...

Andrey: gfilatov пишет: Все тесты проводились на виртуальном (RAM) диске Не совсем понятно ! Что на сервере был создан виртуальный диск и на нем тестировалось ? Тогда это не есть хорошо ... Это не реальная ситуация ! Нужно тестировать на реально-работающем сервере, когда 10-15 клиентов сидят не только в этой задачи, но и в других.

gfilatov: Andrey пишет: Что на сервере был создан виртуальный диск и на нем тестировалось ? Все тесты проводились на виртуальном (RAM) диске на локальной машине Andrey пишет: Тогда это не есть хорошо ... Это не реальная ситуация ! Согласен. Но никто и не будет на сервере добавлять 200 тысяч записей за один раз, как в 1-м тесте

Andrey: Я попробую, чуть попозже !

Pasha: Для xHarbour-пользователей прийдется пересобрать билд, так как надо добавить функцию hb_strncpyLower



полная версия страницы