среда, 21 ноября 2012 г.

Скрипт проверки БД АС-Библиотека-3


За время администрирования АС-Библиотека-3 у меня накопилось несколько SQL запросов, которыми легко обнаруживались проблемы в базе. Подход оказался весьма продуктивным, поэтому я добавил некоторое количество новых и оформил всё это в виде hta скрипта. Скрипт выполняет всего две задачи запустить SQL запрос и отобразить результат, поэтому интерфейс весьма примитивен.


Лучше всего тестировать копию базы. С одной стороны не нагружается основная, с другой стороны исключается возможность получения промежуточных результатов. То есть тестовый запрос вклинивается в последовательность корректных, но ещё не завершённых операций и этот промежуточный результат воспринимается как ошибка. Если у вас АС-3 работает под SQL Server копию сделать не так просто. В этом случае необходимо либо отключить всех пользователей, либо повторить тест. Шансов опять получить ту же ошибку, нет.

Количество ошибок в базе напрямую зависит от режима эксплуатации - наличие ИБП, качество сети, уровень подготовки операторов и т.п. Отдельно можно скачать Демо базу, в которую ошибки внесены в демонстрационных целях.

Каждый тест сопровождается пошаговой инструкцией по устранению проблемы. Однако это не избавляет вас от необходимости понимать, что вы делаете. В большинстве случаев, перед тем как начать исправления лучше сделать резервную копию. Однако если исправления осуществляются штатными средствами (например, в "Каталогизаторе" изменяется состояние экземпляра) то параноить не стоит. Вы же не делаете резервную копию, перед тем как внести в базу новую запись. Из всех инструментов, используемых для правки, предпочтение отдано средствам, входящим в состав АС-3. Но, если вы хорошо владеете Access - нет проблем, хотя держать на сервере офисный пакет выглядит странно.

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

Все тесты, кроме сервисных, построены на базе реальных ошибок, которые встречаются в природе. По мере обнаружения новых будут добавлены и новые тесты, так что следи за версиями. Кроме того, если у тебя есть подобный опыт и тебе не жалко поделиться им с обществом, сообщи об этом.

Скрипт и демонстрационная база доступны для свободного скачивания на панели справа. Файлы лежат на Яндекс.Диске, поэтому насчёт вирусов можешь не переживать. На данный момент поддерживаются последние версии - 3.3.58 и 3.3.64. У меня нет информации о версиях, которые сейчас имеют хождение. Сообщи, если твоя не поддерживается. Скрипт выдаст инструкции как это сделать.
Пиши комментарии (регистрация не требуется) или на почту acbib3@yandex.ru

среда, 3 октября 2012 г.

Формат <> "Users"


С переходом на АС-Библиотека-3 версии 3.3.58 (в 3.3.64 также присутствует) в модуле "Читатель" стала появляться ошибка с надписью "Формат <> 'Users'"

, убить которую можно было только перезапуском модуля. Один из сотрудников выявил закономерность появления ошибки, и оказалось, что если придерживаться определённого поведения, то ущерб можно свести к нулю.
Давай посмотрим, что происходит. Итак, запускаем модуль. В поисковых полях вводим условие, заведомо приводящее к успешному результату. В Демо я просто ввожу "Чит. билет = 1", жму поиск, результат 1.

Переходим на вкладку "Результат" - всё в порядке.

Теперь вернёмся в "Поиск" и определим условие, которое заведомо приведёт к нулевому результату - "Чит. билет = а".

Ищем и переходим в "Результат".

Поймал мысль? Ошибка появляется, когда сначала кто-то найден, а потом не найден. Ситуация вполне типичная для процесса регистрации нового пользователя. Предположим, что кто-то найден или зарегистрирован. Его данные висят на вкладке "Результат". Приходит новый пользователь и просит его зарегистрировать. Вначале осуществляется поиск пользователя, на предмет его присутствия в базе и задолженности. Если всё в порядке и пользователь не найден, переходим на вкладку "Результат", с целью регистрации. И сразу получаем ошибку.
Интересно, что поведение ошибки в разных системах различно. Самое жёсткое поведение в XP. Стоит провести курсором мыши по полю "в отделах"

