Игорь Сотников
Дата: 04.03.2008 15:41:01
Из-за чего рушится база в MS Access 2000?
У нас имеется база MS Access 2000 размером около 150 мегабайт. База размещена на файл-сервере и доступна пользователям по сети. Имеется приложение, разработанное в среде MS Visual Basic 6.0 (и откомпилированное в обычный EXE-файл), которое обращается к этой базе через ADO. Подключение к базе осуществляется при открытии приложения, а отключение - при закрытии, то есть база данных является открытой каждым клиентом достаточно долго - на протяжении нескольких часов. Приложение и база данных у нас используются для производственного и складского учета, для оформления накладных и других документов.
В этом приложении с этой базой реально одновременно работают примерно 7 пользователей (+/-).
Пользователи обращаются к этой базе только через это приложение, но не через Access.
На всех компьютерах используется MS Access 2000.
База данных защищена паролем, но не зашифрована. Пароль установлен именно на саму базу данных, а не на конкретных пользователей.
При этом иногда - примерно раз в неделю - база данных рушится и открыть ее не удается ни в Access'е, ни в приложении. И при попытке ее открыть в Access'е - хоть сразу, хоть после того, как все остальные пользователи закроют приложзение - выдается сообщение:
Требуется восстановление базы данных ...
или этот файл не является файлом базы данных.
Возможно, приложение MicroSoft Access было внезапно закрыто при открытой базе данных
приложения MicroSoft Access.
Разрешить приложению 'MicroSoft Access' попытаться восстановить эту базу данных?
При запуске процедуры сжатия и восстановления базы данных Access выдает сообщение: Ошибочный пароль
(хотя пароль от базы мы вводим правильно).
В некоторых других утилитах при открытии этой базы выдается другое сообщение: Нераспознаваемый формат базы данных.
Если же попытаться восстновить эту базу утилитой JetComp, всё проходит нормально, пароль проходит, всё восстанавливается и никакие данные при этом не теряются. И всё после этого работает нормально.
Такие сбои проявляются в совершенно случайные моменты времени и не связаны с возможными ошибками в программном коде приложения, поскольку если в базе данных повторно выполнить те же действия сколько угодно раз, всё проходит нормально.
Искусственно воспроизвести эту ситуацию и спровоцировать такой сбой не удается.
Однако есть некоторые закономерности:
1) вероятность сбоев повышается, если в это время два или несколько пользователей одновременно выполняют массовые операции изменения данных в приложении.
Под массовой операцией здесь понимаются такие действие, как последовательное выполнение в цикле нескольких сотен или тысяч SQL-запросов на добавление, обновление или удаление записей - и вся эта операция может продолжаться от нескольких десятков секунд до нескольких минут.
При этом такие операции, выполняемые двумя разными пользователями, могут быть совершенно разными и затрагивать совершенно разные таблицы.
При этом сами SQL-запросы, как правило, достаточно простые и один запрос реально изменяет, как правило, только одну запись.
2) вероятность сбоев повышается на том этапе, когда размер базы данных растет.
Известно, что Access увеличивает размер файла MDB не плавно по мере добавления новых записей, а скачкообразно - например, сначала база имеет размер 140 мегабайт, очень долгое время такой размер сохраняется, хотя в базу добавляют много новых документов.
Потом за очень которкое время Access создает очень много новых страниц и размер базы увеличивается (не одномоментно, но все равно за очень короткое время) до 160 мегабайт, потом этот размер в 160 мегабайт очень долго сохраняется и т. п..
Так вот, сбои становятся вероятными тогда, когда происходит такое достаточно быстрое увеличение MDB-файла и когда за короткое время создается много новых страниц. То ли один клиент не видит ту страницу, которую создал другой клиент, то ли в чем дело?
И если эти два условия выполняются, тогда такой сбой происходит. И поскольку после сжатия и восстановления базы данных MS Jet снова пытается за короткое время увеличить размер базы данных до исходного, то очень часто в один день такие сбои повторяются несколько раз, а потом в течение недели или около того всё работает нормально.
И хотя угрозы потери данных в нашем случае не существует и хотя со слишком большим объемом базы мы научились так или иначе бороться, удаляя время от времени старые документы и делая архивные копии базы, тем не менее, такое положение вещей нам очень не нравится.
Нам уже надоело постоянно восстанавливать базу данных!
На всякий случай уточняю, что проблема не в сервере. Мы пытались размещать базу на разных машинах с разными операционными системами Windows 2003 Server, Windows 2000 Server и Windows 98 - но эффект везде один и тот же, на частоту и характер проявления подобных сбоев это не повлияло. Также проблема и не в хабе, поскольку мы его тоже меняли. И вообще все остальные приложения, в том числе и 1С, в нашей сети работают весьма стабильно и никто ни на что не жаловался.
Не можете ли сказать, в чем может быть причина подобных сбоев и как их можно предотвратить в дальнейшем?
Не нужно ли вам прислать одну из таких испорченных копий базы данных (размер в архиве около 20 мегабайт), чтобы вы могли посмотреть, в чем здесь дело?
Игорь Сотников
Дата: 04.03.2008 16:09:46
А еще очень интересное пишут на сайте MicroSoft:
http://support.microsoft.com/kb/209137
Восстановление поврежденной базы данных Jet 4.0 в Access 2000
Цитата:
"Избегайте большого числа операций открытия/закрытия в одном цикле (от 40 000 до 1 000 000 последовательных операций открытия/закрытия)."
Конец цитаты.
Как вы можете это прокомментировать? Что же выходит, если всё остальное нормально, но если в одном цикле осуществляется 40 000 открытий и закрытий подряд, то база может слететь?
И об открытиях и закрытиях чего там идет речь? Самого подключения? Или объекта recordset? Или о каждой записи?
Имеется в виду открытие для изменения этой записи или даже просто для чтения?
И с чем вообще связано подобное ограничение?