В процессе эксплуатации крупных баз данных на платформе 1С:Предприятие 7.7 в файловом режиме (DBF) технические специалисты часто сталкиваются со странным поведением отчетов. Один и тот же отчет (например, Оборотно-сальдовая ведомость), сформированный за один и тот же период, в разное время выдает совершенно разные результаты. При этом в момент формирования отчета другие пользователи могут активно вводить документы и разносить оплаты в системе. Примечательно, что периоды ввода документов и формирования отчета могут не пересекаться (например, отчет строится за август, а документы вводятся сентябрем), но данные все равно искажаются.
В этой статье мы подробно разберем, почему возникает эта серьезная проблема, как работает скрытый механизм СУБД, приводящий к порче выборок, и рассмотрим все практические способы решения — от установки системных патчей до оптимизации структуры базы данных.
Выясним истинную причину этой проблемы, которая в кругах разработчиков 1С 7.7 получила название «проблема 1 Гигабайта».
Описанное поведение системы — это не случайный сбой индексов и не ошибка в коде отчета. Это фундаментальное ограничение файлового движка CodeBase, на котором построена DBF-версия платформы 1С 7.7. Ошибка начинает проявлять себя только тогда, когда размер хотя бы одного из файлов движений регистра (файл вида RA*.dbf) или таблицы бухгалтерских итогов превышает критический порог в 1 ГБ (1 073 741 824 байт).
Разберем физику процесса по шагам:
LockFile и UnlockFile из библиотеки kernel32.dll.RA*.dbf имеет физический размер менее 1 ГБ, все блокировки операционной системы проецируются на несуществующие (виртуальные) адреса файла. База данных работает стабильно: один пользователь пишет новые движения, а второй без проблем читает старые данные для отчета.RA*.dbf перешагивает отметку в 1 ГБ, его реальные физические секторы с данными начинают пересекаться с областью, куда операционная система накладывает виртуальные блокировки.В итоге ваш отчет формируется без части движений и выдает некорректные остатки. Как только активная запись в базу прекращается (например, в обеденный перерыв или вечером), блокировки снимаются, и тот же самый отчет внезапно начинает показывать абсолютно правильные данные. Рассмотрим, как решить эту проблему раз и навсегда.
Самым простым и эффективным способом решения коллизии блокировок без изменения структуры базы данных является смещение виртуальной области блокировок в зону, недостижимую для физического размера DBF. Поскольку максимальный размер любого DBF-файла в 1С 7.7 ограничен самой операционной системой и платформой в 2 ГБ, достаточно перенести область блокировок за предел в 2 ГБ.
Для этого используется известная в сообществе 1С утилита/патч Kernel3x (разработки специалистов Hogik, Romix и др.).
Проанализируем механизм работы данного решения:
Seven.dll или DBEng32.dll.Важно: Перед установкой патча обязательно сделайте полную резервную копию каталога базы данных и исполняемых файлов платформы! Установка патча производится путем замены оригинальных библиотек в каталоге установки платформы 1С 7.7 (обычно в папке C:\Program Files (x86)\1Cv77\bin\) на пропатченные версии или использованием специального загрузчика.
После устранения проблемы с блокировками (или при возникновении расхождений в результатах работы регистров) часто требуется выполнить пересчет итогов. Запуск штатной процедуры «Тестирование и исправление» в Конфигураторе на базе размером в несколько гигабайт может занять много часов. Если сбоит конкретный регистр, мы можем выполнить пересчет только по нему, используя недокументированную, но крайне эффективную методику.
Разберем этот алгоритм по шагам:
1cv7.dd. Файлы регистра будут иметь вид RA***.dbf (таблица движений) и RG***.dbf (таблица итогов), где вместо звездочек указан уникальный числовой идентификатор объекта.RG***.dbf и соответствующий ему индексный файл RG***.cdx. Файл движений RA***.dbf (который весит 1.2 ГБ) трогать нельзя — в нем хранятся все ваши исторические данные.RG*.dbf и движений RA*.dbf других регистров вашей системы. В рабочем каталоге базы данных из файлов регистров должен остаться только один-единственный файл движений нужного нам регистра RA***.dbf.RG***.dbf для оставшегося регистра, автоматически создаст его заново и последовательно пересчитает в него итоги на основе движений из файла RA***.dbf. Поскольку все остальные регистры были временно удалены из каталога, этот процесс займет считанные минуты вместо часов.RA и RG обратно в рабочий каталог базы данных с заменой файлов.*.cdx.После этой процедуры итоги по проблемному регистру будут полностью и корректно пересчитаны.
Если ваша база данных активно растет, а размер файлов приближается к критическому лимиту в 2 ГБ, установка патчей блокировок — это лишь временная полумера. Единственным кардинальным решением является перенос базы данных на клиент-серверную СУБД (Microsoft SQL Server).
Проанализируем преимущества и особенности этого перехода:
Если переходить на полноценный SQL-сервер долго и дорого, рассмотрите технологию Advantage Database Server (ADS). Это специализированный клиент-серверный движок для работы с DBF-файлами.
При использовании ADS блокировки файлов обрабатываются не средствами операционной системы Windows по сети, а непосредственно службой (сервером) ADS. Это полностью исключает возникновение коллизии 1 ГБ, устраняет сетевой трафик по прокачке индексов и значительно повышает скорость работы файловой версии 1С 7.7, сохраняя привычный формат хранения данных DBF.
В обсуждении было упомянуто, что сложный отчет на базе регистров строится около 1 часа. Это критически долго и само по себе создает повышенную нагрузку на дисковую подсистему и сеть, усугубляя проблему блокировок.
Стандартный механизм запросов 1С 7.7 в файловом режиме при построении отчета затягивает весь объем файла регистра с сервера на локальную машину пользователя по сети и обрабатывает его локально. Чтобы кардинально решить эту проблему, рекомендуется переписать тяжелые отчеты на технологию прямых запросов с использованием внешней компоненты 1С++.
Посмотрим на пример логики прямого запроса к DBF-файлу с помощью класса ODBCRecordset из состава ВК 1С++:
// Создаем объект для выполнения прямого запроса к таблицам базы данных
Запрос = СоздатьОбъект("ODBCRecordset");
// Формируем текст SQL-подобного запроса непосредственно к файлу движений регистра
ТекстЗапроса = "
|SELECT
| Reg.SP1234 AS [Товар $Справочник.Номенклатура],
| SUM(Reg.SP1235) AS [КоличествоОборот]
|FROM
| [Регистр.Продажи] AS Reg
|WHERE
| Reg.Date_Time_IDDoc BETWEEN :НачДата AND :КонДата~
|GROUP BY
| Reg.SP1234
|";
Запрос.УстановитьТекстовыйПараметр("НачДата", ВыбНачПериода);
Запрос.УстановитьТекстовыйПараметр("КонДата", ВыбКонПериода);
// Выполняем запрос и получаем результат в таблицу значений за доли секунды
ТабРезультат = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
Использование таких прямых запросов позволяет сократить время формирования отчетов с 1 часа до нескольких секунд или минут. Быстро выполняющийся отчет практически не занимает системные ресурсы, не удерживает блокировки файлов и сводит вероятность коллизий к минимуму.
Если вы хотите остаться на стандартной платформе 1С 7.7 DBF без внедрения сторонних патчей и утилит, единственным легальным способом уменьшить размер файлов регистров и вернуть базу в безопасную зону (менее 1 ГБ) является проведение процедуры свертки базы данных.
Свертка включает в себя:
Это позволит физически уменьшить размер файлов RA*.dbf и RG*.dbf, разгрузить систему и вернуть стабильность при формировании регламентированной отчетности.