как появляется ошибка, в количестве равном количеству отделов. Причём окошко ошибки, как правило, расположено в середине поля "в отделах" и, после закрытия последовательности, малейшее движение мыши вызывает очередную. Отсюда вытекает метод борьбы. Нужно вывести курсор за пределы поля "в отделах", закрыть окошки уведомления об ошибке с клавиатуры (кл. Enter) и создать новую запись. Больше ошибка не появится. Главное при создании записи не зацепить курсором поле "в отделах". Такое же поведение наблюдается и в Висте без SP. В семёрке, что-то изменилось, и реакции на проводку курсора нет.

четверг, 27 сентября 2012 г.

О вреде работы под Администратор 123


О вреде работы под админом в винде все знают, но всё равно работают. А вот в чём проблема работы под Администратор 123 в "АС-Библиотека-3"? Ситуация, согласись, не редкая. Вообще в библиотеках с паролями  большая проблема. Начальство требует списки паролей сотрудников в сейф, последние их забывают, а если записали, то обязательно потеряют и т.д. Поэтому, частенько, все работают под Администратором. Конечно, если коллектив небольшой и все доверяют друг другу, кроме того доступ к компьютерам только у сотрудников и сеть изолирована от Интернета - к чему эти игры в конспирацию. Однако проблема проявляется в совершенно неожиданном месте. Сам не поверил бы, если бы не увидел своими глазами. Дело, в общем то не в Администраторе, а в работе под одной учётной записью несколькими сотрудниками.
Итак, во всех многопользовательских системах обработки данных существует и успешно решается проблема "потерянных обновлений". Проще всего её показать на пальцах. Запустим два "Каталогизатора" и один "Администратор". Во всех модулях залогинимся под Администратором. В обоих "Каталогизаторах" выполним запрос одной и тоже записи (неважно какой), а в "Администраторе" сделаем выборку таблицы Demo__Lock (или другая *__Lock, если логическая база другая).


В левом "Каталогизаторе" изменим пару строк и повременим с сохранением изменений в базе. Перечитаем Demo__Lock - появилась блокировка.


Теперь изменим другое поле (например, дату) в правом "Каталогизаторе" и тоже не сохраняем.


Перечитаем Demo__Lock – та же запись, только время изменилось.


Жмём кнопку "Сохранить" в левом "Каталогизаторе".


Перечитываем Demo__Lock - таблица пустая, блокировки нет.


Жмём кнопку "Сохранить" в правом "Каталогизаторе".


Попробуй угадать, что в базе? Естественно результат второго сохранения. Перечитаем запись в обоих.


Правый "Каталогизатор" закэшировал данные и перекрыл все модификации, выполненные в левом.
Но гипотетический сотрудник, работающий за левым "Каталогизатором" уверен, что он выполнил свою работу. И впоследствии будет крайне удивлён, увидев старые данные. Это и есть один из вариантов проблемы "потерянного обновления".
А что произойдёт, если учётки разные? Перелогинимся в правом "Каталогизаторе" под "Библиотекарь" и попробуем всё повторить.


Начнём модификацию в левом. Перечитаем Demo__Lock - появилась блокировка.


Теперь попробуем модифицировать запись в правом.


Срабатывает защита.
Конечно, решение проблемы "потерянных обновлений" в "АС-Библиотека-3" немного странное, но оно работает именно так. Неважно, какими правами обладают учётки, важно, чтобы они были разными.
Аналогичная ситуация с модулями "Читатель" и "Абонемент", работающими с БД User. Попробуй сам. И не ленись писать комментарии.

четверг, 13 сентября 2012 г.

Транзакции

Этот эксперимент не касается напрямую "АС-Библиотека-3". Однако, поскольку она не может работать без поддержки СУБД он вполне уместен. К тому же производительность системы в целом существенно зависит от данного звена.

Итак, после перехода на MS SQL, решил повозиться с транзакциями, точнее различием их поведения в MS Access и MS SQL. Набросал маленький hta скриптик (в конце статьи ссылки и рекомендации для тех, кто решит повозиться сам). Смысл его в параллельном запуске двух различных SQL запросов, с различным уровнем изоляции транзакций. То есть мы, просто искусственно сталкиваем транзакции и смотрим результат. База состоит из одной таблицы Table_1, в которой два поля - fld1 и fld2. Данные появляются и изменяются в процессе работы. Вначале подключаемся к Access базе Test1.mdb и запускаем два экземпляра скрипта. По умолчанию выбрано adXactCursorStability (adXactReadCommitted) и это единственный уровень изоляции, поддерживаемый базой Access, остальные либо игнорируются, либо приводят к ошибке. В "левом" скрипте выбираем команду обновления
 update Table_1 set fld2 = :Param1 where fld1 = :Param2
