1с как узнать размер хранилища
Данная публикация не претендует на использование в продакшене, но когда "Нельзя, но очень хочется" в отношении получения ооочень больших данных из ХранилищаЗначения и когда сама платформа не может получить значение и падает, при этом, перед падением съедает почти всю память. Это своего рода костыль, в безвыходной ситуации. Речь пойдет про получение больших данных из хранилища значения в файловых базах на 32-х битной платформе. Данное не касается 64-х битных клиентов/серверов где нет ограничения на размер потребляемой памяти (верней есть, но доступно памяти гораздо больше, чем 32-х битному приложению без PAE).
А вы знали? 1С любит держать данные помещенные в ХранилищеЗначения в временном файле на диске? Разумеется имеется ввиду те данные, то лежат в памяти. Возможно, она так любит избавляться только от больших данных, но это уже совсем другая история.
Суть решения "проста", запакованное хранилище значения из себя представляет данные, запакованные алгоритмом Deflate (которая сама 1С использует везде, а доступа к методам дать не могут) и некоторое служебные данные. Этим же методом Deflate, упаковываются ZIP архивы. Итого весь процесс проводится к следующему:
1) Получение из хранилища значений двоичных данных (да-да, 1С не добавила возможности прямого получения):
2) Получаем буфер двоичных за вычетом префикса хранилища значения
3) Формируем структуру ZIP архива и добавляем к нему данные из буфера двоичных данных
4) Распаковать ZIP архив, игнорируя ошибки распаковки (так как у нас нет данных о CRC сумме НЕ запакованных данных, а так же об их размере)
5) На выходе, мы уже получаем распакованные данные, которые были помещены в хранилище значения, НО, они окружены структурой, похожей на JSON которая всюду используется в 1С как минимум с 1С 7.7 (или даже раньше), для того чтобы от неё избавится, надо в начале файла отрезать чуток и в конце, а так-же убрать экранирование кавычек. Тут я пробовал разные варианты (кроме считывания всего текста и СтрЗаменить, ибо память не безлимитная, но и такой способ работает и 1С не падает), но самым оптимальным как по скорости, так и по потреблению памяти, оказалось порционное чтение из файла, замена двойных кавычек на одинарные и запись в результирующий файл (выполняется мгновенно, пруфов нет)
7) Так же не забывайте убирать за собой, помогите сборщику мусора 1С, донесите свой мусор хотя бы до помойки:
Как и писалось в анонсе, данный способ не претендует на использование в продакшене (хотя мы у себя впилили, вместо ХранилищеЗначение.Получить() на проде), но надеюсь, данная публикация вам поможет, когда нужно через хранилище значения, передать много данных, а штатный механизм прожорлив или вообще падает (как в моём случае). Разумеется, вы бы сделали лучше чем я и код фактически один большой костыль.
Тем же, кто думает о своей реализации обмена данными через веб-сервис, я бы пожалуй посоветовал паковку в ZIP архив на сервере (можно даже в памяти это сделать, без записи на диск) и передавать двоичные данные, а на клиенте уже сохранить полученные двоичные данные на диск, а дальше можно использовать типовой механизм.
Выражаю благодарность автору обработки, которая сделала сказку - былью!
Если у вас есть лишние помидоры и яйца, то вспомните о голодающих ;)
PS: Прошу обратить внимание на то, что данная публикация, получает строку, помещенную в хранилище значение, если вы хотите таким образов получать другие типы данных помещенные в хранилище значение, вам явно придется вооружится напильником, но нет ничего не возможного!
PS: Так же надо учитывать, что данный способ медленней чем штатный способ получения значения! Обратите так же внимание, тестировать обработку лучше в файловой базе или хотя бы на 32-х битном сервере 1С, где есть техническое ограничение на потребляемую память. На 64-х битном сервере 1С, даже очень большие данные сможет получить. Да, обработка не демонстрирует проблему, а демонстрирует решение.
Часто возникает необходимость понять, почему база данных 1С занимает много места. Особенно если это новый клиент\проект.
1. Увеличилось количество вводимых данных.
2. Хранение детальной аналитики предыдущих лет.
Здесь тоже все просто. Компания работает на рынке 5-10 лет и сверткой информационной базы никто не занимался. База потихоньку росла, и в какой-то момент размер стал сказываться на производительности. Обработка по свертке информационной базы нам поможет.
3. Активное использования хранилища дополнительной информации.
Именно для оценки данного параметра и написана текущая обработка.
Сама функция расчета занимаемого места взята отсюда:
для 32-битной системы — 2гб
для 64-разрядной — 4 гб
Для того чтобы увеличить размер адресной памяти, необходимо:
Запустить командную строку: «Пуск — Выполнить» — введите CMD и нажмите enter.
Введите в командной строке «bcdedit /set increaseuserva 3072″, где 3072 — размер желаемой адресной памяти.
Перезагрузите компьютер.
Попробуйте выполнить действие в 1С 8, которое не получалось ранее.
Если всё получилось и операция повторяется не так часто, рекомендуется вернуть размер адресной памяти к значению по умолчанию с помощью команды «bcdedit /deletevalue increaseuserva».
При открытии обработки заполняется поле для отбора, где можно просмотреть наиболее используемые типы данных.
Нужно установить отбор по выбранным типам объектов.
Или отметить необходимое количество объектов для оценки.
После выбора необходимых данных. На вкладке размер жмем кнопку "Заполнить размер".
Также можно остановить расчет Ctrl+Break (ОбработкаПрерыванияПользователя())
Обработка проверялась на работоспособность в конфигурации:
Управление торговым предприятием для Украины редакция 1.2.51.2
Но должна работать во всех типовых конфигурациях, где есть справочник "Хранилище дополнительной информации".
Часто возникает необходимость понять, почему база данных 1С занимает много места. Особенно если это новый клиент\проект.
1. Увеличилось количество вводимых данных.
2. Хранение детальной аналитики предыдущих лет.
Здесь тоже все просто. Компания работает на рынке 5-10 лет и сверткой информационной базы никто не занимался. База потихоньку росла, и в какой-то момент размер стал сказываться на производительности. Обработка по свертке информационной базы нам поможет.
3. Активное использования хранилища дополнительной информации.
Именно для оценки данного параметра и написана текущая обработка.
Сама функция расчета занимаемого места взята отсюда:
для 32-битной системы — 2гб
для 64-разрядной — 4 гб
Для того чтобы увеличить размер адресной памяти, необходимо:
Запустить командную строку: «Пуск — Выполнить» — введите CMD и нажмите enter.
Введите в командной строке «bcdedit /set increaseuserva 3072″, где 3072 — размер желаемой адресной памяти.
Перезагрузите компьютер.
Попробуйте выполнить действие в 1С 8, которое не получалось ранее.
Если всё получилось и операция повторяется не так часто, рекомендуется вернуть размер адресной памяти к значению по умолчанию с помощью команды «bcdedit /deletevalue increaseuserva».
При открытии обработки заполняется поле для отбора, где можно просмотреть наиболее используемые типы данных.
Нужно установить отбор по выбранным типам объектов.
Или отметить необходимое количество объектов для оценки.
После выбора необходимых данных. На вкладке размер жмем кнопку "Заполнить размер".
Также можно остановить расчет Ctrl+Break (ОбработкаПрерыванияПользователя())
Обработка проверялась на работоспособность в конфигурации:
Управление торговым предприятием для Украины редакция 1.2.51.2
Но должна работать во всех типовых конфигурациях, где есть справочник "Хранилище дополнительной информации".
Не раз приходилось мне объясняться с нашим системным администратором по вопросу неожиданного роста базы данных. И вот наконец решил больше не гадать о причинах и написал такой инструмент.
Идея очень проста:
1. Вводим строку подключения к серверу баз данных. Нажимаем кнопку "Заполнить структуру БД".
1. Строится дерево метаданных и реальных таблиц в которых хранятся объекты.
2. Обработка обращается напрямую к серверу баз данных и для каждой реальной таблицы производится запрос с определением ее физического размера.
3. Полученные данные о размере выводятся в дерево метаданных, суммируются итоги.
4. Изучаем, идем разговаривать с админом))))
Опробовано на MS SQL Server 2008.
Специальные предложения
Чего то не могу к базе данных на сервере подключится. Для входа на сервер какое имя и пароль использовать? С которыми входишь на sql-сервер?
: Ошибка при вызове метода контекста (NextRecordset)
RS = RS.NextRecordset();
по причине:
Произошла исключительная ситуация (ADODB.Recordset): Текущий проводник не поддерживает возврат нескольких наборов записей в результате одной операции.Форма.Форма.Форма(120)>
Ну ну интересно интересно. Обьработка судя по скринам мега полезная но нету денег как появятся обязательно скачаю
Пример строки запроса
Тоже вылезала ошибка на RS = RS.NextRecordset(); пока не изменил поставщика на SQL Server Native Client 10.0 - с ней заработала.
Provider=SQLNCLI10.1;Integrated Security=SSPI;Persist Security Info=False;User ;Initial Catalog=database_name;Data Source=server-addres;Initial File Name="";Server SPN=""
спасибо за обработку давно искал (+)
Я подключаюсь через MS OLE DB Provider for SQL Server.
Строка подключения выглядит так:
Provider=SQLOLEDB.1;Persist Security Info=False;User Catalog=databasename;Data Source= SERVER
(7) вырос объем базы, и были только несколько предположений, с помощь обработки все подтвердил. Есть один удаленный филиал, объем с которым осуществляется по электронной почте, в результате отсутствия связи файл обмена вырос и они хранились в самой БД.
(7) да заработало. Пытался ввести доменный логин и пароль, затем пароль пользователя базы 1С с полными правами. Выкидывало в ошибку. Затем поставил чекбокс в NT и все само заработало!
Спасибо, очень помогла. Размер базы удалось уменьшить с 7.1 Гб до 5.7 Гб (оказывается кадры загрузили весь кладр)
Пожалуйста))) Рад что смог помочь!
У нас как-то при очередном обновлении УПП база выросла на 20 Гб.
Как потом разобрались причиной послужило автоматическое включение типового механизма версионирования.
: Ошибка при вызове метода контекста (NextRecordset)
RS = RS.NextRecordset();
по причине:
Произошла исключительная ситуация (ADODB.Recordset): Текущий поставщик не поддерживает возврат нескольких наборов записей в результате выполнения одной операции.
Строка подключения:
Provider=SQLOLEDB.1;Persist Security Info=False;User Catalog=cat;Data Source=server
Поставщика на SQL Server Native Client 10.0 в списке нет
(10) dka80, тоже бьюсь над этой проблеммой .
такая ошибка вылетает иногда причем я заметил только на больших таблицах. И выпадает она именно из за того, что когда выполняется sp_spaceused иногда происходит конфликт блокировок в итоге селект не возвращает ничего и 1С вылетет .
Пытаюсь бороться с этим уже недели и в транзакции запускал и время соединения (таймаут) увеличивал, все равно иногда вылетает.:( :(
Очень обидно так как эту замечательную обработку настроил так чтобы она выгружала информацию о статистике в отдельно стоящую базу, в которой накапливаются данных о наших 15 информационных базах. В итоге наконец то получил общую статистику по размерам. Теперь бы сделать так чтобы сбор статистики работал стабильно, чтобы можно было ее запускать регулярно.
Вопрос к автору. Во первых огромное спасибо за обработку и во вторы можно ли с Вами как то связаться е-майл, телефон, скайп? Может постараемся как то совместно решить данную проблему? Я очень заинтересован в развитии данной обработке и думаю что сделаю следующие дополнительные опции:
1) Выгрузка данных в отдельно стоящее хранилище - простенькая БД с табличками Сервер, БазаДанных, Таблица1С_СКЭЛЬ, ЛогРазмеров на каждую дату.
2) Дополнительно хочу сделать выгрузку по каждой таблице размера индекса и статистике их использования, по аналогии с таблицами получать данные по DM_DB_INDEX_OPERATIONAL_STATS,DM_DB_INDEX_USAGE_STATS, sp_MSindexspace
3) накапливание статистики по рекомендуемым индексам в БД
(10) dka80, SQL Server Native Client 10.0 может и отсутствовать на клиенте, если только вы не ставили его специально, по умолчанию он отсутствует, как выход - переделать на встроенный SQL Server, разницы не будет ни какой.
: Ошибка при вызове метода контекста (NextRecordset)
RS = RS.NextRecordset();
по причине:
Произошла исключительная ситуация (ADODB.Recordset): Текущий проводник не поддерживает возврат нескольких наборов записей в результате одной операции.Форма.Форма.Форма(120)>
Урааа. Две недели бился :)
кажется решил проблему с таймаутом и ошибкой Текущий поставщик не поддерживает возврат нескольких наборов записей в результате
попробуйте изменить следующее:
RS = Новый COMОбъект("ADODB.Recordset");
cmd = Новый COMОбъект("ADODB.Command");
cmd.ActiveConnection = Connect;
cmd.CommandText = СтрЗаменить(ШаблонЗапроса,"%ИмяТаблицы%",Строка.ТаблицаSQL);
//Добавляем информацию о тамймауте.
cmd.CommandTimeout=360;
Попытка
//при вызове рекодсета так - он не использует настройки таймаута.
//RS.Open(СтрЗаменить(ШаблонЗапроса,"%ИмяТаблицы%",Строка.ТаблицаSQL), Connect);
//Вызываем рекордсет через RS=cmd.Execute(); RS=cmd.Execute();
Исключение
Сообщить(ОписаниеОшибки());
Сообщить("------------------");
сообщить(СтрЗаменить(ШаблонЗапроса,"%ИмяТаблицы%",Строка.ТаблицаSQL));
КонецПопытки;
Для информации - мой вариант запроса по размерам таблицы.
1) Была проблема когда параллельно выгружаешь данные из нескольких баз а временная таблица одна. Для каждой базы нужно создавать таблицу со своим имененм. Переменная должна быть инициализирована выше.
2) Добавил перед началом удаление таблицы если она существует.
3) Если по каким то причинам запрос вылетает (у меня иногда бывает, когда запускаешь в консоли - конфликты блокировок, сделал так чтобы команда выполнялась 30 раз в цикле, если возникает какая то проблема.
Вы получаете только таблицы с ссылками на объекты. Сколько реально данных и их объем по объектам метаданных (хоть документ, хоть - регистр), вы и близко не получаете.
В 1с практически нет связей "один объект - одна таблица" (только для самых примитивных "объектов" - которые представлены примитивными типами данных). Это не реляционная система хранения данных. Чтобы получить объем данных по объекту - нужно по ссылкам найти все завязанные на этот объект данные по всем смежным таблицам.
А вы просто получате данные по списку объектов, который, собственно, вы можете получить любым списком в 1С, а не по самим объектам. И умножить на вес полей в таблице хранения - и получите тот же самый объем таблицы хранения ссылок.
(16) AlexO, изучите обработку повнимательнее.
Для каждого объекта выводятся таблицы SQL в которых он хранится.
Регистр - Основная, Итоги.
Документ, Справочник - Основная, Табличные части.
Для каждой реальной таблицы определяется ее размер средством запроса к SQL серверу.
Не понятен крик Вашей души. Что не так?
(17)
т.е. вы даже не занете, как ваша обработка работает?
и что даже на скриншоте у вас - одна таблица к каждому объекту и вес/количество записей в ней?
(18) AlexO, вы даже скриншот внимательно не посмотрели))))
и вот что там нарисовано:
Что вы имели ввиду?
то, что у вас один объект - одна таблица, и подсчет только по этой таблице. А в 1С такого не бывает - чтобы объект занимал одну таблицу (документ там, или справочник; понятно, что можно получить "вес" всех записей регистра - но какое это имеет отношение к "весу", скажем, документов?).
В 1С данные по объектам "размазаны" по базе, а не в одной таблице находятся.
(19)
вы одного не поймете - что чтобы получить объем, например, определенного вида документов, нужно оценить все таблицы как самих документов, так и их взаимодействие: проводки по регистрам (что вы и оцениваете как "вес объекта"), использование данных (и создание под это новых структур хранения в базе - т.е. увеличение занимаемого базой места) из них в других объектах и т.д.
(28) AlexO,
Вы тестировали обработку ? Сравнивали полученный результат с размером файла базы данных?
Один в один они конечно не сойдутся, всегда будет отличие на объем служебных таблиц.
Скачайте, сравните, потом претензии.
Интересная обработка
У меня при формировании выдала ошибку:
Не удалось соединиться с SQL - сервером
: Ошибка при вызове метода контекста (Open): Произошла исключительная ситуация (Microsoft OLE DB Provider for SQL Server): Ошибка входа пользователя "sa".
Ошибку удалось обойти выбрав сохранить пароль.
Работает. Может пригодиться.
Безвариантное представление информации - только дерево, ни фильтров, ни смены сортировки, но это легко решаемо.
Надобность вручную вписать строку подключения напрягла, но не сильно, минут на 5.
А вот что хотелось бы сразу видеть в статье - что запускать обработку надо в той же базе, для которой берешь статистику. А то я было разогнался в другую базу, мол, всё равно строку подключения целиком пишу ;-]
Грех не плюсануть наследника Базопузомера!
Однако воспользоваться обработкой не смогу. У меня нет MsSQL. Пользую PostgreSQL.
Обработка, которая когда-то была заброшена на стадии позднего бета-тестирования. То есть выполняет основное предназначение, но не дошлифована в некоторых моментах (в основном в выводе результатов на СКД). Планов дорабатывать нет, поэтому если кто-нибудь доработает и выложит на данном ресурсе - на здоровье.
Обработка находит пользовательские данные, которые хранятся в виде хранилища значений. Так как хранилище значения может иметь достаточно большой объем, то даже один элемент справочника может в базе данных занимать очень много места.
Если база данных серверная, то оптимальнее и быстрее размер данных смотреть в базе SQL-сервера (или где там у вас хранится база). В нормальном случае человек мало-мальски разбирающийся в sql-запросах должен сделать это быстро.
Так как нет вариантов средствами 1с сделать запрос с получением размеров данных расположенных в Хранилище значений, то обработка последовательно перебирает объекты, извлекает данные из хранилища значений и вычисляет размер. Если данных много, то процесс может занять длительное время. В подобном случае прерывание процесса стандартное Ctrl+Break. После этого можно выполнять обработку данных порционно - по видам документов, справочников и т.д.
Акцентирую внимание - теоретически отчет может использовать любой пользователь, однако необходимы полны права при его работе, так как отчет смотрит практически все пользовательские объекты в базе данных.
На форме предварительного просмотра формируется список видов пользовательских объектов у которых хотя бы один реквизит имеет тип ХранилищеЗначений. В скобках приводится информация о количестве объектов данного вида. При установке галочки "Не выводить имеющие ноль элементов" виды объектов при отсутствии данных не будут выведены в таблицу.
Выделив необходимые виды объектов или даже только некоторые реквизиты в видах объектов, можно запустить отчет на расчет данных и вывод их в форму СКД.
В чем прелесть СКД - богатые возможности по работе с данными (отбор, сортировка и прочее). Кроме того, результаты можно сохранить в приемлемом формате (все поддерживаемые форматы 1с).
Отчет разрабатывался на платформе 8.2.19.130
При создании статьи небольшая проверка (ну и скриншоты) были выполнены на платформе 8.3.8.1675
Так как отчет был полем изучения некоторых возможностей 1Cv8 и, в частности, СКД там наворочено следующее (что помню).
1. Это внешний отчет и нем есть возможность открыть одновременно несколько форм с результатами. Насколько помню в стандартном случае это невозможно, поэтому пришлось делать часть вывода программно.
2. На ресурсе есть отчет с выводом аналогичных данных. В отличии от него данный отчет проверяет также табличные части.
3. Отчет считает объем которые занимает ХранилищеЗначений в базе. И даже если значение равно Неопределено, то в базе данных это занимает место.
Некоторые аспекты программирования в 1С умышленно освещаются в стиле "для дилетантов", и если при этом не обладает любознательностью и стремлением расширить кругозор, то возникают ненужные темы "как гадать по звездам в 1С" 😄
4. Подсчет размера с помощью ДанныеBase64 = Base64Строка(ДанныеХранилища) решил не применять, так как получаем сбой если в хранилище лежат не двоичные данные, картинка или строка (например в константе лежит Структура).
Читайте также: