Каждый администратор или разработчик, сопровождающий базы данных на платформе 1С:Предприятие 7.7 с файловой структурой (DBF), рано или поздно сталкивается с необъяснимым поведением системы. Представим ситуацию: менеджер открывает карточку клиента из расходной накладной и видит сумму долга в 1000 рублей. Спустя пять минут тот же менеджер нажимает ту же самую кнопку, изменений по клиенту в этот промежуток времени не вносилось, но отчет внезапно показывает уже 1200 рублей. Еще более странно выглядит ситуация, когда типовой отчет «Обороты» за один и тот же период на одном компьютере показывает одну сумму, а на соседнем — совершенно другую.
В этой статье мы подробно разберем, почему возникает этот неприятный и опасный эффект «плавающих» данных, в чем кроется его глубинная техническая причина, и какими методами можно навсегда решить эту проблему, обеспечив достоверность отчетов.
Для того чтобы понять природу этой ошибки, нам придется погрузиться во внутреннюю архитектуру работы СУБД-движка 1С 7.7. Платформа использует сторонний плоский движок баз данных CodeBase 6.x для работы с файлами *.DBF и индексными файлами *.CDX.
Когда база данных эксплуатируется в многопользовательском (разделенном) режиме, операционная система Windows должна как-то координировать одновременный доступ пользователей к одним и тем же таблицам. Для этого используется механизм файловых блокировок. Движок CodeBase устроен так, что область блокировок в файле начинается строго со смещения 1 ГБ (а точнее, с отметки в 1 073 741 824 байт или 2 в 30-й степени).
Пока файлы базы данных (такие как таблицы итогов RG*.DBF или таблицы движений регистров RA*.DBF) не превышают размер в 1 ГБ, запись и чтение происходят в штатном режиме. Но как только размер любого из этих файлов переваливает за границу 1 ГБ, реальные транзакционные данные начинают записываться в ту самую область, которую операционная система Windows резервирует под системные блокировки.
В этот момент и начинается самое интересное:
RA1234.DBF), находящиеся за пределами отметки 1 ГБ.В результате отчет формируется без каких-либо ошибок, но в него попадает только часть документов. Через 5 минут, когда второй пользователь закрыл форму или завершил транзакцию проведения, блокировка снимается. Тот же самый отчет при повторном запуске успешно считывает файл до самого конца и выдает уже полную, корректную сумму. Именно поэтому данные постоянно «плавают», сводя с ума бухгалтеров и менеджеров.
Рассмотрим пример типичного кода, который при работе с базой объемом более 1 ГБ подвержен «тихому обрыву»:
Рег = СоздатьОбъект("Регистр.Взаиморасчеты");
Рег.ВыбратьДвижения(ДатаНачала, ДатаКонца);
Пока Рег.ПолучитьДвижение() = 1 Цикл
// При наличии конфликта блокировок на файле > 1 ГБ
// этот цикл молча прекратит выполнение досрочно!
СуммаДолга = СуммаДолга + Рег.Сумма;
КонецЦикла;
Поскольку сама фирма 1С давно прекратила активную поддержку платформы 7.7, исправлением этой фундаментальной ошибки занимались независимые разработчики. Наиболее известным и проверенным решением является применение так называемого «патча Ходжика» (компоненты семейства Kernel3x).
Разберем подробнее, как функционируют подобные патчи:
Kernel33.dll, Kernel35.dll или Kernel37.dll) перехватывают низкоуровневые системные вызовы файловых блокировок Windows API.Альтернативным решением является использование модифицированной библиотеки движка баз данных dbeng32.dll (например, сборки от разработчика Wirth), которая на уровне самого движка решает проблему некорректной адресации блокировок.
Важное ограничение: Любые патчи файлового движка лишь отодвигают границу проблемы до 2 ГБ на один файл. Предел в 2 ГБ обойти невозможно физически, так как это жесткое ограничение самого формата таблиц DBF и 32-битной адресации файлов движком CodeBase. При достижении любым файлом размера в 2 ГБ база данных 1С 7.7 полностью потеряет работоспособность.
Еще одна частая административная причина искажения данных в отчетах на терминальных серверах (таких как Windows Server 2003/2008) связана с неправильным распределением временных файлов пользователей.
При построении отчетов, особенно использующих сложные запросы или временные расчетные таблицы, платформа 1С 7.7 создает временные файлы во временной папке пользователя. Если в конфигураторе для пользователей не настроены индивидуальные рабочие каталоги, система использует общую папку базы данных для хранения этих временных файлов.
Проанализируем, к чему это приводит:
Для исправления этой ситуации выполним следующие шаги:
C:\1C_Users\Andrey\).Если ваша база данных расположена на сетевом ресурсе под управлением Windows Server 2003, причиной искажения данных могут стать так называемые оппортунистические блокировки (Opportunistic Locks / Oplocks). Этот механизм разработан Microsoft для ускорения работы с файлами по сети за счет агрессивного кэширования на стороне клиента.
В случае с базой 1С 7.7 это приводит к тому, что локальный компьютер пользователя кэширует индексные файлы *.CDX и таблицы базы. Когда один пользователь вносит изменения, другие пользователи из-за кэша могут «видеть» устаревшие индексы и считывать старые данные из таблиц, что мгновенно искажает итоговые отчеты.
Для гарантированного устранения этой проблемы рекомендуется отключить механизм Oplocks на сервере через системный реестр:
regedit на сервере.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters.EnableOplocks и установим его значение в 0.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MRxSmb\Parameters.OplocksDisabled и установим его значение в 1.Подводя итог, сформируем четкий план действий для администратора базы данных по локализации и устранению данной проблемы:
.DBF, чей размер превышает 1 ГБ (обычно это 1SENTRY.DBF, 1SBKTTL.DBF, или файлы таблиц регистров RG*, RA*).*.CDX.