и изменяем строку с fld1 = 3, присваиваем fld2 значение 7. Жмём Старт и видим окошко с предложением зафиксировать транзакцию. Пока не нажато ОК, транзакция находится в активном состоянии. В это время в "правом" скрипте запустим операцию чтения той же строки с fld1 = 3. Чтение происходит успешно.

Жмём ОК в "правом" скрипте, а затем в "левом", и смотрим результат. Всё в соответствии с описанием уровня изоляции adXactReadCommitted. "Правый" скрипт без препятствий вычитал старое значение fld2 = 3, поскольку новое fld2 = 7 ещё не было зафиксировано.


Теперь изменим параметры подключения на SQL Server, и повторим предыдущие шаги. Видим, что SQL Server встрял по полной! Как видно на скриншоте



"правый" скрипт даже PrintScreen не берёт. Более того - он встрянет даже при чтении соседней строки. Как это отражается на производительности "АС-Библиотека-3" понятно - пока кто-то проводит интенсивные изменения в базе, остальные ждут, вне зависимости от количества ядер в твоём сервере. Но главная проблема - полное несоответствие описанию поведения уровня изоляции adXactReadCommitted. Глюк? "Курим" мануалы ...
Находим интересную команду (надо сказать, что такому поведению SQL Сервера в документации посвящена целая глава и, по хорошему – сначала читаем, потом делаем, но …  ):
 alter database Test1 set read_committed_snapshot on
переводящую базу в режим контроля версий строк (off - отключить; применять в контексте базы master; работает почти мгновенно, если долго ковыряется, значит что-то блокирует базу). Применяем её и всё становится на свои места. То есть поведение блокировок ничем не отличается от Access. Посмотреть текущий режим работы баз можно запросом:
 select name, is_read_committed_snapshot_on  from sys.databases
