Форум » 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 на Харборе, ... и вообще все в наших руках :). Кто хочет участвовать в разработке, тестировании - пишите.

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

Pasha: alkresin пишет: Т.е. если удалить в kladr все записи кроме одной и написать программу... Да, у меня ошибка 9009 выскочила, правда почему-то только на 3-й раз А с фиксом все работает. Вроде бы код аналогичный, но тем не менее.. А в Harbour этот пример работает ?

Sergey Spirin: Andrey пишет: Какие еще могут быть варианты с запуском сервиса LetoDB ? Я что-то не понимаю, если он сервис, то какие могут быть проблемы? Идем в службы, находим его и ставим - "тип запуска - Авто". ??

PSP: Запуск сервера - "Панель управления - Назначенные задания"


alkresin: А в Harbour этот пример работает ? У меня kladr сейчас под рукой нет, а качать 74М не хочется.

AlexMyr: Сегодня упал сервер, в letodb_crash.log Breakdown at: 2010.08.06 10:37:04 Unrecoverable error 1010: hb_cdxIndexPageRead: Read index page failed. ------------------------------------------------------------------------ User: 127.0.0.1 GRU VIEWWSGUI.EXE Command: ord;02;513;data;2; Table: \res.dbf Unrecoverable error 9104: hb_cdxIndexFree: index file still locked. Breakdown at: 2010.08.06 10:44:45 Unrecoverable error 6005: Exception error: %s Exception Code:C0000005 Exception Address:00408AC2 EAX:00000000 EBX:00000000 ECX:00000024 EDX:004C0000 ESI:0070FB0C EDI:01050174 EBP:0070FB18 CS:EIP:017F:00408AC2 SS:ESP:0187:0070FAF4 DS:0187 ES:0187 FS:0F9F GS:0000 Flags:00010293 CS:EIP: 83 7B 40 00 0F 84 19 02 00 00 8B 03 50 E8 4C 1A SS:ESP: 00000000 0070FB18 01050174 0070FB0C 01052EA4 00408EBC 00000017 00000000 40E2E3A0 3638004C 30303538 76720031 76207265 392E302E 003B4E3B 00000000 C stack: EIP: EBP: Frame: OldEBP, RetAddr, Params... 00408AC2 0070FB18 3638004C 30303538 76720031 76207265 392E302E 003B4E3B 00000000 004C0CF0 0070FB60 004A4474 ... и letodb.log 08/06/10 10:18:25: Leto DB Server has been started. 08/06/10 10:21:29: Error DBFCDX/1011 Write error: c:\cars\res.dbf (DOS Error 5) 08/06/10 10:26:52: Error DBFCDX/1011 Write error: c:\cars\res.dbf (DOS Error 5) 08/06/10 10:26:52: Error DBFCDX/1011 Write error: c:\cars\res.dbf (DOS Error 5) 08/06/10 10:28:10: Leto DB Server has been started. 08/06/10 10:32:18: Leto DB Server has been started. 08/06/10 10:38:07: Leto DB Server has been started. 08/06/10 10:44:00: Error DBFCDX/1011 Write error: c:\cars\res.dbf (DOS Error 5) 08/06/10 10:44:45: Error DBFCDX/1011 Write error: c:\cars\res.dbf (DOS Error 5) 08/06/10 10:44:45: Error DBFCDX/1011 Write error: c:\cars\res.dbf (DOS Error 5) 08/06/10 10:48:42: Leto DB Server has been started. База res размером 42 Мб, записей 1060560. Работает програма с декабря 2009 года. Только один компьютер собирает информацию и записывает данные в базу через leto_BeginTransaction() ... leto_CommitTransaction(), 3-4 компа только читают. После падения потерялись в базе за вчерашний день больше половины информации за сегодняший почти вся. Что могло произойти?

Pasha: Ошибка возникает при выполнении команды ord;02, т.е при вызове OrdKeyNo Возможно, произошло разрушение индексного файла Вы открываете БД в режиме shared или монопольно ?

AlexMyr: Share_tables = 1

Pasha: AlexMyr пишет: Share_tables = 1 А зачем ? Если сервер открывает БД монопольно, он работает намного лучше Возможно, в процессе совместной работы letodb и еще какой-то программы и произошло нарушение индекса.

Pasha: После выполнения OrdListAdd текущая запись становится не первая по индексу, а запись с номером один, на которую таблица позиционируется после открытия без индекса. Для исправления несовместимости предпочтительнее будет изменить протокол, в результат команды open;02 добавить leto_rec, и на клиенте отрабатывать ParseRec Хотя можно и с клиента после открытия индекса делать gotop прямо в функции letoOrderListAdd Как сделать ?

alkresin: AlexMyr пишет: Unrecoverable error 1010: hb_cdxIndexPageRead: Read index page failed. Да, это повреждение индекса. Оно может произойти или из-за какой-либо ошибки в dbfcdx, или, поскольку у вас используется Share_tables = 1, из-за аварийного завершения клиентской программы, работающей параллельно с leto. А вот в пропажу информации из БД не верится. При Share_tables = 1 letodb открывает таблицу в shared режиме ( если она в программе открывается как shared - а раз ту таблицу читают с других компьютеров, это, наверное, так и есть ). DBFCDX в shared режиме, естественно, не использует буферы и записывает каждое изменение на диск, чтобы параллельно работающие программы его сразу видели. Возможно, переиндексировав файл, вы найдете все "потерянные" записи.