К сожалению, протестировать этот режим в "боевых" условия при интенсивной нагрузке в настоящий момент не имею возможности - нет "полигона". Проверка в однопользовательском режиме на Демо-версии проблем не показывает, но этого мало. Если заинтересуешься и сделаешь это - сообщи в комментарии. Потребуется поддержка, готов помочь.
В конце несколько слов о содержимом архива.
Скачать архив здесь - TransactTest.zip
1. Transact.hta - запускаемый скрипт. Для редактирования строк подключения открыть в "Блокноте".
2. Test1.mdb - база Access. Для подключения в Transact.hta снять комментарий (//) и закомментировать стоку SQL Server, при необходимости откорректировать путь к базе.
3. Test1.mdf, Test1_log.ldf - база данных и журнал транзакций SQL Server. Скопируй их в стандартный каталог баз (где лежит master.mdf) или придётся возиться с настройками доступа. В Transact.hta сними комментарий со строки подключения, замени XXXX на реальный пароль sa  и закомментируй строку подключения Access. Если подключиться не удаётся – смотри в мануалах конструирование строки подключения (эта задача не тривиальна), но если ты воткнул Z-Сервер, то воткнёшь и скрипт.

На этом всё. Если есть вопросы – пиши комментарий.

Добавил видео по теме. Для просмотра лучше скачать.

вторник, 24 июля 2012 г.

Шлюз

Сделаем простой эксперимент с WWW-шлюзом.
Откроем в браузере страницу поиска

и добавим к http://localhost/lib/ в строке запроса EWww.xml.
В результате получим строку запроса следующего вида http://localhost/lib/EWww.xml.

Жмём Enter и видим ошибку XML парсинга.

Значит, документ получен! Ошибка нас не интересует. Просто откроем исходный текст (Меню -> Страница -> Просмотр HTML-кода). Вот он, вместе со всем своим богатством (у меня Демо)


Адрес Z-сервера (а чаще всего это основной физический сервер в библиотеке), имена баз, логины и пароли! И всё это лёгким движением руки!
Так что, если тебя беспокоит безопасность, не забудь прикрыть этот ценный файл в настройках IIS.

среда, 23 мая 2012 г.

32 браузера

Когда организовывал доступ к базе из Интернет, решил тупо проверить, а сколько коннектов удержит моя система? Есть ли предел? Насколько мне было известно - количество подключений через WWW-шлюз не лимитируется даже на "Демо". В результате нашёл много интересного. Ты можешь повторить сам - это абсолютно безопасно даже на рабочей системе. Просто в этот момент никто не должен выполнять реальную работу, иначе получишь по полной.
Итак, запускаем браузеры. Но перед этим остановим Z-сервер и удалим EServer.log (именно .log, а не .exe!!!) - будет легче искать записи об ошибках. Стартуем Z-сервер и запускаем браузеры, сколько сможем. Проще всего это сделать из командной строки.



Стрелка вверх повторит предыдущую команду. По ходу можно закрывать уже открытые браузеры - они своё дело уже сделали. Периодически смотрим в EManager количество подключений. На "Демо" установке каждый новый браузер даёт два подключения, с другими настройками всё может быть по-другому, но смысл не изменит. Последний нормальный запуск происходит с достижением кол-ва подключений 62.



А дальше...



Подключение остаётся одно и появляется следующая ошибка:
18:42:28-15/05: [fatal][debug][warn][log][app][all] DB: User Connection: TSqlConnection.Open( Provider=Microsoft.Jet.OLEDB.4.0;Data Source=.\DB\Lib.mdb;Persist Security Info=False ): Неопознанная ошибка []
18:42:28-15/05: [fatal][debug][warn][log][app][all] Restart server []
А что произошло бы с обычными клиентами ("Абонемент", "Каталогизатор", ...)? Ты уже догадался - естественно они будут "сброшены". Если сомневаешься - проверь. У меня была очередь с жалобами на то, что система всё время требует ввести пароль, и я грешил на ошибки с таймаутом. А на самом деле всё оказалось проще. Что, при этом, происходит с базой - приходится только догадываться.
Хотя, судя по тексту ошибки, это не похоже на проблему с Z-сервером. Возможно это беда "Access" движка "Jet"? Как это проверить? Да запросто. Следующий скрипт просто создаёт подключения в кол-ве указанном в переменной count, выбрасывает исключение при ошибке и выводит кол-во успешных:
<HTML>
<HEAD>
  <TITLE>ConnectCount</TITLE>
    <HTA:APPLICATION ID="oHTA"
     APPLICATIONNAME="myApp"
  BORDER = "thick"
     BORDERSTYLE="normal"
     CAPTION="yes"
     ICON=""
     MAXIMIZEBUTTON="yes"
     MINIMIZEBUTTON="yes"
  SCROLL = "yes"
     SHOWINTASKBAR="yes"
     SINGLEINSTANCE="no"
     SYSMENU="yes"
     VERSION="1.0"
     WINDOWSTATE="maximize"/>
 <SCRIPT>
function getPath()
{
 var pathl = document.URL;
 var i = pathl.length;
 var j;
  while(pathl.charAt(--i) != '\\');
  j = i;
  while(pathl.charAt(--j) != '/');
 return pathl.substring(j+1, i+1);
}
var i = 0;
conns = [];
count = 100;
while(i < count)
{
 conns[i] = new ActiveXObject("ADODB.Connection");
 conns[i].ConnectionString = "Provider='Microsoft.Jet.OLEDB.4.0';Data Source='" + getPath() + "adb.mdb'";
 try
 {
  conns[i].Open();
  i++;
 }
 catch(e)
 {
  alert(e.message);
  break;
 }
}


function window.onload()
{
oPre.innerText = i;
}
</SCRIPT>
</HEAD>
<BODY>
  <PRE ID=oPre>  </PRE>
</BODY>
</HTML>
Для начала сделаем count=100. Если захочешь повторить просто скопируй его в "Блокнот" и сохрани с любым именем и расширением .hta (например, ConnectionCount.hta). База adb.mdb любая (я сделал "Access"-ом пустую). Можешь скопировать Explain.mdb в тоже место, где находится скрипт и переименовать в adb.mdb. Запускаем и получаем:



та же ошибка, а количество подключений:



Сделаем count=64 - ошибки нет. Более того, её не будет, если тут же запустить второй экземпляр скрипта! В сумме окажется 128 подключений! Судя по всему это ограничение на процесс и новому процессу даётся новая "квота". Известно, что Z-сервер (EServer) "АС-Библиотека-3" работает одним многопоточным процессом и, по всей видимости, упирается в это ограничение. Поиски в Интернете и настройках "Jet" как обойти, или изменить порог в 64 ничего не дали (если у тебя есть какая либо информация на эту тему сообщи в комменте).
Какой выход? Я нашёл только один - переход на SQL Server. Но не торопись делать то же самое. Если у тебя несколько клиентов (не фиксируется вышеприведённая ошибка), небольшая база (меньше 1Гб в сжатом виде) и нет внешнего доступа, то издержки эксплуатации SQL Server перекроют все прелести неограниченой подключаемости. К тому же на небольшой базе Access обставит SQL и по скорости и по компактности.

четверг, 3 мая 2012 г.

Администратор 123

Недавно подвернулась интересная утилита для анализа сетевой активности "oSpy". Она ловит даже "петлю". И вот результат.


Какой-то подозрительный "123", а где "Администратор"? Сохраним пакет в "сыром" виде и откроем любым текстовым редактором.


А вот они и вместе. Похоже, что логин и пароль в "АС-Библиотека-3" передаются открытым текстом. Хорошо это или плохо? Не то и не другое. Существует множество не "секюрных" протоколов (HTTP, FTP, telnet, ....). Всё зависит от использования. Если в локальной сети - то это не проблема (если за локалкой следить конечно), а если хочешь затеять корпоративку или просто внешний доступ - учти этот момент. Есть масса технологий для "прикрытия" (VPN, IPSec, ....).

четверг, 26 апреля 2012 г.

Переход

Года три назад решили перейти на новую версию "АС-Библиотека-3" 3.3.58. Технологий перехода много, но для начала выбрали самую простую - через выгрузку записей из старой версии и загрузку в новую (выдачи, естественно, просто скопировали с помощью "Access"). Однако первая же проверка показала, что записи легли криво. Например, запрос:
select count(*) from All__Delivery D
 where not exists (select B.BookID from All__Book B where B.BookID = D.BookID)
дал кучу записей о выдачах экземпляров, которых нет в БД! И наоборот.
В результате, комбинируя "перезаливку" с реструктуризацией, базу удалось конвертировать. Но вопрос надолго завис в воздухе.
Недавно сделал простой эксперимент, который прояснил ситуацию. Ты можешь повторить его сам, если интересно. Лучше на "Demo" - не придется отматывать назад.
Итак, запускаем "Каталогизатор" и делаем выборку всех записей (в демо их немного). Находим простую (однотомник, при этом должен быть экземпляр, проще говоря, инвентарный номер, поэтому общая часть не подойдёт и экземпляр должен быть один для простоты, общности это не нарушает) и запомним её номер

выгружаем её в файл с сохранением локальных полей.


Далее загружаем "Администратор", подключаемся к базе и делаем два запроса на вкладке "SQL":
select max(DocID) from Demo__Doc


и
select max(BookID) from All__Book


Первый даёт DocID записи с максимальным значением в таблице Demo__Doc, вторая максимальный BookID экземпляра. У меня 81 и 121 соответственно. Запомним их. Теперь откроем "Каталогизатор» -Ом сохранённую в файл запись и откорректируем Mark поля 001, 8993 и 200a так:
001 = z3950://127.0.0.1/Demo/7 - до
001 = z3950://127.0.0.1/Demo/91 - после

8993 = 7 - до
8993 = 131 - после

200a = Почему погиб социализм - до
200a = Почему погиб социализм 1 - после

то есть просто добавим по 10 сверх максимальных (10 не принципиально можно любое). Кроме того добавим к заглавию любой символ (для отличия, иначе получим дублет). Сохраним запись в тот же файл. Сначала жмём на галочку "сохранить", а потом на значке "сохранить в файл все записи" (у нас одна).
Теперь импортируем запись в БД (Demo), не забыв поставить галочку "Сохранять номера записей".


И что стало с номерами?
001 = z3950://127.0.0.1/Demo/91
200a = Почему погиб социализм 1
8993 = 122 вместо 131



то есть, номер записи сохранился, а номер экземпляра стал на единицу больше максимального. А поскольку в "выдачи пишутся" номера экземпляров, а не записей и возникла "каша".

среда, 28 марта 2012 г.

Lib.ldb


Наверное, для начала, что-то общее для всех. Описываемые далее действия производились в разное время и в конце привели к некоторому пониманию назначения файла *.ldb, который всё время болтается возле больших и серьёзных файлов (не забудь вместо * подставить имя открытой базы, например Lib.ldb). Сам появляется, сам исчезает...
Кстати, все средства выгрузки записей в МАРК формате, модулей АС-Библиотека-3, по умолчанию так-же предлагают расширение *.ldb (очевидно от local db). Но это другая тема.
Из руководств по "Access" известно, что это файл блокировок. Ну и что это даёт? Зачем он нужен? Можно ли его грохнуть? И когда?
Попробуем препарировать его с помощью "Процесс монитор" (Найдёш его и ещё много интересного по ссылке http://technet.microsoft.com/ru-ru/sysinternals/bb896645)
Сразу замечу, если задумаеш повторить, не забудь поставить фильтрацию событий только процесса "EServer". Иначе ты утонеш в потоке. Кроме того, по умолчанию, он сохраняет события в виртуальной памяти, а значит в файл подкачки. И если он невелик - ты быстро исчерпаеш ресурсы. Направь поток в какой нибудь файл, если намерен сделать "большой захват". В нашем случае можно оставить по умолчанию.
Итак, открываем "Диспетчер задач", находим для "EServer.exe" PID = 3924.


Запускаем "Процесс монитор" и сразу останавливаем захват, очищаем экран и ставим фильтр, исключающий все события, не отнносящиеся к PID = 3924.
(с лева на право)


Стартуем захват и даём нагрузку. Я просто подключаю "Администратор" и делаю небольшую выборку из произвольной таблицы. После чего захват можно остановить.
Первое, что бросилось в глаза - создание временного файла "C:\Windows\Temp\JET3B7.tmp".


Я сразу проверил папку "C:\Windows\Temp" и обнаружил там несколько сотен, небольших по размеру, файлов с началом "JET*.tmp". Понятно, что если на компьютере и по сети не открыта ни одна база "Access", то их быть не должно. Поэтому рекомендую тебе периодически заглядывать в эту папку и наводить там порядок.
Прокрутив ниже, легко обнаружить место, где создаётся файл "Lib.ldb" и небольшая запись в него, с использованием стандартного "IRP".


А дальше начинается самое интересное. Обрати внимание - блокировки кладутся на "Lib.ldb", а читается "Lib.mdb" и всё это методом "FASTIO_*". Кроме того, смещения, по которым блокируется "Lib.ldb", какие то запредельные: "Offset 268435457". Файл то ведь маленький!


Я знал, что "Lib.ldb" это файл блокировок. Но что в таком буквальном смысле, скажу честно, не ожидал. Не так давно я читал книгу "Внутреннее устройство Windows" М.Руссиновича и Д.Соломона (кстати "Процесс монитор" это творение Руссиновича, а книгу всячески рекомендую) и мне, похоже, удалось найти объяснение. Точнее это только версия, но весьма правдоподобная. Всё дело в многочисленных ограничениях, накладываемых системой на возможность выполнения операций "Быстрого" (FASTIO_) ввода-вывода. Их названия говорят за себя - обмен происходит напрямую с системным кэшем, минуя большое количество системных слоёв (драйверы ФС и т.д.). Одной из причин отклонения "FASTIO_*" является наложенная блокировка, поэтому их и вынесли в отдельный файл *.ldb. Есть системные счетчики, отвечающие за "FASTIO_*": "Кэш:Синхронных чтений/сек" и "Кэш:Не осуществлённых чтений/сек" (названия могут отличаться, для разных систем). Однако их показания меня не впечатлили. Если при подключении "Администратор" их зашкаливает (на графике красным цветом),


то на выборке небольшой таблицы их показания совсем не велики (а может, просто, этого достаточно?).


На больших выборках они вовсе никак себя не проявляют. Однако "Access", всё же настольная база.
Теперь несколько слов об удалении. Так удалять или нет? Когда то давно я читал рекомендации "Microsoft" по обслуживанию баз "Access" (сейчас, хоть убей, не могу найти). Там было чётко указано, что перед операцией "Сжать/Восстановить" необходимо удалить соответствующий файл блокировки. В данной ситуации лучше прислушаться к производителю. В остальном, в свете выше сказанного, вопрос сводится к следующему - могут ли в *.ldb "застрять" активные блокировки? При катастрофических сбоях наверное да. Но это автоматически приводит к операции "Сжать/Восстановить" и к удалению. А если ты просто принудительно "положил" "EServer" с подключенным клиентом, то вряд ли. Система зачистит ресурсы. Другое дело, если база открыта по сети, из "расшареной" папки. Но это уже не наш случай.