alkresin: Pasha пишет: Для исправления несовместимости предпочтительнее будет изменить протокол, в результат команды open;02 добавить leto_rec, и на клиенте отрабатывать ParseRec Хотя можно и с клиента после открытия индекса делать gotop прямо в функции letoOrderListAdd Первый вариант, конечно, предпочтительнее. Меня лично не пугает в данном случае изменение протокола, поскольку оно не должно привести к нарушению работы программ в случае, когда клиент и сервер откомпилированы разными версиями. Но тут есть такой момент, что текущий индекс и текущая запись изменяются только если открываемый индекс - первый. А если второй, третий и т.д., то текущий индекс и, соответственно, запись, остаются прежними - надо это учесть.

AlexMyr: alkresin пишет: Да, это повреждение индекса. Оно может произойти или из-за какой-либо ошибки в dbfcdx, или, поскольку у вас используется Share_tables = 1, из-за аварийного завершения клиентской программы, работающей параллельно с leto. А вот в пропажу информации из БД не верится. При Share_tables = 1 letodb открывает таблицу в shared режиме ( если она в программе открывается как shared - а раз ту таблицу читают с других компьютеров, это, наверное, так и есть ). DBFCDX в shared режиме, естественно, не использует буферы и записывает каждое изменение на диск, чтобы параллельно работающие программы его сразу видели. Возможно, переиндексировав файл, вы найдете все "потерянные" записи. Да я сразу всех остановил (пользователей, сервер), индекс удалил, запустился, индекс создался, но данных нет (смотрел саму базу без индекса - тоже данных нет). Может дело все в том, что у меня сервер собран еще второго февраля, а клиент собран в мае (хотя до того дня все работало)?

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

alkresin: 3-4 компа только читают. А эти 3-4 компа через letodb работают ? Я это к тому, что если они работают параллельно, через dbfcdx ( иначе зачем share_tables=1 ? ) и "видят" каждое новое изменение - значит, это каждое изменение записывается на диск ... Есть сейчас в реализации транзакций один момент, который меня беспокоит - по ее завершении не происходит автоматический commit, а если он находится между leto_BeginTransaction() и leto_CommitTransaction(), то он не передается на сервер. Думаю, что в shared режиме добавляемые записи и без commit должны писаться на диск ( сейчас у себя сделал маленький тест - вроде так и есть ), но все равно commit внутри транзакции сделать надо.

AlexMyr: alkresin пишет: А диск на потерянные кластеры проверяли ? Проверю. alkresin пишет: А эти 3-4 компа через letodb работают ? Я это к тому, что если они работают параллельно, через dbfcdx ( иначе зачем share_tables=1 ? ) и "видят" каждое новое изменение - значит, это каждое изменение записывается на диск ... Да, через letodb, а с share_tables игрался когда тестировал, то так и оставил, не менял больше. Еще открывал Dos Navigatorom по F3 (на компе где leto запущено и база лежит), но сначала работы програмы такого не было.

Pasha: AlexMyr пишет: у меня сервер собран еще второго февраля, а клиент собран в мае Лучше пересобрать и сервер, и клиент. За последнее время было много существенных изменений, в том числе исправлялись ошибки

AlexMyr: Буду пересобирать, но уже в сентябре - ухожу в отпуск

Pasha: Сбросил кое-какие изменения: Функция Leto_Memoread() - Отключил проверку SkipBuf для shared режима; - Позиционирование на первую запись при открытии индекса; - Обьявление кодовых страниц перенес в отдельный файл - Протокол для открытия индекса изменился, но, поскольку содержимое записи добавлено в конец пакета, клиент можно не пересобирать Но, если клиент пересобран, надо собрать и сервер.

Pasha: Для вызова с клиента функций на сервере предлагается такая схема: Сервер собирается вместе с модулем udf.prg, в который разработчик по желанию сможет добавлять свои функции. Первый параметр, который получает такая функция - это nUserStru. На сервере добавляется функция Leto_Alias(nUserStru, cClientAlias) --> cRealAlias, которая возвращает реальный алиас по клиентскому, для доступа к таблицам БД. Эта функция уже написана. На клиенте добавляется функция Leto_Udf(<cFuncName>, Param1, ...). Серверу передается команда usr;01;cFuncName;cParams Параметры формируются с помощью HB_Serialize. На сервере параметры обрабатываются с помощью hb_DeSerialize, функция выполняется, результат возвращается опять таки через HB_Serialize - hb_DeSerialize Поскольку для xHarbour HB_Serialize сделана на prg-уровне, прийдется написать обертку, что-то вроде leto_Serialize Недостаток этого способа (пока) - то, что udf-функция будет выполняться в основном потоке, но, думаю, он будет устранен. Некорректная функция к тому же может привести к падению сервера, но это уже будет проблема разработчика такой функции.

Pasha: В конце концов реализовал (пока) такую схему: На клиенте вызывается функция: leto_udf(cServerName+cFunction, cParam) пример: leto_udf('//127.0.0.1:2812/leto_alias', 'employee') на сервере вызывается функция cFunction с параметрами nUserStru и cParam ее результат (пока только символьная строка) возвращается клиенту В дальнейшем планирую реализовать произвольное число параметров любых типов На сервере для реализации пользовательских функций загружается файл letoudf.hrb, в котором пользователь и делает свои функции В связи с этим у меня вопрос: как загружать hrb на старом харборе ? Сейчас я сделал так в server.prg: #ifndef __XHARBOUR__ #include "hbhrb.ch" #endif ... IF File( "letoudf.hrb" ) #ifndef __XHARBOUR__ hb_HrbLoad(HB_HRB_BIND_DEFAULT, "letoudf.hrb" ) #else __hrbLoad( "letoudf.hrb" ) #endif WrLog( "letoudf.hrb has been loaded." ) ENDIF будут ли эти операторы компилироваться старым Harbour ? В дальнейшем еще планирую для udf-функций дать возможность возвращать клиенту содержимое изменившихся рабочих областей, т.е. leto_rec Скажем, функция-триггер добавила запись, и вернула ее клиенту



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