Е.В.Филиппов Настольная книга 1С:Эксперта по технологическим вопросам. Издание 2 Электронная книга в формате pdf; ISBN 978-5-9677-2475-6. Электронный аналог издания "Настольная книга 1С:Эксперта по технологическим вопросам" (ISBN 978-5-96772354-4, М.: ООО "1С-Паблишинг", 2015; артикул печатной книги по прайс-листу фирмы "1С": 4601546118530). По вопросам приобретения печатных изданий издательства «1С-Паблишинг» обращайтесь к партнеру «1С», обслуживающему вашу организацию, или к другим партнерам фирмы «1С», в магазины «1С Интерес», а также в книжные и интернет-магазины). «Настольная книга 1С:Эксперта по технологическим вопросам» посвящена теории и практике решения проблем производительности и параллельности в информационных системах на платформе «1С:Предприятие 8». В работе приводятся теоретические сведения, необходимые для понимания основных механизмов, обеспечивающих функционирование платформы «1С:Предприятие 8» и СУБД как многоуровневой многопользовательской системы. Кроме этого, дается алгоритм основного бизнес-процесса расследования проблем и приводятся практические приемы решения конкретных прикладных задач: описывается развертывание, настройка и использование инструментов для воспроизведения и расследования, а также возможные способы исправления, применяемые, когда причины проблем найдены. При работе был учтен опыт подготовки сотрудников на аттестацию 1С:Эксперт по технологическим вопросам: в книге собраны необходимые для подготовки к аттестации материалы и методики. Также в книгу вошли методики, наработанные автором за длительный срок решения практических проблем производительности и параллельности. В значительной степени это методики профилактики, регулярного контроля и ранней диагностики. Во втором издании скорректированы неточности в теоретической части и в инструкциях, а также добавлены новые материалы. Для 1С:Экспертов по технологическим вопросам, для сотрудников ИТ-служб заказчика (ИТдиректоров, системных администраторов, методистов, администраторов СУБД), а также для сотрудников фирм-1С:Франчайзи: внедренцев, разработчиков, руководителей проектов. Оглавление Глава 1. Поднимемся на крыльцо, откроем дверь..............................................................9 Глава 2. Основной подход к решению проблем.................................................................11 2.1. Мы работаем только с проблемами......................................................................................................................... 11 2.2. Как измерять, как получать цифры............................................................................................................................ 16 2.3. Как устроена система................................................................................................................................................. 17 2.4. Бизнес-процесс решения проблем по ключевым операциям............................................................................... 20 Глава 3. Теория.........................................................................................................................25 3.1. Ключевые операции.................................................................................................................................................... 25 3.2. Методика APDEX......................................................................................................................................................... 27 3.3. Критичные ошибки...................................................................................................................................................... 29 3.4. Расчет доступности системы..................................................................................................................................... 30 3.5. Регламентные работы................................................................................................................................................ 34 3.6. Транзакции. Уровни изоляции транзакций. Явные и неявные транзакции. Вложенные транзакции. Откат транзакций.................................................................................................................................... 37 3.7. Блокировки данных СУБД. Уровни блокировок. Совместимость блокировок........................................................ 50 3.8. Сведения об управляемых и объектных блокировках............................................................................................. 54 3.9. Ошибки блокировок: таймауты и взаимоблокировки.............................................................................................. 57 Общие вопросы................................................................................................................................................................................. 57 Таймаут.............................................................................................................................................................................................. 59 Взаимоблокировка (deadlock)........................................................................................................................................................... 61 3.10. Эскалация блокировок.............................................................................................................................................. 66 3.11. Сведения о параллельности операций с данными разных типов......................................................................... 68 Общие сведения................................................................................................................................................................................ 68 Узкие места........................................................................................................................................................................................ 70 Реальные транзакции Запись + Запись........................................................................................................................................... 73 Реальные транзакции Чтение + Запись................................................................................................................................................................................................................................................. 73 3.12. Сведения о размещении данных. Способ получения этих сведений................................................................... 77 3.13. Сведения об индексах базы. Способ получения этих сведений. Кластерный и некластерные индексы.................................................................................................................... 84 Важное дополнение по индексам для 8.3 без режима совместимости....................................................................................... 92 4 Настольная книга 1С:Эксперта по технологическим вопросам 3.14. Планы запросов. Получение плана запроса в профайлере SQL. Операторы плана, наиболее важные для нас........................................................................................................................................ 94 Получение плана запроса в профайлере SQL............................................................................................................................... 94 Наиболее важные для нас операторы........................................................................................................................................... 101 3.15. Особенности чтения в объектной модели........................................................................................................... 106 3.16. Работа с SQL Server. Где хранятся временные таблицы. Где хранятся снимки Snapshot для уровня изоляции Read Committed Snapshot.................................................................................................. 108 3.17. Работа с SQL Server. Где размещать базы. Как переносить базы.................................................................... 109 3.18. Работа с SQL Server. Различия между полной (FULL) и простой (SIMPLE) моделями восстановления базы. Особенности сжатия журнала транзакций...................................................................... 112 3.19. Работа с SQL Server. Настройка и использование бэкапов различных видов................................................ 118 Глава 4. Инструкции...............................................................................................................123 4.1. Как настроить сбор информации о загрузке оборудования и как оценить эту загрузку.................................... 123 4.2. Выяснение скорости диска....................................................................................................................................... 133 4.3. Настройка автоматического перезапуска сервера «1С»....................................................................................... 134 Перезапуск средствами платформы.............................................................................................................................................. 134 Перезапуск службы средствами операционной системы............................................................................................................ 135 4.4. Регламентные операции SQL Server и настройка их автоматического выполнения.......................................... 136 Общие вопросы............................................................................................................................................................................... 136 Обновление статистики SQL Server............................................................................................................................................... 137 Очистка процедурного кеша (кеша планов).................................................................................................................................. 138 Дефрагментация индексов............................................................................................................................................................. 139 Реиндексация таблиц базы............................................................................................................................................................ 140 Контроль выполнения регламентных заданий.............................................................................................................................. 141 4.5. Как включить технологический журнал «1С» и как его можно разбирать............................................................ 142 4.6. Общий подход к анализу технологического журнала «1С».................................................................................. 146 4.7. Замеры производительности................................................................................................................................... 146 Замер производительности отладчиком 1С8 ............................................................................................................................... 146 Простейший код замера времени.................................................................................................................................................. 147 Оценка производительности БСП (инструкция по установке, описание работы).............................................................................................................................. 148 4.8. Требования к сети. Как проверить сеть................................................................................................................. 153 Общие вопросы............................................................................................................................................................................... 153 Ошибки сети..................................................................................................................................................................................... 154 Недостаточная пропускная способность....................................................................................................................................... 156 Маршрутизация................................................................................................................................................................................ 157 Надстройки активного оборудования............................................................................................................................................. 158 Надстройки серверов ландшафта «1С»........................................................................................................................................ 158 Сетевые службы.............................................................................................................................................................................. 158 4.9. Сбор статистики дампов (общий принцип).............................................................................................................. 159 Автоматизированный сбор дампов................................................................................................................................................ 159 Сбор дампов вручную..................................................................................................................................................................... 161 4.10. Работа с ЦКК. Общие принципы, стандартные возможности, первичная настройка...................................... 162 Общие вопросы............................................................................................................................................................................... 162 Что надо сделать для начала работы........................................................................................................................................... 163 4.11. Работа с 4.12. Работа в 4.13. Работа в 4.14. Работа в ЦКК. Настройка собственных контрольных процедур......................................................................... 169 профайлере. Как получить план запроса............................................................................................. 172 профайлере. Как получить сумму duration........................................................................................... 172 профайлере. Как получить граф взаимоблокировки.......................................................................... 175 Оглавление 5 4.15. Работа в профайлере. Как получить сведения об эскалации блокировок........................................................ 177 4.16. Работа с ЦУП. Общие принципы, стандартные возможности, общая последовательность работы, мастер настройки, таблица прав............................................................................................................. 178 Общие вопросы............................................................................................................................................................................... 178 Что надо сделать для начала работы........................................................................................................................................... 179 Мастер подключения к базе.......................................................................................................................................................... 180 Права, необходимые для работы ЦУП.......................................................................................................................................... 193 4.17. Работа с 4.18. Работа с 4.19. Работа с 4.20. Работа в ЦУП. Получение плана запроса............................................................................................................ 196 ЦУП. Разбор взаимоблокировки........................................................................................................... 205 ЦУП. Регламентный мониторинг.......................................................................................................... 212 конфигураторе. Исправление запросов............................................................................................... 215 Список правил.................................................................................................................................................................................. 215 Пояснение к правилу 3 («ДЛЯ ИЗМЕНЕНИЯ»)............................................................................................................................ 217 Пояснение к правилу 4 (соответствие индексов и условий запроса)....................................................................................... 217 Пояснение к правилу 8 (не использовать подзапросы в условиях).......................................................................................... 221 Пояснение к правилу 9 (не использовать соединения с подзапросами, а использовать временные таблицы).................. 222 Пояснение к правилу 10 (не соединять виртуальные таблицы с реальными, а также виртуальные с виртуальными)........................................................................................................................................ 224 Пояснение к правилу 13 (в проблемных запросах отказываться от ИЛИ)..................................................................................................................................................................... 227 Пояснение к правилу 14 (избегать запросов к пустым таблицам в режиме автоматического управления блокировками «1С»).................................................................................................... 227 Пояснение к правилу 15 (не получать значение через точку от поля составного типа)........................................................... 229 Пояснение к правилу 16 (понимать, как запрос может быть изменен платформой при работе механизма RLS)................. 231 4.21. Нагрузочные тесты................................................................................................................................................. 232 Простейший...................................................................................................................................................................................... 232 Останов в отладчике...................................................................................................................................................................... 232 Останов в модальной форме........................................................................................................................................................ 232 Нагрузочное тестирование групповыми обработками................................................................................................................. 233 Работа с Тест-центром. Общие принципы и стандартные возможности. Простой тест с помощью Тест-центра.............. 233 Встраивание Тест-центра............................................................................................................................................................... 235 Работа с Тест-центром. Шаблон полноформатного теста.......................................................................................................... 239 Работа с Тест-центром. Универсальный нагрузочный тест....................................................................................................... 244 Работа со Стандартным нагрузочным тестом «1С». Общие принципы и стандартные возможности........................................................................................................................................ 246 Новые возможности 8.3 по функциональному и нагрузочному тестированию........................................................................ 247 Классификация нагрузочных тестирований.................................................................................................................................. 256 Расследование падений платформы, ошибок блокировок и причин неудовлетворительной производительности, которые воспроизвелись при выполнении теста..................................................................................... 257 4.22. Бизнес-процесс общей диагностики...................................................................................................................... 257 4.23. Работа в конфигураторе. Редактирование параметра времени ожидания блокировки.................................. 259 4.24. Работа с ТЖ. Как посмотреть, какие управляемые блокировки были установлены....................................... 260 4.25. Работа с ТЖ. Как расследовать конфликт на управляемых блокировках....................................................... 261 4.26. Измерение динамики производительности по журналу регистрации............................................................... 265 4.27. Про открытие модальных окон в транзакции...................................................................................................... 266 4.28. Ловушка для получения стека вызовов, когда отладка недоступна................................................................... 268 4.29. Как собрать отказоустойчивый кластер 8.3 из двух серверов............................................................................ 270 4.30. Как оставить сервис лицензирования только на одном сервере кластера 8.3................................................. 274 6 Настольная книга 1С:Эксперта по технологическим вопросам 4.31. Как собрать отказоустойчивый кластер 8.2 из двух серверов............................................................................ 275 Настройка отказоустойчивой схемы 8.2 с масштабированием и балансировкой нагрузки.................................................... 279 4.32. Работа с ЦКК. Как сделать код доступным для отладки.................................................................................... 283 4.33. Работа с ЦКК. Развертывание для целей контроля ошибок блокировок.......................................................... 285 Глава 5. Методики и дополнительная информация.........................................................291 5.1. Обзор платных и бесплатных инструментов......................................................................................................... 291 5.2. Требования с диска ИТС, применяемые при проверке на 1С:Совместимо!, влияющие на производительность.......................................................................................................................................... 292 5.3. Уточнения, важные для общего понимания картины ............................................................................................ 295 5.4. Проектные и технические решения, приводящие к проблемам......................................................................... 296 5.5. Приемы конфигурирования, приводящие к проблемам....................................................................................... 297 5.6. Ежедневный мониторинг.......................................................................................................................................... 297 Глава 6. Дополнительные заметки......................................................................................299 6.1. Экономический смысл автоматизации учета и оптимизации производительности........................................... 299 6.2. О режиме доступности 24х7..................................................................................................................................... 301 6.3. О методике расчета оборудования......................................................................................................................... 302 6.4. О работах в различных СУБД................................................................................................................................. 303 Заключение. О гарантиях работоспособности системы через несколько лет...........305 Кому что читать......................................................................................................................309 Список сокращений................................................................................................................311 Об авторе Филиппов Евгений Валерьевич Имеет высшее техническое образование. В 2009 году первым провел успешное нагрузочное тестирование, в ходе которого в одной базе «1С:Предприятия» работало 1 000 пользователей, и экспериментально подтвердил работоспособность такой информационной системы. Работая в компаниях «Трейд Софт», а затем «1С:Первый БИТ», участвовал не менее чем в десяти проектах ЦКТП. В период подготовки второго издания руководил компанией «Центр технологической экспертизы Аксиома», специализировавшейся на проведении работ по нагрузочному тестированию и оптимизации производительности решений на платформе «1С:Предприятие». Ведет активную деятельность в направлении разработки механизмов и методик, которые снижают стоимость проведения таких работ и делают эти работы доступными для массового рынка. Проводит обучающие семинары и вебинары для сотрудников своей компании, партнеров и представителей клиентов. Замечания и предложения по данной книге принимаются на адрес publishing@1c.ru. Благодарности Автор выражает благодарность А. Н. Арламенкову, А. А. Долгову, А. В. Звонилову, А. Р. Зорину, И. Н. Костяковой, Н. А. Моисеенко, А. Н. Морозову, С. Г. Нуралиеву, К. В. Рупасову, И. И. Русаковой, П. А. Скловскому за поддержку и помощь, оказанную на разных этапах создания книги. 8 Настольная книга 1С:Эксперта по технологическим вопросам ГЛАВА 1 Поднимемся на крыльцо, откроем дверь Широкое распространение информационных систем на платформе «1С:Предприятие» неизбежно поставило вопрос повышения технологического качества работы этих систем. Связано это и с естественным ростом информационных систем вместе с ростом предприятий, их использующих, и с усложнением учета, которое становится возможным по мере вовлечения в информационную систему новых участков, и с ростом баз, происходящим в течение жизни информационных систем. И однажды эти количественные и качественные изменения могут вызвать (и вызывают) у людей, обслуживающих эти системы, проблему: новый уровень информационной системы требует, во-первых, изменения подхода к принципиальным схемам работы и к их технической реализации, а во-вторых, нового уровня обслуживания. На практике, однако, оказывается, что изменения подхода как к схемам и их воплощениям в виде решений, так и к обслуживанию могут запаздывать. В итоге в уже вполне больших и серьезных системах встречаются механизмы, которые выглядят как сколоченное из досок крыльцо для дачного домика в качестве входа в многоэтажный бизнес-центр. И ведь нельзя сказать, что дощатое крыльцо – это заведомо некачественная или негодная вещь, отнюдь нет. Оно вполне может быть сделано с любовью и сделано руками мастера: красиво, ровно, аккуратно, с украшениями. Вот только его объективные технические характеристики (ограниченная пропускная способность, низкая износостойкость и ограничения по массе и габаритам для проносимого по нему груза) не позволяют его рассматривать и использовать иначе, чем для маленького домика. И наоборот, шикарный стеклянный фасад с вращающимися или автоматическими дверями на дачных участках найти сложно: дорогое удовольствие, как в установке, так и в обслуживании. 10 Настольная книга 1С:Эксперта по технологическим вопросам Понятно, что и уровень обслуживания сложных механизмов должен быть другой: деревянную дверь вполне можно обслуживать только по факту возникновения проблем (смазывать петли), а у вращающихся или автоматических дверей состав и стоимость работ намного больше и определяется заводом-изготовителем. Дверь и крыльцо однако находятся у всех на виду. А механизмы информационных систем прямому восприятию на первый взгляд недоступны, и, к сожалению, нередка ситуация, когда кто-то начинает думать, как решить проблемы качества работы системы, только если эти проблемы уже стоят в полный рост в виде недовольных пользователей. Первоначально данная работа задумывалась именно как способ объяснить, что на самом деле работу систем на платформе «1С:Предприятие» можно видеть так же отчетливо, как входную дверь и очередь на вход, причем для этого не требуется никаких особых платных инструментов: все встроено в штатные механизмы. Эта идея в книге осталась, см. раздел 5.6 «Ежедневный мониторинг». Однако стало необходимо объяснить, что стоит за полученными при мониторинге показателями и что с ними делать дальше. Это потребовало в относительно полном объеме собрать и изложить материал, который требуется для подготовки 1С:Эксперта по технологическим вопросам. И постараться изложить не только сам материал, но и подход к его использованию, потому что эта информация раскидана по многим источникам. Тем, кто уже аттестовался как 1С:Эксперт по технологическим вопросам, известен замкнутый круг: чтобы правильно воспринять теорию, нужен правильный подход, но, чтобы использовать подход, нужно владеть теорией. Чтобы усвоить знания, нужен опыт, но, чтобы получить опыт, нужны знания. Проблема стоит даже не в сборе информации, а в отсутствии системного подхода к ее усвоению и применению. А ему учат в единственном месте: на специализированном курсе в «1С». На практике эта проблема решается тем, что специалисты посещают курс несколько раз и выходят из замкнутого круга, набрав требуемые знания и опыт и усвоив правильный подход к решению проблемы. Все бы ничего, но долго. А до этого момента новичок при решении практических задач оказывается беспомощным и реально самостоятельно работать не может. Поэтому в нашей работе сделана попытка объединить вместе и правильный процесс подхода к решению проблем, и теорию, и инструкции по работе с инструментами, и практические методики по отработанным ситуациям. Только все вместе это может дать цельную картину, необходимую для правильного понимания и успешного решения возникающих проблем. ГЛАВА 2 Основной подход к решению проблем 2.1. Мы работаем только с проблемами Для начала хотелось бы уточнить, какие именно задачи решают 1С:Эксперты по технологическим вопросам. Иногда случается, что задачи, которые нам присылают, формулируются так: провести аудит нашей системы управления торговлей, оценить: 1. Быстродействие системы. Анализ аппаратных и программных средств, поиск узких мест. Рекомендации по увеличению быстродействия. 2. Степень соответствия программного кода стандартам «1С». Возможно, дать рекомендации по исправлению, с расчетом стоимости работ. 3. Степень востребованности доработок функционала в системе. 4. Оптимальность реализации написанного функционала с точки зрения методологии (оптимальность бизнес-процессов) и с точки зрения программирования. Дать рекомендации по оптимизации. Дать рекомендации по развитию системы; в ближайшей перспективе планируется подключение баз пятнадцати филиалов. Можно высказать ряд догадок1, откуда именно берется подобная постановка задач, однако есть смысл сказать сразу: задача в подобной постановке решена быть не может. Хотя бы просто потому, что в ней не задано ни начальное, ни конечное состояние системы, ни само пространство состояний. Давать же рекомендации по переходу из одного неизвестного состояния в другое неизвестное состояние 1 Было высказано пожелание писать более конкретно и четко. К сожалению, когда приходится принимать решения в условиях высокой неопределенности и нечеткой постановки задачи, возможности что-либо конкретизировать практически не бывает; такая возможность появляется, только когда задача уже формализована. 12 Настольная книга 1С:Эксперта по технологическим вопросам в пространстве неопределенной размерности, а также оценивать стоимость работ по такому переходу как-то затруднительно, потому что потом за свои рекомендации придется отвечать. Тем не менее, если люди к вам обратились, значит, определенная потребность в ваших работах есть, и надо как-то выяснить, что именно их к вам привело и какую задачу нужно решить на самом деле. Для этого надо определить: пространство состояний системы, ■■ текущее состояние и мнение заказчика о нем, ■■ желаемое состояние и мнение о нем. Обычно бывает, что задача сводится к двум вариантам: ■■ 1. Работающая система. Заказчик обратился к вам, потому что текущее состояние системы его не устраивает. Это можно переформулировать так: пользователи, работающие в базе, сталкиваются с какими-либо проблемами. 2. Существенно изменяемая или проектируемая система. Заказчик обратился к вам, потому что у него есть ожидания, что после некоторых изменений в системе пользователи, работающие в базе, начнут сталкиваться с какими-либо проблемами. Текущее состояние системы его устраивает, но сама система находится на пороге изменений либо уже изменяется. В обоих случаях существует важный объект, называемый проблемой. Введение этого объекта позволяет определить пространство состояний системы и задать количественные характеристики, определяющие желательные и нежелательные состояния. Существует частный случай варианта 1. У нас все медленно работает. Сколько стоит посмотреть и исправить? Хотя пространство состояний определено (это время выполнения каких-то операций) и текущее состояние обозначено как нежелательное, для такого варианта бывает характерно, что по разным причинам более подробной детализации получить не удается. В таком случае, если требуется назвать сроки и стоимость работ, лучше договориться об экспресс-диагностике (см. раздел 4.22) и уже по итогам анализа данных, полученных о системе, попробовать самостоятельно сформулировать проблемы, требующие решения. Итак, что такое проблемы. Это те симптомы, которые видит (или потенциально увидит, если речь об изменениях системы) пользователь и которые определяют для него текущее состояние системы как нежелательное. К ним относятся: ■■ ■■ ■■ медленная работа, зависания, сообщения об ошибках. Основной подход к решению проблем 13 Это означает, например, что участок кода, при написании которого никто и не думал ни о каких стандартах и при написании которого оптимизировали затраты на его создание, а не время его выполнения, совершенно не обязательно надо дорабатывать, потому что может иметь место следующее: Этот код работает всегда с очень малым объемом данных и поэтому всегда выполняется быстро. Поясню: очень плохой код может выполняться за 0,1 с. Если его оптимизировать, он станет выполняться в 10 раз быстрее, т. е. за 0,01 с. Но поскольку абсолютное значение в 0,1 с мало само по себе, то такой код, скорее всего, оптимизировать не надо, даже если он написан совершенно ужасно. ■■ Этот код никогда не вызывается или вызывается раз в год. ■■ Любой другой пример, почему совершенно неоптимальный, в спешке написанный код может не создавать пользователям никаких проблем. Увидев такой код, совершенно не надо начинать его оптимизировать просто по факту его выявления. То, что пользователь «видит» проблемы, не обязательно означает, что он «жалуется» на них. Желание жаловаться является субъективным, подвержено изменениям и формализации не поддается, а это означает, что «наличие жалоб» в качестве формальной границы, отделяющей желательное состояние системы от нежелательного, не годится совершенно. ■■ И хотя очень многие службы поддержки на практике используют количество обращений и жалоб в качестве одного из основных показателей своей деятельности, качественный мониторинг проблем при таком подходе весьма затруднителен. Поэтому надо понять, что проблема – это симптом, который пользователь видит. А реагирует он на него или нет – нас не интересует, так как система содержит средства, позволяющие нам наблюдать эти же симптомы. Нас интересует, вышли ли некоторые объективно измеряемые характеристики этого симптома из зоны желательных значений или нет, а получать эти сведения можно и без привлечения пользователей. Однако, несмотря на наше стремление определить пространство состояний исключительно в объективно измеряемых показателях, этого сделать не удается. Есть две вещи, определяющие размерность и границы пространства состояний, являющиеся по определению субъективными, поскольку они не измеряются, а назначаются человеком: важность проблемы: количеством важных проблем определяется размерность пространства состояний, относительная важность (приоритет) определяет порядок осей координат этого пространства; ■■ разделение количественных значений характеристик на желательные и нежелательные (а также в некоторой степени желательные, если допускается нечеткость подмножеств): этим определяются границы областей пространства состояний, в которых мы будем работать. Несмотря на такую субъективность и, возможно, нечеткость, существует единственный разумный способ формализовать важность и желательность – зафиксировать список важных проблем, их относительную важность (приоритеты) ■■ 14 Настольная книга 1С:Эксперта по технологическим вопросам и желательные значения количественно измеряемых показателей этих проблем в договоре. Если важная проблема возникает вследствие превышения допустимого значения длительности выполнения системой некоторого действия, такое действие называют ключевой операцией. То есть, говоря наоборот: ключевая операция – это операция (действие) системы, у которой количественной характеристикой, определяющей наступление нежелательного состояния, является время выполнения этой операции, и наступление этого нежелательного состояния является важной проблемой. Обычно ключевая операция – это однократное нажатие пользователем какой-то кнопки на форме или выбор пункта меню, а время выполнения – это время, за которое система это нажатие отрабатывает. Иногда разные кнопки могут интерпретироваться как одна и та же ключевая операция (но обычно при этом системой выполняются одни и те же действия: проведение документа, формирование отчета, открытие формы и т. п.). Когда таких действий выполнено много, имеет смысл как-то сворачивать в число совокупность всех полученных значений длительности их выполнения (получать интегральную характеристику). Фирмой «1С» в качестве способа такой свертки применяется методика APDEX. Подробнее о понятии ключевой операции и интегральной характеристике APDEX см. главу «Теория», разделы 3.1 и 3.2. Если важная проблема возникает вследствие реакции системы, не позволяющей продолжить выполнение действия (единичной или некоторого количества за период), такую реакцию системы называют критичной ошибкой. То есть, говоря наоборот: критичная ошибка – это операция (действие) системы, у которой количественной характеристикой, определяющей наступление нежелательного состояния, является фактическое количество таких действий за период, и наступление этого нежелательного состояния является важной проблемой. О критичных ошибках подробнее см. главу «Теория», раздел 3.3. Все проблемы таким образом оказываются поделенными на два класса, и обычно в договорах по повышению технологического качества информационных систем «1С» их выделяют как: ■■ ■■ коэффициент производительности: значение показателя APDEX, являющееся сверткой времени выполнения ключевых операций; количество критичных ошибок, обычно за какой-то период, к которым относят: □□ ошибки блокировок; □□ системные ошибки; □□ ошибки защиты; □□ падение кластера серверов «1С:Предприятия»; □□ зависание кластера серверов «1С:Предприятия». Основной подход к решению проблем 15 Надо отметить, что часть критичных ошибок в проектной документации на создание центров обработки данных и в других похожих задачах интерпретируется как устойчивость системы, а также как процент доступности системы. Что это и как осуществляется расчет таких показателей, см. главу «Теория», раздел 3.4. Также следует обратить внимание на то, что при работах по оптимизации системы и при работах по повышению технологического качества системы не уделяется внимания несистемным, функциональным и прикладным ошибкам, в т. ч.: синтаксическим ошибкам кода; ■■ неправильной, с точки зрения пользователя, реакции системы без сообщения об ошибке (при нажатии кнопки не заполняется табличная часть); ■■ неправильным расчетам (НДС считает 17 % вместо 18 %) и т. п. Связано это с тем, что такие ошибки относятся к другим областям знаний и обычно требуют от сотрудника несколько (а иногда и существенно) иных знаний и умений, чем те, которые предъявляются к 1С:Экспертам по технологическим вопросам. ■■ В итоге в договор должен попасть список ключевых операций и критичных ошибок, формально определяющий пространство состояний системы. Критерий включения в список – важность возникающей проблемы и ее практическая значимость. По каждому из компонентов списка должно быть указано целевое состояние, в которое надо привести этот компонент: приемлемая стабильность, ■■ целевое значение APDEX для каждой из ключевых операций. В совокупности это даст целевое состояние всей системы. ■■ Существует опасность задать слишком большой список ключевых операций. Это может привести к следующему: обычное время решения одной проблемы – дня три; 20 проблем = 60 рабочих дней – это 3 месяца. С учетом того, что при работах по оптимизации существует необходимость устанавливать мораторий на внесение изменений в определенную область конфигурации (а если операций много, то на всю конфигурацию), устранение даже 20 проблем потребует трехмесячного моратория на доработки функционала. В реальности даже такой срок предоставить никто не может, не говоря уже о большем. Поэтому список ключевых операций надо ограничивать, и совершенно точно нет смысла включать в него свыше 20 позиций. Впоследствии (после завершения оптимизации этих 20 операций) можно будет составить новый список из следующих по приоритету операций. Целевое состояние, которое мы описанным выше образом формализовали, определяет требования к производительности, доступности и работоспособности системы, которым она должна удовлетворять либо в ее нынешнем состоянии, либо с учетом ее планируемых изменений. 16 Настольная книга 1С:Эксперта по технологическим вопросам 2.2. Как измерять, как получать цифры Как отмечалось в предыдущем разделе, работы по оптимизации производительности или повышению технологического качества работы системы могут быть инициированы: на работающей системе; ■■ на перспективной системе, к которой можно отнести как проектируемую систему, так и существующую систему, для которой запланированы изменения. В обоих случаях методика замеров одинакова. Замерять надо: ■■ время выполнения ключевых операций с указанием, что за операция выполнялась; ■■ количество критичных ошибок в разрезе того, что это за ошибки: □□ ошибки блокировок; □□ системные ошибки; □□ ошибки защиты; □□ падение кластера серверов «1С:Предприятия»; □□ зависание кластера серверов «1С:Предприятия». Удобным способом получения длительности выполнения ключевых операций и их интегральных оценок по шкале APDEX является встраивание подсистемы «Оценка производительности» из состава Библиотеки стандартных подсистем «1С». Как ее встроить, см. главу «Инструкции», раздел 4.7. ■■ Ошибки блокировок, системные ошибки и ошибки защиты можно считать по технологическому журналу. Как организовать сбор технологического журнала и его анализ, см. главу «Инструкции», разделы 4.5 и 4.6. Этот алгоритм планируется встраивать в Центр контроля качества (ЦКК). Аварийные завершения процессов кластера серверов «1С:Предприятия» можно считать по дампам, образующимся при падении процессов при включенной специальной настройке. Общий подход – см. главу «Инструкции», раздел 4.9. Рекомендуется, однако, использовать ЦКК, в него уже встроены подсчет дампов и их группировка по офсетам. Зависание кластера серверов «1С:Предприятия» нужно отслеживать с помощью ЦКК. Вручную факт зависания можно отследить только непосредственно наблюдая его симптомы (процессы кластера находятся в памяти, но ни на какие запросы пользователей кластер не отвечает и новые клиентские соединения создавать не дает). Понятно, что такой метод ни полноты картины, ни удобства не обеспечивает. Если речь идет о комплексе с одной базой, то всю собранную статистику можно объединять вручную. Однако если речь идет о комплексе с большим количеством баз и с интенсивным потоком событий, ручное формирование сводной статистики может превратиться в трудоемкую операцию, и в таком случае существенное облегчение может быть получено за счет использования ЦКК для автоматизации сбора всей статистики. О принципах работы ЦКК см. главу «Инструкции», разделы 4.10 и 4.11. Основной подход к решению проблем 17 В случае перспективной системы вместо построения теоретических умозаключений будет значительно эффективнее согласовать и создать модель базы, которая должна получиться в первые месяцы работы системы. Затем на оборудовании заказчика или на арендованном оборудовании в этой базе нужно запустить нагрузочный тест с учетом прогнозируемой интенсивности ввода документов, после чего посмотреть на результаты и сделать выводы. О том, как организуются нагрузочные тесты, см. главу «Инструкции», раздел 4.21. Для получения статистики перспективной системы применяется тот же состав замеров и методика их организации, что и для работающей системы. При этом надо понимать, что если нагрузочный тест не проведен заранее силами роботов, то это же нагрузочное тестирование все равно пойдет в первые же дни эксплуатации созданной (или измененной) системы. Только это тестирование пойдет уже на живых пользователях в ходе реальной работы, и еще неизвестно, какое из тестирований по факту обойдется дороже. Если все же принято решение о нагрузочном тестировании на людях, это также не меняет ни состава, ни методики организации замеров. Данные, полученные в ходе измерений, как показатели APDEX, так и количество критичных ошибок, надо сравнить с целевыми требованиями и переходить к решению проблем. По падениям и непонятным ошибкам, оцененным как критичные, необходимо обращаться в фирму «1С»: либо в техподдержку, либо через участие в проекте ЦКТП. По задачам оптимизации ключевых операций последовательность действий определяется как движение по «незеленым» строчкам в списке полученных показателей APDEX, начиная с операции, имеющей наивысший приоритет. 2.3. Как устроена система Действие пользователя, предусматривающее чтение данных из базы или запись их в базу, вызывает некоторую последовательность команд. Эти команды и связанные с ними данные должны пройти приблизительно следующий маршрут, сначала в прямом направлении, а затем в обратном: ■■ ■■ ■■ клиент: □□ код на языке «1С», выполняющийся на клиенте, □□ платформа «1С:Предприятие» (клиентское приложение), □□ ОС, □□ оборудование, сеть, сервер «1С»: □□ код на языке «1С», выполняющийся на сервере, □□ платформа «1С:Предприятие» (серверные процессы), □□ ОС и софт виртуальной машины (если есть), □□ ОС физической машины, □□ оборудование, 18 Настольная книга 1С:Эксперта по технологическим вопросам сеть, ■■ сервер СУБД: □□ сами запросы, □□ СУБД, □□ ОС и софт виртуальной машины (если есть), □□ ОС физической машины, □□ оборудование. По приведенной выше схеме видно, что система является многоуровневой, и в расходах времени на операцию принимают участие все накладные расходы на всех уровнях, в обе стороны. ■■ Чтобы понять, о чем речь, можно сопоставить такой схеме схему поездки в сетевой гипермаркет. Причем нет особой разницы: идет чтение или идет запись – и то, и другое одинаково описывается с помощью такого сопоставления. Туда: дом: □□ найти ключи, □□ лифт, ■■ дорога: □□ дойти до автомобиля, □□ автомобиль (дорога туда), ■■ магазин: □□ найти тележку, □□ траволатор, □□ стеллажи, □□ касса. Обратно: ■■ магазин: □□ траволатор, □□ погрузить сумки в автомобиль, ■■ дорога: □□ автомобиль (дорога обратно), □□ донести сумки до лифта, возможно, за несколько заходов, ■■ дом: □□ лифт, □□ отпереть дверь, зайти домой. Такая схема годится, потому что и организация движения, и организация розничной торговли, и система на платформе «1С:Предприятие» по своей сущности являются системами массового обслуживания. Для простоты будем считать, что все автомо■■ Основной подход к решению проблем 19 били, которые едут по дороге, едут либо в этот магазин, либо из него, и таким образом снимем необходимость других допущений. Рассмотрение систем на платформе «1С:Предприятие» с помощью аппарата теории массового обслуживания еще ждет своего исследователя. Одним из практических аспектов такого исследования могла бы стать замена нагрузочных тестов для некоторых целей имитационным моделированием (нагрузочный тест хотя и проводится с помощью средств вычислительной техники, представляет собой все-таки натурный эксперимент, хотя и с заменой живых пользователей «роботами»). Как отмечалось ранее, на каждом из уровней системы существуют определенные накладные расходы на выполнение команд (действий, требований). Совокупность этих расходов определяет суммарное время выполнения операции. Расходы, происходящие на каждом из уровней, определяются: 1. Собственно свойствами уровня (более скоростной автомобиль может доехать до магазина быстрее). 2. Свойствами выполняемых действий (от количества товаров в тележке зависит время обслуживания на кассе). 3. Потерями времени на ожидание (очередь в кассу и пробка на дороге сводят на нет весь выигрыш времени, полученный от использования скоростного автомобиля и небольшого количества покупок). Первые два фактора приводят к проблемам, называемым проблемами производительности. Эти проблемы возникают, даже если система в указанный момент времени обслуживает только одну операцию. Третий фактор приводит к проблемам, называемым проблемами параллельности. Эти проблемы возникают только тогда, когда в системе одновременно выполняется более одной операции. Существует характерная особенность систем, в которых есть проблемы параллельности. Она заключается в том, что в условиях установившегося входного потока пропускная способность системы определяется пропускной способностью ее самого медленного уровня. Такой уровень называется «узким местом» или «бутылочным горлышком» (bottle neck). В рассматриваемом классе систем (у всех действий единая точка входа, например, все автомобили, которые едут по дороге, едут либо в этот магазин, либо из него) это «бутылочное горлышко» всегда одно. Так же, как на дороге, на уровнях, находящихся после этого «бутылочного горлышка», всегда будет иметь место характерный спад загрузки: если покупатели толпятся в овощном отделе, на кассах будет свободно; если в системе выстроилась очередь из блокировок, оборудование сервера СУБД будет простаивать. 20 Настольная книга 1С:Эксперта по технологическим вопросам 2.4. Бизнес-процесс решения проблем по ключевым операциям Выше рассматривалась схема взаимодействия с заказчиком. Подводя итог написанному выше, ее можно представить так: 1. Получить список жалоб. 2. По списку жалоб составить список ключевых операций (ограниченное количество). 3. По списку ключевых операций совместно с заказчиком назначить целевое время и приоритеты. 4. Пока идет согласование по п. 3 (это не всегда быстро), можно подключить и настроить ЦУП, но он не понадобится до этапа 8. 5. По списку ключевых операций встроить замеры в базу, получить результаты. 6. Сравнить результаты с целевым временем. Операции с плохим фактическим временем относительно целевого (с плохим APDEX) следует начинать разбирать в порядке убывания приоритета. 7. По каждой операции найти наиболее типичное действие (по гистограмме найти интервал времени, в который попало наибольшее количество замеров). 8. Для этого действия провести анализ, выяснить, что это за действие (как – описано в этом разделе ниже). 9. Понять, с какой проблемой имеем дело, что придется делать, и оценить трудоемкость решения. 10. Оформить результаты по п. 7 и 8 в виде отчета, согласовать с заказчиком дальнейшие действия. 11. Воплотить рекомендации в жизнь, сравнить результаты с целевым временем. Теперь более подробно рассмотрим алгоритм анализа (п. 7, 8) и оценки трудоемкости (п. 9) из списка выше. На рис. 2.4.1 приведена схема бизнес-процесса решения проблем по ключевым операциям. Ключевым пунктом схемы является вопрос: имеем мы дело с проблемой производительности или проблемой параллельности. Основной подход к решению проблем Рис. 2.4.1. Схема бизнес-процесса решения проблем по ключевым операциям 21 22 Настольная книга 1С:Эксперта по технологическим вопросам Чтобы подготовить ответ на этот вопрос, нужно найти наиболее типичного представителя действий, выполненных по ключевой операции, для которой требуется улучшать APDEX, и в нерабочее время его выполнить. Дело в том, что если для этой же операции ориентироваться на наихудших представителей, список причин, вызывающих проблемы, может оказаться другим. Чтобы этого наиболее типичного представителя найти, для ключевой операции, по которой требуется улучшать APDEX, нужно: по данным замеров построить гистограмму2 распределения частот попаданий значений времени в интервалы (количество и границы интервалов определяются сообразно фактическим данным), написание программного кода построения такой гистограммы трудностей вызвать не должно; ■■ определить интервал, в который частота попадания максимальна; ■■ подобрать действие3 по этой ключевой операции, длительность выполнения которого по данным замеров соответствует этому интервалу. Выполнив именно это действие (например, проведя этот же документ) в тех же самых условиях, под тем же самым пользователем, но в нерабочее время, и сопоставив время выполнения этого действия с исходным временем, мы сразу сможем установить: происходили ли при выполнении этого же действия в рабочее время ожидания в очередях. Если они были, то время выполнения в нерабочее время будет гораздо меньше, чем в рабочее, и мы имеем дело с проблемой параллельности. Если же время выполнения осталось примерно то же самое, то мы имеем дело с проблемой производительности. ■■ Чтобы было понятнее, можно вернуться к аналогии с автомобилем и гипермаркетом. Едем на той же машине в тот же магазин, но ночью. Если приехали намного быстрее, чем днем, то днем была пробка, следовательно, нужно устранять ее причины (строить развязку). Если приехали примерно за то же время, то мы ездим на «запорожце» – нужно менять его на «порше». Определив, с какой проблемой имеем дело, можно четко установить план дальнейших действий. Сначала рассмотрим, что делать с проблемой производительности. У проблем производительности есть два обычных подозреваемых: ■■ ■■ 2 3 плохая работа запроса, плохая работа кода. В текущей версии подсистемы ОП гистограмма строится автоматически. При использовании подсистемы «Оценка производительности», если ключевая операция связана с транзакцией, это можно точно определить имеющимися средствами. Регистр сведений «Замеры времени» содержит реквизит «Имя пользователя» и данные о времени начала замера. Нужно найти по журналу регистрации, что пользователь в это время делал, и в нем по полю «Представление данных» определить, например, что это был за документ (номер и дату). Если ключевая операция с транзакцией не связана (например, ключевая операция – это выполнение отчета или открытие формы), обычно просто достаточно знать, под каким пользователем это действие выполнялось. Но если этого недостаточно, надо вместе с началом замера вносить в журнал регистрации данные, необходимые для понимания особенностей выполняемой операции. Основной подход к решению проблем 23 Прочие подозреваемые описаны в главе «Методики», разделы 5.2–5.5. Методики их поимки, см., например, «Инструкции», раздел 4.22 и «Методики», раздел 5.6. Обоих обычных подозреваемых надо проверить. Плохая работа запроса для СУБД MS SQL проверяется так: включив профайлер SQL Server, выполняем ключевую операцию еще раз и собираем длительности всех запросов, выполнявшихся во время его работы (показатель duration). Инструкцию, как это сделать и как получить их сумму, см. в главе «Инструкции», раздел 4.13. Если сумма duration близка ко времени выполнения всей операции, можно однозначно делать вывод, что потери времени происходят в СУБД. Дальнейшее исправление состоит в определении неоптимальностей и их устранении (см., например, главу «Инструкции» раздел 4.20). Для измерения длительности запроса в других СУБД (не MS SQL Server) рекомендуется использовать технологический журнал «1С». Плохая работа кода проверяется так: включив замер на отладчике (см. главу «Инструкции», раздел 4.7), выполняем действие еще раз (отладка на сервере должна быть включена). Получаем таблицу, содержащую строки кода, количество их выполнений и время выполнения (как абсолютное, так и в процентном отношении к общему). Следует учесть, что замер отладчиком показывает именно работу кода конфигурации, а не общее время операции, включающее в себя также и платформенные вызовы. Первое, на что надо смотреть, сколько раз выполнялись строки кода, входящие в топ по времени выполнения. Если эти строки содержат запросы к базе через объектную модель или на языке запросов и эти строки выполнялись много раз, то эти участки кода надо иметь в виду как приоритетные для исправления: запрос в цикле – это способ программирования, который всегда дает проигрыш во времени выполнения кода. Второе, на что надо смотреть, есть ли строки кода, выполнение которых заняло существенную часть от общего времени. Это позволяет оценить шансы в борьбе за повышение производительности. Если такие строки есть, то шансы можно оценивать как очень хорошие. Если же таких строк нет и, например, на первом месте находится строка, выполнение которой занимает 3–5 % от общего времени, то понятно, что уменьшение времени выполнения этой строки даже до нуля даст прирост в те же самые 3–5 %. Поскольку речь может идти о том, чтобы ускорить выполнение операций в разы, шансы на это будут совершенно призрачны. Далее надо оценить и согласовать трудозатраты, требующиеся на решение проблемы. Основанием для оценок трудоемкости решения проблемы будут служить полученные сведения. Если проблема находится в СУБД или есть строки кода, имеющие высокую относительную длительность выполнения, то, как правило, проблема может быть решена техническими средствами и решена довольно быстро: пары часов обычно хватает, чтобы с ней разобраться. Как и что можно исправить, см. главу «Инструкции», раздел 4.20 и главу «Методики и дополнительная информация», разделы 5.2 и 5.5. 24 Настольная книга 1С:Эксперта по технологическим вопросам Если же все строки кода имеют малую относительную длительность, а строк много, то длительность работ серьезно возрастает: только на то, чтобы провести анализ ситуации, может уйти день работы. По итогам анализа может быть установлено, что проблема не имеет технического решения, и потребуются сложные методические или даже административные решения, с пересмотром основ конфигурации, с вовлечением в процесс программистов-разработчиков, методистов и заказчиков. Для решения проблем параллельности, как указывалось ранее, всегда надо найти «бутылочное горлышко». Однако надо понимать, что за одним «горлышком» может быть целый каскад следующих «горлышек», и, вообще говоря, количество уровней может быть непредсказуемым. Поэтому, встретившись с проблемами параллельности, оценку трудозатрат надо давать с учетом этой особенности таких задач. Обычные подозреваемые: избыточная блокировка данных в «1С» или в СУБД. Подробности по блокировкам см. в главе «Теория», разделы 3.6–3.10; ■■ не справляется оборудование. Как организовать замер загрузки оборудования и интерпретировать значения, см. в главе «Инструкции», раздел 4.1. Может, однако, случиться и такое, что сработает критическая секция (участок кода, который одновременно может выполняться только в одном месте), например: ■■ автонумератор, драйвер HASP-ключа и др. Такая проблема классифицируется как неподконтрольная проблема. В таких ситуациях, с одной стороны, нет никаких средств диагностики, с другой – видно, что это проблема параллельности. При обнаружении такой проблемы неизбежным и правильным вариантом решения является обращение за помощью в ЦКТП. ■■ ■■ В заключение надо сказать, что и в ходе работ по решению проблем производительности, и в ходе работ по решению проблем параллельности вам могут встретиться задачи, для решения которых не хватит средств диагностики и опыта. В случае необходимости применения методических или административных способов решения проблем вам может не хватить авторитета. В случае работы над проектом, который выполняет ваша же компания, у вас может не быть возможности для независимой оценки, либо заказчик может не верить в то, что ваша оценка независима. В случаях работы в рискованных финансовых или технических условиях вам может не хватить уверенности из-за отсутствия страховки. Во всех этих случаях обращение в ЦКТП является правильным и может обеспечить успех проекта, а иногда и просто его спасти. ГЛАВА 3 Теория 3.1. Ключевые операции Ключевая операция (КО) – это операция (действие) системы, у которой количественной характеристикой, определяющей наступление нежелательного состояния, является время выполнения этой операции, и наступление этого нежелательного состояния является важной проблемой. На практике под ключевой операцией понимают действия системы после однократного нажатия пользователем какой-либо кнопки на форме или выбора пункта меню. С единственной оговоркой4 можно утверждать следующее: ключевая операция всегда начинается на клиенте; ■■ ключевая операция не может состоять из нескольких интерактивных действий пользователя, потому что мы оптимизируем только систему, а не работу пользователей; ■■ ключевая операция всегда заканчивается на клиенте. То есть мы не можем разбить на несколько КО действие, которое является единым с точки зрения пользователя. В этом нет смысла, т. к. требования к частям операции не могут быть определены (пользователю все равно). Обычно нежелательность состояния рассматривается с точки зрения пользователя: проблема – это симптом, который видит пользователь, и в данном случае это недостаточно быстрое выполнение системой какой-либо важной для него операции. ■■ 4 Оговорка заключается в том, что при проведении нагрузочных тестов в качестве ключевых операций может выступать как раз время выполнения действий на сервере, потому что организовать это проще и дешевле. Это имеет право на существование, если достоверно установлено, что вызов кода обработкой с сервера, а не имитацией выполнения действия на клиенте, не исказит результатов. Например, вам надо удостовериться, что с точки зрения решаемой задачи допустимо вместо нажатия кнопки ОК на форме использовать вызов ДокументОбъект.Записать(...) сразу с сервера. 26 Настольная книга 1С:Эксперта по технологическим вопросам Перед началом выполнения работ по оптимизации список ключевых операций должен быть составлен и зафиксирован. Размер списка не должен быть большим: разбор даже несложных проблем по каждой ключевой операции требует времени, и работы по списку из 20 операций точно займут не менее двух-трех месяцев. Каждой ключевой операции должно быть назначено (пользователем) целевое время Т, а также приоритет. Целевое время – это время, за которое, с точки зрения пользователя, всегда должна выполняться ключевая операция, чтобы он считал работу системы отличной. Пользователь имеет право выразить завышенные ожидания, и тогда его надо письменно предупредить, что, возможно, вы вернетесь к этому разговору (см. рис. 3.1.1). Приоритет обычно определяется исходя из того, насколько проблема, вызываемая недостаточно быстрым выполнением действий системы, важна для пользователя. На практике при такой формулировке пользователь говорит: «Мне все проблемы важны одинаково» – и ставит всем одинаковый приоритет (как вариант выделяет несколько групп с разными приоритетами). На самом деле приоритет – это то, в каком порядке вы будете заниматься решением проблем пользователя. Поэтому заказчику так и надо сказать: «Оптимизацией будет заниматься один человек (это наиболее распространенный случай), поэтому он все равно будет решать задачи не параллельно, а последовательно. Пожалуйста, укажите, в каком порядке ему заниматься решением задач, если по итогам замеров окажется, что по всем операциям производительность недостаточно хороша». В договоре обычно указывается следующее (см. рис. 3.1.1): Перечень ключевых операций (нужно заполнить список вместе с клиентом) Ключевая операция Приоритет Целевое время Т (сек.) Перечень ключевых операций является предварительным и может быть изменен по взаимному согласию сторон. Целевое время, указанное для каждой ключевой операции, также может уточняться в процессе выполнения работ по договору при наличии объективных причин, например, при несовпадении субъективной оценки пользователей и оценки APDEX. Рис. 3.1.1. Список ключевых операций и дополнительные пояснения к ним, обычно включаемые в договор После согласования списка ключевых операций замеры времени надо встроить в конфигурацию. Удобный способ это сделать – использовать подсистему «Оценка производительности» из состава Библиотеки стандартных подсистем «1С». Описание см. в главе «Инструкции», раздел 4.7. Теория 27 3.2. Методика APDEX Когда ключевая операция выполняется много раз, имеет смысл как-то сворачивать в число совокупность всех значений (получать интегральную характеристику) времени ее выполнения. И глядя с противоположной стороны, собранные замеры всегда имеет смысл рассматривать на достаточно большой выборке – не менее 100 замеров. Агрегировать можно по-разному: максимум, минимум, среднее, сумма, взвешенная сумма, методы математической статистики, методика APDEX. Не очень важно, как именно вы агрегируете или сворачиваете показатели. Важно, чтобы ваш заказчик понимал, в чем эта свертка заключается и почему она корректна. Фирма «1С» считает, что удобной и корректной является методика APDEX. Эта методика используется в составе подсистемы «Оценка производительности» из Библиотеки стандартных подсистем. Подробную информацию об этой методике можно найти в Интернете (на английском языке): http://apdex.org/index.html, http://en.wikipedia.org/wiki/Apdex. Смысл методики таков: если какое-то действие должно выполниться за T секунд и оно выполняется за эти T секунд или быстрее, оно считается успешно выполненным. Если оно выполняется несколько дольше – от Т до 4Т, оно считается наполовину успешным. Если оно выполняется очень долго – свыше 4Т, оно считается неуспешным. Если действия выполнялись неоднократно (N раз), далее достаточно подсчитать успешно выполненные действия (пусть их будет NS), подсчитать наполовину успешные (пусть их будет NT). Число (NS + NT /2) / N показывает отношение успешных и наполовину успешных действий к общему количеству действий. Что такое Т и 4Т, с точки зрения пользователя: Т – это время, которое пользователя полностью удовлетворяет; 4Т – это время, которое пользователя не удовлетворяет, но он дождался получения результата; ■■ больше 4Т – пользователь не дождался получения результата, то есть операция вообще не выполнена. В таблице 3.2.1 показано, какие качественные значения соответствуют количественным значениям показателей APDEX. ■■ ■■ Таблица 3.2.1. Соответствие качественных оценок значениям APDEX Шкала APDEX 0.00 0.50 0.70 0.85 0.94 Значение от до 0.50 0.70 0.85 0.94 1.00 Оценка неприемлемо очень плохо плохо (в некоторых интерпретациях – удовлетворительно) хорошо отлично 28 Настольная книга 1С:Эксперта по технологическим вопросам В случае 100-кратного выполнения5 действия на практике это выглядит так, как показано в таблице 3.2.2. Таблица 3.2.2. Примеры комбинаций N, NS и NT для 100-кратного выполнения действия и соответствующие им оценки APDEX (показаны комбинации для нижней границы диапазона, соответствующего оценке) (NS + NT /2) / N 0,94 – 1 0,94 – 1 0,85 – 0,93 0,85 – 0,93 0,70 – 0,84 0,70 – 0,84 0,50 – 0,69 0,50 – 0,69 0,00 – 0,49 Оценка отлично отлично хорошо хорошо плохо плохо очень плохо очень плохо неприемлемо NS (успешных) NT (наполовину успешных) N – NS – NT (не уложившихся в 4Т) 94 0 6 88 12 0 85 0 15 70 30 0 70 0 30 40 60 0 50 0 50 0 100 0 Все, что еще хуже, чем две предыдущие строки Заказчики не сразу принимают такую схему, но для массовых замеров она действительно хороша, так как учитывает не двоичную логику результата (уложились/ не уложились), а более сложную (уложились полностью/уложились в рамках допустимого/не уложились). Соответствие качественной оценки «хорошо» значению показателя 0,85 и выше – это для бизнеса, т. к. решаются его задачи. При этом некоторые операции выполняются долго или не выполняются вообще (пользователи «страдают»6). Но, поскольку может оказаться дешевле оплачивать «страдания» пользователей, чем оптимизировать систему до 1,00, это приемлемо с точки зрения бизнеса. Повторим еще раз: можно использовать любой подходящий для вашей ситуации способ свертки7, лишь бы у вас с заказчиком по этому поводу было единое мнение. Если вы идете по пути встраивания подсистемы «Оценка производительности» из Библиотеки стандартных подсистем, то по сырым данным регистра сведений «Замеры времени» вы можете самостоятельно построить любую подходящую функцию, позволяющую яснее представить результат себе и заказчику. Свертка по методике APDEX в этой подсистеме, однако, уже реализована, и это еще один хороший повод пользоваться именно ей. 5 6 7 Как говорилось выше, для получения необходимой точности нужно не менее 100 замеров. Если речь идет не о частых, а о редких или даже единичных событиях большой длительности (например, о выполнении каких-то регламентных операций), то описанный подход не годится: очень велика становится разница, выполняется операция, скажем, 2 часа или же 8. Если такая ключевая операция находится в числе прочих (коротких и частых), то надо смотреть по ситуации, что с ней делать. Можно считать для нее APDEX просто для сохранения единого подхода к замерам, соответственно подобрав целевое время, но можно сразу выделять ее в отдельную задачу, с результатом в виде достижения обозначенного времени выполнения. Почему «страдания» заключено в кавычки, и что страдает на самом деле, см. раздел 6.1. Но только не в том случае, если вы работаете с «1С» по проекту ЦКТП – тогда использование именно методики APDEX будет обязательным. Теория 29 Существует обратная задача – получить целевое время по заданному значению APDEX, если заказчик затрудняется это целевое время назвать. На практике, правда, в такой постановке эта задача встречается редко: список ключевых операций согласовывается до встраивания замеров в базу, а предлагаемая методика основывается на том, что замеры в базу уже встроены. Более вероятен вариант – использовать этот подход при необходимости переназначения и повторного согласования целевого времени, изначально заданного чересчур жестко. Задачу необязательно решать вручную. В подсистему ОП встроен механизм автоматического подбора времени Т под заданное значение APDEX. Если же требуется все-таки ручное решение, то порядок действий должен быть таким: 1. Получить у заинтересованных пользователей субъективную оценку производительности этой операции в терминах APDEX: Неприемлемо, Очень плохо, Плохо, Хорошо, Отлично. Установить значение APDEX, равное середине диапазона: соответственно, 0,25, 0,6, 0,775, 0,9, 0,95. 2. Собрать информацию – сколько на самом деле выполняется эта операция в системе. 3. Подобрать такое значение T, чтобы APDEX, рассчитанный для него, был примерно равен значению, назначенному в п. 1. В случае использования подсистемы «Оценка производительности» из БСП это можно делать непосредственно в режиме исполнения. 4. Проверить правильность полученного значения Т, если подбор осуществлялся каким-то другим способом. 5. Продолжать получать значение APDEX для данной операции, исходя из нового времени Т, убедиться в том, что получаемая оценка APDEX соответствует субъективной оценке заказчика (в том числе если имело место переназначение и повторное согласование целевого времени). 3.3. Критичные ошибки К критичным ошибкам относятся: ■■ ■■ ■■ ■■ ■■ ошибки блокировок, системные ошибки, ошибки защиты, аварийные завершения процессов кластера серверов «1С:Предприятия», зависание процессов кластера серверов «1С:Предприятия». 30 Настольная книга 1С:Эксперта по технологическим вопросам Ошибки блокировок Ошибкой блокировки называется ошибка, возникающая при превышении времени ожидания на блокировке (lock request time out) или неразрешимый конфликт блокировок (взаимоблокировка – deadlock). Системные ошибки Системной ошибкой называется ошибка данных информационной базы или ошибка платформы, которая не позволяет пользователю выполнить какое-либо прикладное действие с системой. Любые функциональные ошибки кода конфигурации не являются системными ошибками. Аварийные завершения процессов кластера серверов «1С:Предприятия» Падением кластера серверов «1С:Предприятия» называется самопроизвольная выгрузка любого процесса кластера серверов «1С:Предприятия» или всех его процессов одновременно. Зависание процессов кластера серверов «1С:Предприятия» Зависанием кластера серверов «1С:Предприятия» называется состояние кластера, при котором он не отвечает на запросы пользователей, не позволяет создать новое клиентское подключение и т. п., но при этом остается загруженным в память рабочего сервера. 3.4. Расчет доступности системы Достаточно частым требованием при проектировании системы является обеспечение требуемого уровня доступности и самой системы, и служб ее обслуживания и поддержки. Здесь доступность информации – состояние информации, характеризуемое способностью информационной системы обеспечивать беспрепятственный доступ к информации субъектам, имеющим на это полномочия. В требованиях часто указывается режим работы 24х7. Такой режим функционирования закрепляется в документах, вводится в жизнь, а потом подвергается пересмотру, и иногда достаточно болезненно. Связано это с тем, что любые информационные системы, и системы на платформе «1С:Предприятие» тут не исключение, требуют проведения регламентных операций. Чем более ответственные задачи выполняет эта система, тем строже надо следить, чтобы эти операции выполнялись. Конечно, если есть необходимость, ничто не мешает построить систему с полным дублированием всех компонентов, которая будет спокойно работать 24х7. Это возможно, но это дорого и сложно, и созданием такого комплекса надо специально заниматься, сам собой он не возникнет. Список операций приведен в следующем разделе 3.5, а здесь скажем только, что часть операций требуется выполнять во время технологических окон, и работа других пользователей во время этих окон будет либо невозможна, либо сопряжена с некоторыми ограничениями. Теория 31 Поэтому, например, можно сразу заявить режимы функционирования контуров системы так, как представлено в таблице 3.4.1. Таблица 3.4.1. Штатные режимы функционирования контуров системы Серверы Гарантированное предоставление услуг Обслуживание и поддержка Серверы «1С» и СУБД в основном контуре 22х7* 8x5** Терминальные серверы, Web-сервер интеграции, сервер лицензий и другие серверы в основном контуре Серверы «1С» и СУБД в контуре разработки и (или) тестирования Терминальные серверы, Web-сервер интеграции, сервер лицензий и другие серверы в контуре разработки и (или) тестирования 22х7 8x5 22х7 8x5 22х7 8x5 *22x7 – ежедневно, круглосуточно, с плановым 2-часовым технологическим окном и 8-часовым ежеквартально (длительность технологических окон приведена для примера). **8x5 – по рабочим дням с 9:00 до 18:00, с перерывом с 14:00 до 15:00. Чтобы отделить сервисные режимы от сбоев, можно указать, что требуется обеспечить функционирование системы в следующих режимах: штатный режим (работа в течение 7 дней в неделю, 22 часа в сутки (22х7)); сервисный режим (для проведения обслуживания, реконфигурации и пополнения новыми компонентами) – плановое 2-часовое технологическое окно ежедневно; ■■ режим восстановления после сбоев. В штатном режиме работы система должна обеспечивать весь функциональный объем. ■■ ■■ Работа системы в сервисном режиме возможна в согласованное время (например, в ночное время, не более 2 часов в сутки, а также в дневное время, только в выходные или праздничные дни, не более 1 дня в месяц). В сервисном режиме работы допускается недоступность промышленных систем в связи: с проведением регламентных работ по обслуживанию информационных баз «1С»; ■■ проведением периодических профилактических работ, затрагивающих аппаратную или программную часть системы; ■■ переносом запросов на изменение в продуктивную систему, влияющих на надежность и быстродействие системы; ■■ обновлением программной или аппаратной части. В режиме восстановления после сбоев система может оказаться полностью или частично недоступна на период резервного копирования и восстановления в соответствии с установленными в данной организации требованиями к надежности (см. таб. 3.4.2). ■■ Процент доступности, приведенный в таблице, рассчитывается как отношение количества минимально допустимого фактического времени работы системы только 32 Настольная книга 1С:Эксперта по технологическим вопросам в штатном режиме за период (например, количество часов за квартал) к общему количеству часов за период. Например, указанный в таблице 3.4.2 процент доступности 91,3 % рассчитывается так: В году 365 х 24 = 8760 часов. Сервисный режим: 2 часа в день + 8 часов в квартал. 2 х 365 + 8 х 4 = 762 часа. Потери времени на режим восстановления после сбоев идут за счет сервисного режима. Превышение не допускается. (8760 - 762) / 8760 = 0,913; отсюда 91,3 %. Обеспечение надежности функционирования системы обычно производится: ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ дублированием элементов серверного, коммутационного оборудования системы и при необходимости каналов передачи данных; применением устройств бесперебойного электроснабжения серверов и коммутационного оборудования системы; регулярным проведением регламентных профилактических работ по обслуживанию технических средств; регулярным проведением регламентных работ по обслуживанию информационных баз «1С»; соблюдением технических требований эксплуатации элементов программно-технических средств, обеспечивающих их бесперебойное функционирование; применением организационных и технических мер защиты системы от несанкционированного доступа; применением средств антивирусной защиты и их регулярным обновлением; периодическим резервным копированием информации системы; привлечением к обслуживанию системы высококвалифицированных специалистов и повышением квалификации штатного обслуживающего персонала системы. Терминальные серверы, Web-сервер интеграции, сервер лицензий и другие серверы в контуре разработки и (или) тестирования Непрерывная, 24х7 – для 97,8 % аппаратного обеспечения и системного программного обеспечения, 22х7 – доступность содержимого базы данных 16 16 93,4 % – недоступность не чаще 2 дней в месяц 84,7 % 8 Непрерывная, 24х7 – для 97,8 % аппаратного обеспечения и системного программного обеспечения Терминальные серверы, Web-сервер интеграции, сервер лицензий и другие серверы в зоне основного контура Разработка и (или) тестирование 8 Непрерывная, 24х7 – для 91,3 % аппаратного обеспечения и системного программного обеспечения, 22х7 – доступность содержимого базы данных Общая доступность системы Основной Контур 24 24 Ежедневные регламентные работы (указать время проведения) Ежедневные регламентные работы (указать время проведения) 2 1 раз в квартал Еженедельные регламентные работы (указать день недели и время проведения) 8 3 2 1 раз в квартал Еженедельные регламентные работы (указать день недели и время проведения) 8 3 1 раз в квартал Ежедневные регламентные работы (указать время проведения) 1 раз в квартал Периодичность Перерывы на обслуживание и поддержку Длительность, раб. часов При необходи8 мости восстановления с резервной копии – начало текущего рабочего дня, 2 при необходимости отката базы – 1 час 24 8 Восстановление после сбоя Доступность предоставляемых услуг, с учетом Целевое время Целевая точка сервисного восстановления восстановления режима (RTO), раб. (RPO), часов часов Таблица 3.4.2. Пример параметров надежности системы Теория 33 34 Настольная книга 1С:Эксперта по технологическим вопросам 3.5. Регламентные работы Для обеспечения устойчивой работы требуется проведение регламентных мероприятий (см. таблицу 3.5.1). Для проведения регламентных мероприятий с частотой «ежедневно» (исключая резервное копирование) должно быть выделено ежедневное технологическое окно. Длительность технологического окна зависит от особенностей системы. Более подробный регламент должен быть разработан дополнительно. В нем должны быть указаны ответственные (должности, функциональные роли или фамилии), способ отчетности (по эл. почте, вручную по журналам, через SMS), способ выполнения (автоматизированно, через ЦКК или вручную). При составлении регламента надо иметь в виду, что для некоторых регламентных операций время их выполнения и требующиеся для их выполнения ресурсы зависят от того, насколько редко эти операции делают. Это относится и к операциям из этого списка (например, обновление статистик), и к не входящим в него, и даже к тем операциям, которые не относятся к обеспечению устойчивости системы (обмены, восстановление последовательностей). Поэтому если какая-то операция не успевает выполниться за отведенное время в период бездействия пользователей или за время технологического окна, есть смысл попробовать делать ее не реже, а, наоборот, чаще. Может случиться (и часто случается) так, что выполнение операции каждые 5–15 минут из-за малого объема данных проходит настолько быстро, что не успевает никому помешать так сильно, чтобы это заметили. Перезапуск рабочих процессов или агентов сервера «1С» Резервное копирование базы Контроль наличия свободного места на дисках Контроль устойчивости (образование дампов) Контроль доступности системы Контроль количества ошибок, в т. ч. ошибок блокировок, по технологическому журналу Контроль загруженности оборудования сервера приложений, сервера СУБД, терминальных серверов. Контролировать параметры: ○○ интенсивность обмена между дисковой подсистемой и оперативной памятью; ○○ использование выделенной памяти; ○○ загруженность процессоров; ○○ очередь к процессорам; ○○ очередь к дискам; ○○ скорость передачи данных через сеть Контроль времени выполнения ключевых операций Мероприятие Минимум ежедневно По отдельному регламенту Ежедневно. При использовании ЦКК контроль идет постоянно Постоянно Нет Да В том числе В том числе В том числе В том числе В том числе Ежедневно. При использовании ЦКК контроль идет постоянно Ежедневно. Планируется включить в ЦКК, станет возможным постоянный контроль Постоянно Выполнение во время технол. окна В том числе Частота Постоянно Таблица 3.5.1. Проведение регламентных мероприятий Ответственный См. Инструкции 4.1 Способ выполнения Возможен контроль и оповещения через ЦКК См. Инструкции 4.3 Возможен контроль и оповещения через ЦКК Возможен контроль и оповещения через ЦКК См. Инструкции 4.5 Возможно через ЦКК. Как только показатель производительности выходит из коридора, ЦКК сразу рассылает оповещения Отчетность Теория 35 Не реже 1 раза в квартал Ежемесячно. При использовании режима разделения итогов – ежедневно Ежедневно, также рекомендуется делать непосредственно после загрузок больших объемов данных Непосредственно после обновления статистики Режим «Тестирование и исправление базы» 10 9 8 См. Инструкции 4.4 См. Инструкции 4.4 Способ выполнения Да Отчетность См. Инструкции 4.4 Ответственный Да Ежедневное – да Нет Да Нет Выполнение во время технол. окна При использовании СУБД SQL Server. В целом эти рекомендации устарели. Ими можно пользоваться, но с оговорками: обновление статистик может не помочь исправить плохой план. Если обновление статистик помогает, то это указывает на то, что запрос многократно переусложнен. Нужно его радикально упрощать. При нормально (то есть просто) написанных запросах обновление статистик вообще не нужно – достаточно того, которое делает автоматически СУБД. Необязательно их выполнять во время технологического окна, хотя на практике это и удобнее. См. предыдущую сноску. ________________ Очистка процедурного кеша10 Обновление статистик8 Пересчет итогов Периодичность контроля – не реже 1 раза в месяц Ежедневно Частота Обрезание базы и журнала транзакций. Рекомендуется для файла журнала транзакций при значительных объемах неиспользуемого пространства в нем и нехватке места на диске Реиндексация базы8 Мероприятие 36 Настольная книга 1С:Эксперта по технологическим вопросам Теория 37 3.6. Транзакции. Уровни изоляции транзакций. Явные и неявные транзакции. Вложенные транзакции. Откат транзакций Транзакция вообще – это минимальная логически осмысленная операция, которая имеет смысл и может быть совершена только полностью. Транзакция в информатике – это группа логически объединенных последовательных операций по работе с данными, обрабатываемая или отменяемая целиком. То есть все изменения данных, вносимые транзакцией, должны быть либо зафиксированы (COMMIT), либо отменены (ROLLBACK). Свойства транзакции: неделимость (атомарность): □□ все или ничего, □□ должна или пройти, или не пройти полностью, ■■ изоляция: □□ действия других пользователей не должны повлиять на мои результаты. Когда речь идет об однопользовательском режиме, транзакция нужна для защиты от аппаратных сбоев. Но когда требуется обеспечить работу нескольких пользователей (прохождение нескольких транзакций) одновременно, появляются новые задачи. ■■ Например, в транзакции 1 выполняется следующий набор действий (проведение документа): 1. Проконтролировать остатки по регистру накопления 1. 2. Записать движения по регистру накопления 1. 3. Проконтролировать остатки по регистру накопления 2. 4. Записать движения по регистру накопления 2. В транзакции 2 выполняется точно такой же набор действий (проведение документа, для определенности будем считать, что такого же и с такими же данными), но начинается она, например, когда первая транзакция дошла до шага 3. В этом случае у системы должно быть некое правило, в соответствии с которым она определит дальнейший ход событий для транзакции 2. Система может, например: разрешить транзакции 2 выполнять все действия, не обращая внимания на транзакцию 1 (это, вообще говоря, совсем не транзакционный механизм); ■■ разрешить транзакции 2 выполнять чтение, не обращая внимания на транзакцию 1; ■■ не разрешить транзакции 2 выполнять никаких действий до окончания транзакции 1, поставив ее в очередь, поскольку речь идет об одних и тех же данных в регистре накопления 1. Уже из изложенного видно, что даже если разрешить транзакции 2 только чтение, то данные этого чтения могут оказаться неточными, потому что транзакция 1 может ■■ 38 Настольная книга 1С:Эксперта по технологическим вопросам быть отменена. Но параллельность работы при этом выше. И наоборот, только последовательный доступ к данным повышает точность и согласованность данных, но количество параллельно выполняемых транзакций может снижаться. К несогласованностям данных, которые следует принимать во внимание, относятся следующие: потерянное обновление (англ. lost update) – если один и тот же блок данных одновременно изменяют две разные транзакции, то будет зафиксировано только одно изменение, второе потеряется (при работе «1С» невозможно, поскольку в «1С» не бывает записи вне транзакции); ■■ «грязное» чтение (англ. dirty read) – чтение данных, добавленных или измененных транзакцией, может дать неточный результат, потому что та транзакция впоследствии не подтвердится (откатится); ■■ неповторяющееся чтение (англ. non-repeatable read) – при повторном чтении в рамках одной и той же транзакции оказывается, что ранее прочитанные данные изменены или удалены; ■■ фантомное чтение (англ. phantom reads) – при повторном чтении в рамках одной и той же транзакции оказывается, что прочитаны строки, которых при предыдущих чтениях не было (новые строки называют «фантомными»). То, насколько транзакции изолированы друг от друга (обратно – то, насколько в них допускаются несогласованные данные), называется уровнем изоляции транзакций. Уровни изоляции описаны с точки зрения того, какие из побочных эффектов параллелизма разрешены. ■■ Определяют следующие уровни изоляции (в порядке ее повышения): ■■ ■■ 11 Read Uncommitted (неподтвержденное чтение, изоляция незафиксированного чтения)11.8 Указывает, что запросы могут считывать строки, которые были изменены другими транзакциями, но еще не были зафиксированы. Допускается чтение незафиксированных изменений текущей транзакции (параллельными транзакциями) и незафиксированных изменений параллельных транзакций (нашей и другими транзакциями). Самый низкий уровень, при котором транзакции изолируются до такой степени, чтобы только уберечь от считывания физически поврежденных данных. Возможны «грязные», неповторяемые чтения и фантомы. Read Committed Snapshot (подтвержденное чтение с включенным параметром READ_COMMITTED_SNAPSHOT). Для СУБД MS SQL в «1С» поддерживается начиная с 8.3 (без режимов совместимости с 8.2). В СУБД ORACLE уровень с такими же свойствами используется «1С» и в версии 8.2. Уровень указывает, что запросы не могут считывать данные, которые были изменены другими транзакциями, но еще не были зафиксированы. В скобках – синонимы. Теория ■■ ■■ ■■ 39 В момент начала чтения транзакции будет выделен моментальный снимок (snapshot) базы данных, включающий в себя все изменения завершенных к этому моменту времени транзакций. Транзакция может читать этот снимок, получая чистые данные (без «грязного» чтения) и при этом никого не блокируя. «Грязные» чтения невозможны, возможны неповторяемые чтения и фантомы. Использование этого режима накладывает дополнительные требования по качеству кода (т. е. по качеству наложенных управляемых блокировок). Там, где раньше в транзакции при контроле остатков произошел бы таймаут на уровне СУБД, теперь будут просто прочитаны строки с предыдущими номерами, и, таким образом, не будут учтены изменения, вносимые транзакцией, начавшейся раньше нашей, но к моменту контроля остатков в нашей транзакции еще не завершившейся. Таким образом, могут возникнуть проблемы, которые будет очень сложно отловить. Read Committed (подтвержденное чтение, изоляция зафиксированного чтения). Это режим по умолчанию для уровня Read Committed (параметр READ_ COMMITTED_SNAPSHOT выключен). Как и уровень Read Committed Snapshot, указывает, что запросы не могут считывать данные, которые были изменены другими транзакциями, но еще не были зафиксированы. При выполнении операций чтения текущей транзакцией используются разделяемые блокировки для предотвращения изменения строк другими транзакциями (время освобождения в общем зависит от того, что блокируется – строка, страница или таблица, но достаточно понимать, что все освобождается после выполнения запроса) и для предотвращения от считывания строк, измененных другими транзакциями, пока они не завершатся. «Грязные» чтения невозможны, возможны неповторяемые чтения и фантомы. Repeatable Read (повторяемое чтение, изоляция повторяющегося чтения). Указывает на то, что другие транзакции не могут изменять данные, читаемые текущей транзакцией, до ее завершения. Как и предыдущий уровень, указывает, что запросы не могут считывать данные, которые были изменены другими транзакциями, но еще не были зафиксированы. Разделяемые блокировки применяются ко всем данным, считываемым любым запросом транзакции, и сохраняются до ее завершения. Это запрещает другим транзакциям изменять строки, считываемые текущей транзакцией. «Грязные» и неповторяемые чтения невозможны. Возможны фантомы. Snapshot (изоляция моментального снимка), отдельный уровень изоляции в SQL Server 2005. Дается для справки, в «1С» не поддерживается. Указывает на то, что данные, считанные любым запросом транзакции, будут согласованы на уровне транзакции с версией данных, существовавших в ее начале. Транзакция распознает только те изменения, которые были зафиксированы до ее начала (это отличие от Read Committed Snapshot). Запросы на чтение, 40 Настольная книга 1С:Эксперта по технологическим вопросам выполняемые текущей транзакцией, не видят изменений данных, произведенных другими транзакциями после запуска текущей транзакции. «Грязные» и неповторяемые чтения невозможны. Фантомы невозможны. ■■ Serializable (упорядоченный, изоляция упорядочиваемых транзакций, сериализуемый, упорядоченные транзакции, сериализуемые транзакции). Отличие от Repeatable Read в том, что другие транзакции не могут вставлять новые строки со значениями ключа, которые входят в диапазон ключей, считываемых запросами текущей транзакции, до ее завершения. Остальные ограничения сохраняются: другие транзакции не могут изменять данные, считываемые текущей транзакцией, до ее завершения, и запросы не могут считывать данные, которые были изменены другими транзакциями, но еще не были зафиксированы. Этот уровень изоляции идентичен ситуации, при которой транзакции выполняются строго последовательно, одна после другой. «Грязные» и неповторяемые чтения, а также фантомы невозможны. В таблице 3.6.1 показаны побочные эффекты параллелизма, допускаемые различными уровнями изоляции. Таблица 3.6.1. Побочные эффекты параллелизма, допускаемые различными уровнями изоляции Уровень изоляции Read Uncommitted Read Committed Snapshot Read Committed Repeatable Read Serializable «Грязное» чтение Да Нет Нет Нет Нет Неповторяющееся чтение Да Да Да Нет Нет Фантомное чтение Да Да Да Да Нет Уровень изоляции теоретически может устанавливаться как для всей СУБД, так и для одной транзакции и даже с определенными ограничениями (ограничений мало) изменяться в течение транзакции. 9 Однако при работе с информационными системами на платформе «1С:Предприятие» следует всегда понимать, что в случае, когда используются транзакции12, уровень изоляции регулируется только изменением режима управления блокировкой данных. Эти уровни устанавливаются средствами платформы «1С:Предприятие» в свойствах конфигурации для всей базы. Также для отдельной транзакции уровень можно установить в качестве параметра процедуры глобального контекста НачатьТранзакцию() – такая установка параметра имеет смысл, если для свойства конфигурации «Режим управления блокировкой данных» выбрано значение «Автоматический и Управляемый»13. Какие уровни для каких СУБД используются, показано в таб. 3.6.2.10 12 13 Как указывалось выше, записи вне транзакций в «1С» не бывает. Но читать вне транзакции можно, и таким образом получить «грязное» чтение. Использование этого режима вне переходного процесса с автоматического режима управления блокировками на управляемый режим является ошибкой. Растягивание этого переходного процесса на несколько месяцев (а тем более лет) также является ошибкой. Теория 41 Таблица 3.6.2. Блокировки СУБД, используемые в транзакции в зависимости от режима управления блокировкой данных, версии платформы и от СУБД Уровень изоляции транзакций Вид блокировки Для 8.2 Для 8.3 Автоматические блокировки Файловая БД Таблиц MS SQL Server Записей IBM DB2 Записей PostgreSQL Oracle Database Таблиц Таблиц Файловая БД Таблиц MS SQL Server 2000 Записей MS SQL Server 2005 и выше Записей IBM DB2 Записей PostgreSQL Записей Oracle Database Записей Serializable Repetable Read или Serializable* Repetable Read или Serializable* Serializable Serializable Serializable Repetable Read или Serializable* Repetable Read или Serializable* Serializable Serializable Serializable Read Committed Read Committed Read Committed Read Committed Read Committed Serializable Read Committed Read Committed Snapshot Read Committed Read Committed Read Committed Управляемые блокировки * Repeatable Read используется для объектных сущностей (все, у чего есть поле Ссылка – справочники, документы и т. п.), Serializable – для необъектных. Платформа исходит из того, что объекты будут искаться по уникальной ссылке, поэтому проблема фантомного чтения для объектов неактуальна (платформа не позволит добавить объект с такой же ссылкой). Любая операция чтения данных, выполняемая вне транзакции, считается безответственной. Поведение системы при безответственном чтении (например, при выполнении отчетов) отличается в различных режимах блокировок. Отличия безответственного чтения в разных режимах работы управления блокировками (автоматическом или управляемом) для платформы 8.3 приведены в таблице 3.6.3. Таблица 3.6.3. Отличия безответственного чтения в разных режимах работы блокировок для 8.3 (при установленном режиме совместимости конфигурации с 8.3 и выше) Чтение вне транзакции Автоматические блокировки Файловая БД MS SQL Server IBM DB2 PostgreSQL Oracle Database «Грязное» чтение «Грязное» чтение «Грязное» чтение Согласованное чтение Согласованное чтение Управляемые блокировки Файловая БД MS SQL Server 2000 MS SQL Server 2005 и выше IBM DB2 PostgreSQL Oracle Database «Грязное» чтение «Грязное» чтение Согласованное чтение «Грязное» чтение Согласованное чтение Согласованное чтение Если для защиты изменений данных транзакция устанавливает блокировку, то это всегда исключительная (монопольная) блокировка Х, и эта блокировка держится до тех пор, пока транзакция не завершится, независимо от уровня изоляции, установленного для транзакции. Уровень изоляции транзакции влияет на то, ставится вообще блокировка или нет, и на что она ставится. Например, на уровне Serializable появляются блокировки Range. 42 Настольная книга 1С:Эксперта по технологическим вопросам Если транзакция устанавливает блокировку для защиты чтения данных, то, когда речь идет об обычном чтении в транзакции, ставится разделяемая (совместимая) блокировка S, а когда о чтении ДЛЯ ИЗМЕНЕНИЯ – блокировка обновления U. Детальнее о совместимости блокировок говорится в следующей главе. Уровень изоляции транзакции влияет не только на то, ставится ли вообще блокировка и на что она ставится, но и на то, когда она снимается. Снятие блокировок (на уровне СУБД) происходит так: блокировка, установленная «на запись», всегда остается до конца транзакции; ■■ при использовании Repeatable Read или Serializable (автоматический режим управления блокировками «1С») блокировка, установленная «на чтение» сохраняется до конца транзакции. Если после чтения идет запись, это может приводить к взаимоблокировкам по причине повышения уровня блокировки ресурса (причины и обход см. в разделе 3.9); ■■ при использовании Read Committed (управляемый режим управления блокировками «1С») блокировка, установленная «на чтение», снимается после выполнения запроса. Это требует дополнительного блокирования прочитанных данных, если требуется обеспечить их неизменность (см. раздел 3.8). Сводные данные по всем режимам, доступным в «1С:Предприятии», приведены в таблице 3.6.4 (недоступные режимы не приводятся). ■■ Таблица 3.6.4. Сводная таблица по всем режимам, доступным в «1С:Предприятии» Транзакция Уровень изоляции Действие Блокировка Вне транзакции READ UNCOMMITTED чтение нет Вне транзакции* чтение нет чтение Управляемая транзакция READ COMMITTED SNAPSHOT* READ COMMITTED SNAPSHOT* READ COMMITTED REPEATABLE READ Автоматическая транзакция SERIALIZABLE «Грязное» чтение Неповт. чтение Чтение фантомов + + + - + + нет14 - + + запись X - + + чтение запись чтение объектов S (запрос) X S - + + - - + - - - чтение объектов"ДЛЯ ИЗМЕНЕНИЯ" запись объектов чтение регистров чтение регистров "ДЛЯ ИЗМЕНЕНИЯ" запись регистров U X S, RangeS U, RangeU X, RangeX * Только начиная с 8.3 с режимом совместимости с 8.3 и выше ________________ 14 Точнее ставится блокировка стабильности схемы (Sch-S), но она не влияет на блокировки транзакций, включая монопольные (X) блокировки. Теория 43 Транзакции могут быть явными и неявными. Явные транзакции начинаются средствами языка «1С» процедурой глобального контекста НачатьТранзакцию(), завершаются процедурой глобального контекста ЗафиксироватьТранзакцию(), отменяются процедурой ОтменитьТранзакцию(). Неявные транзакции начинаются, завершаются и отменяются средствами платформы. Любые операции, изменяющие данные (например, проведение и отмена проведения документов), выполняются только в транзакции. События прикладных объектов конфигурации, обработчики которых выполняются в неявной транзакции15, приведены в таблице 3.6.5. Речь идет и об обработчиках, которые вызываются через модули этих прикладных объектов, и об обработчиках, которые вызываются через подписки на события.11 Таблица 3.6.5. Обработчики событий прикладных объектов, выполняемые в транзакции Источник Событие Выполняется в транзакции БизнесПроцессОбъект.<Имя бизнес-процесса> ВнешнийИсточникДанныхТаблицаНаборЗаписей.<Имя внешнего источника>.<Имя таблицы внешнего источника данных> ВнешнийИсточникДанныхТаблицаОбъект.<Имя внешнего источника>.<Имя таблицы внешнего источника данных> ДокументОбъект.<Имя документа> ЗадачаОбъект.<Имя задачи> КонстантаМенеджерЗначения.<Имя константы> ПерерасчетНаборЗаписей.<Имя перерасчета> ПланВидовРасчетаОбъект.<Имя плана видов расчета> ПланВидовХарактеристикОбъект.<Имя плана видов характеристик> ПередЗаписью Да ПланОбменаОбъект.<Имя плана обмена> ПланСчетовОбъект.<Имя плана счетов> ПоследовательностьНаборЗаписей.<Имя последовательности> РегистрБухгалтерииНаборЗаписей.<Имя регистра бухгалтерии> РегистрНакопленияНаборЗаписей.<Имя регистра накопления> РегистрРасчетаНаборЗаписей.<Имя регистра расчета> РегистрСведенийНаборЗаписей.<Имя регистра сведений> СправочникОбъект.<Имя справочника> 15 Речь о неявной транзакции, инициированной средствами платформы при выполнении действий с прикладным объектом, и обработчиках, при выполнении этого действия автоматически выполняющихся. Но если просто взять и вызвать выполнение процедуры ОбработкаПроведения(), то само по себе это действие транзакцию не инициирует. Данное замечание верно для таблиц 3.6.5–3.6.8. 44 Настольная книга 1С:Эксперта по технологическим вопросам Источник Событие Выполняется в транзакции БизнесПроцессОбъект.<Имя бизнес-процесса> ВнешнийИсточникДанныхТаблицаНаборЗаписей.<Имя внешнего источника>. <Имя таблицы внешнего источника данных> ВнешнийИсточникДанныхТаблицаОбъект.<Имя внешнего источника>.<Имя таблицы внешнего источника данных> ДокументОбъект.<Имя документа> ЗадачаОбъект.<Имя задачи> КонстантаМенеджерЗначения.<Имя константы> ПерерасчетНаборЗаписей.<Имя перерасчета> ПланВидовРасчетаОбъект.<Имя плана видов расчета> ПланВидовХарактеристикОбъект.<Имя плана видов характеристик> ПриЗаписи Да ПередВыполнением Да ПланОбменаОбъект.<Имя плана обмена> ПланСчетовОбъект.<Имя плана счетов> ПоследовательностьНаборЗаписей.<Имя последовательности> РегистрБухгалтерииНаборЗаписей.<Имя регистра бухгалтерии> РегистрНакопленияНаборЗаписей.<Имя регистра накопления> РегистрРасчетаНаборЗаписей.<Имя регистра расчета> РегистрСведенийНаборЗаписей.<Имя регистра сведений> СправочникОбъект.<Имя справочника> ЗадачаОбъект.<Имя задачи> ЗадачаОбъект.<Имя задачи> ПриВыполнении Да ДокументОбъект.<Имя документа> ОбработкаПроведения Да ДокументОбъект.<Имя документа> ПередУдалением16 Да ДокументОбъект.<Имя документа> ОбработкаУдаленияПроведения Да События расширений управляемых форм, обработчики которых выполняются в неявной транзакции, приведены в таблице 3.6.6. ________________ 16 В синтакс-помощнике выполнение обработчика события ПередУдалением в транзакции в явном виде указано только для ДокументОбъект, для остальных видов объектов связь обработчика с транзакциями не указана. Теория 45 Таблица 3.6.6. Обработчики событий расширений управляемых форм, выполняемые в транзакции Источник Выполняется в транзакции Событие Расширение управляемой формы для бизнес-процесса Расширение управляемой формы для документа Расширение управляемой формы для задачи Расширение управляемой формы для записи регистра сведений Расширение управляемой формы для записи таблицы внешнего источника данных Расширение управляемой формы для констант ПриЗаписиНаСервере Да Расширение управляемой формы для набора записей Расширение управляемой формы для объекта таблицы внешнего источника данных Расширение управляемой формы для объектов Расширение управляемой формы для плана видов характеристик Расширение управляемой формы для справочника События расширений обычных форм, обработчики которых выполняются в неявной транзакции, приведены в таблице 3.6.7. Таблица 3.6.7. Обработчики событий расширений обычных форм, выполняемые в транзакции Источник Выполняется в транзакции Событие Расширение формы вида расчета Расширение формы документа Расширение формы задачи Расширение формы записи регистра сведений Расширение формы констант Расширение формы набора записей регистра бухгалтерии Расширение формы набора записей регистра накопления Расширение формы набора записей регистра расчета ПриЗаписи Да Расширение формы набора записей регистра сведений Расширение формы объекта бизнес-процесс Расширение формы узла Расширение формы элемента вида характеристик Расширение формы элемента плана счетов Расширение формы элемента справочника События расширений управляемых форм, обработчики которых выполняются вне неявной транзакции, приведены в таблице 3.6.8. 46 Настольная книга 1С:Эксперта по технологическим вопросам Таблица 3.6.8. Обработчики событий расширений управляемых форм, выполняемые вне транзакции Источник Событие Выполняется в транзакции Расширение управляемой формы для бизнес-процесса Расширение управляемой формы для документа Расширение управляемой формы для задачи Расширение управляемой формы для записи регистра сведений Расширение управляемой формы для записи таблицы внешнего источника данных Расширение управляемой формы для констант ПередЗаписьюНаСервере Нет ПослеЗаписиНаСервере Нет ПослеЗаписи Нет Расширение управляемой формы для набора записей Расширение управляемой формы для объекта таблицы внешнего источника данных Расширение управляемой формы для объектов Расширение управляемой формы для плана видов характеристик Расширение управляемой формы для справочника Расширение управляемой формы для бизнес-процесса Расширение управляемой формы для документа Расширение управляемой формы для задачи Расширение управляемой формы для записи регистра сведений Расширение управляемой формы для записи таблицы внешнего источника данных Расширение управляемой формы для констант Расширение управляемой формы для набора записей Расширение управляемой формы для объекта таблицы внешнего источника данных Расширение управляемой формы для объектов Расширение управляемой формы для плана видов характеристик Расширение управляемой формы для справочника Расширение управляемой формы для бизнес-процесса Расширение управляемой формы для документа Расширение управляемой формы для задачи Расширение управляемой формы для записи регистра сведений Расширение управляемой формы для записи таблицы внешнего источника данных Расширение управляемой формы для констант Расширение управляемой формы для набора записей Расширение управляемой формы для объекта таблицы внешнего источника данных Расширение управляемой формы для объектов Расширение управляемой формы для плана видов характеристик Расширение управляемой формы для справочника Теория 47 События расширений обычных форм, обработчики которых выполняются вне неявной транзакции, приведены в таблице 3.6.9. Таблица 3.6.9. Обработчики событий расширений обычных форм, выполняемые вне транзакции Источник Событие Расширение формы вида расчета Расширение формы документа Расширение формы задачи Расширение формы записи регистра сведений Расширение формы констант Расширение формы набора записей регистра бухгалтерии Расширение формы набора записей регистра накопления ПослеЗаписи Расширение формы набора записей регистра расчета Расширение формы набора записей регистра сведений Расширение формы объекта бизнес-процесс Расширение формы узла Расширение формы элемента вида характеристик Расширение формы элемента плана счетов Расширение формы элемента справочника Выполняется в транзакции Нет Прочие события объектов, их форм, обычных и управляемых, и расширений этих форм выполняются вне неявных транзакций. Чтобы удостовериться, выполняется обработчик события в транзакции или нет, нужно открыть его в синтакс-помощнике, и если это так, в блоке «Описание» будет написано «возникает в транзакции», «вызывается... до окончания транзакции» и т. п. Наличие параметра Отказ в параметрах обработчика событий не служит признаком, того, что обработчик выполняется в транзакции: например, обработчик события ОбработкаПроверкиЗаполнения() содержит параметр Отказ, но выполняется вне неявной транзакции. Операции чтения могут выполняться в неявной транзакции. Это происходит, когда требуется обеспечить чтение согласованного набора данных. На текущий момент нам известно о двух случаях, когда это происходит: ■■ ■■ 17 При чтении в объектной технике объектов, имеющих табличные части17, например, запрос: 12 ДокументПроведен = ДокументСсылка.Проведен; будет выполняться в неявной транзакции, если для документа данного типа в конфигураторе определена табличная часть, но вне транзакции, если табличных частей у документа нет. При формировании отчетов, требующих согласованных данных. Например, если отчет строится с помощью построителя, то в большинстве случаев он выполняется, как и ожидается, без транзакции, но если в настройке отчета в группировках строк указать «По неделям», то при вызове метода ПостроительОтчета.Вывести(ТабличныйДокумент); инициируется транзакция. Анонсирован отказ от использования транзакций для этих целей в будущем. 48 Настольная книга 1С:Эксперта по технологическим вопросам Обращаем внимание на то, что раз разговор идет о транзакционном чтении, то в этих случаях могут возникать (и возникают) конфликты блокировок в совершенно неожиданных местах: при работе с формами, в отчетах и, казалось бы, в безобидных обработках. Ситуация с отчетами ухудшается тем, что на выбор – выполняется чтение в транзакции или нет – влияет не код конфигурации, а пользовательские настройки. А чтение в объектной технике – это настолько важный вопрос, что ему посвящен отдельный раздел 3.15 «Особенности чтения в объектной модели». Узнать, выполняется чтение с транзакции или нет, можно в профайлере SQL Server. Настроив трассировку, например, в соответствии с разделом 4.12 «Работа в профайлере. Как получить план запроса», нужно с помощью отладчика, выполнить подозрительную строку. Если транзакция имеет место, в трассировке появятся BEGIN TRANSACTION и COMMIT TRANSACTION. Транзакции, как явные, так и неявные, могут быть вложенными. Обычный случай, например, запись элемента одного справочника из процедуры ПриЗаписи модуля другого справочника или из подписок на события, обрабатываемых внутри транзакции. Применение такого подхода при всем его удобстве, однако, может создавать проблемы производительности, поэтому пользоваться им надо аккуратно, а злоупотреблять, создавая каскады записывающихся друг из друга объектов, не стоит вообще. Если внутри транзакции произошла исключительная ситуация, она откатывается. Если внутри транзакции были вложенные транзакции или она сама являлась вложенной, откатываются все транзакции, независимо от того, на каком из уровней вложенности это произошло. Проще говоря, никто не запрещает начинать одну транзакцию внутри другой, но ведет себя все это почти всегда как одна транзакция самого верхнего уровня, т. е. вложенные транзакции игнорируются. Нюансы поведения, связанные с отработкой некоторых ошибок в коде, приведены ниже. Если исключительную ситуацию отработать с помощью скобок Попытка... Исключение... КонецПопытки, расположенных внутри транзакции, то транзакция не завершится в момент возникновения исключительной ситуации, она дойдет до следующего обращения к данным – чтения или записи, продолжая при этом блокировать ресурсы, и откатится с сообщением: «В данной транзакции уже происходили ошибки!». Если таких ошибок много и они начинают создавать проблемы пользователям, то без модификации кода, удаления этих скобок очень трудно найти, где они произошли и почему. Описанное поведение системы позволяет говорить о том, что при возникновении ситуации, когда внутри транзакций нужно использовать скобки Попытка... Исключение... КонецПопытки, необходимо, отработав исключительную ситуацию, вызывать оператор ВызватьИсключение. Случается, однако, что транзакция, встретившись с ошибкой, находящейся в скобках Попытка... Исключение... КонецПопытки, продолжает работу. Такое различие в поведении будет зависеть от типа исключительной ситуации. Исключительные Теория 49 ситуации бывают восстановимыми (после которых можно продолжить работу и завершить транзакцию) и невосстановимыми (после которых нельзя продолжить работу и завершить транзакцию, например, ошибка базы данных). Внешне это может выглядеть как зависимость от того, как код, вызвавший исключение, и скобки Попытка... Исключение... КонецПопытки расположены относительно ближайшей к ним транзакции. Пример 1 НачатьТранзакцию(); Попытка ЭтотОбъект.ВыполнитьНесуществующийМетод(); // (такого метода у объекта не создавали) Исключение КонецПопытки; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ПлатежноеПоручение.Ссылка |ИЗ | Документ.ПлатежноеПоручение КАК ПлатежноеПоручение"; Результат = Запрос.Выполнить(); СпрСсылка = Справочники.Организации.НайтиПоКоду("000001"); СпрОбъект = СпрСсылка.ПолучитьОбъект(); СпрОбъект.НаименованиеПолное = ТекущаяДата(); // это чтобы отследить, зафиксирована транзакция или нет СпрОбъект.Записать(); ЗафиксироватьТранзакцию(); Код выполнится. Транзакция успешно завершится. Исключительная ситуация оказалась расценена как восстановимая. Пример 2 Сначала в процедуру ПриЗаписи модуля справочника Организации добавим строку: ЭтотОбъект.ВыполнитьНесуществующийМетод(); // (такого метода у объекта не создавали) Далее изменим код из примера 1: НачатьТранзакцию(); Попытка СпрСсылка = Справочники.Организации.НайтиПоКоду("000001"); СпрОбъект = СпрСсылка.ПолучитьОбъект(); СпрОбъект.НаименованиеПолное = ТекущаяДата(); //это чтобы отследить, зафиксирована транзакция или нет СпрОбъект.Записать(); // неявная транзакция, там, как помним, ошибка Исключение КонецПопытки; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ 50 Настольная книга 1С:Эксперта по технологическим вопросам | |ИЗ | ПлатежноеПоручение.Ссылка Документ.ПлатежноеПоручение КАК ПлатежноеПоручение"; Результат = Запрос.Выполнить(); ЗафиксироватьТранзакцию(); Получим ошибку: Ошибка при вызове метода контекста (Выполнить) Результат = Запрос.Выполнить(); По причине: Ошибка выполнения запроса. По причине: В данной транзакции уже происходили ошибки! Исключительная ситуация, хотя она вызвана аналогичной строкой кода, потянула за собой дополнительные последствия (откат транзакции записи элемента справочника) и оказалась расценена как невосстановимая. 3.7. Блокировки данных СУБД. Уровни блокировок. Совместимость блокировок Блокировка – это отметка (информация) о том, что требуемый ресурс в настоящее время захвачен (в случае блокировок в рассматриваемых информационных системах захвачен транзакцией). В СУБД на блокировках основана работа механизм обслуживания параллельных запросов. Возвращаясь к аналогии с поездкой в магазин, можем указать следующие аналоги блокировок: покупатель у стеллажа с товаром: его самого видно, эта визуальная информация есть указание на блокировку ресурса «стеллаж»; ■■ ряд стеллажей, перегороженный для работы погрузчика: сам погрузчик не занимает всего ряда, но ресурс «ряд стеллажей» заблокирован ограничительными лентами полностью; ■■ автомобиль на шоссе: его видно, эта визуальная информация есть указание на блокировку ресурса «часть дорожного полотна»;13 ■■ знак «ремонт» и ограждение: даже если за ними сейчас нет рабочих, это указание на блокировку ресурса «протяженный участок дороги». Еще раз обращаем внимание, что вообще-то блокировка – это не физический захват ресурса, а информация о том, что ресурс захвачен. В широко известной статье про яблоки18 для подчеркивания этого специально используется внесение записей о захвате ресурсов, потому что иначе, как и в приведенных выше примерах с блокированием ряда стеллажей и протяженного участка дороги, невозможно объяснить и описать захват большего количества ресурсов, чем захватывается физически. ■■ 18 Эта статья является фрагментом книги: П. С. Белоусов, А. В. Островерх «1С:Предприятие: от 8.0 к 8.1». Дата выхода книги – ноябрь 2007. Теория 51 Иногда, конечно, можно приводить аналогии и с физическим захватом объектов, понимая под информацией о захвате непосредственное наблюдение факта захвата ресурса. Но вот если мы хотим разобрать работу самого механизма блокировок, физический захват от информации о нем надо отделять. Следует отметить, что блокировки с точки зрения прикладной логики могут быть необходимыми, а могут быть избыточными. Ограждение ремонта дороги, безусловно, необходимо. Но то же самое ограждение ремонта дороги, занимающее гораздо больше места, чем реально требуется для проведения работ (можно было оградить сначала один ряд, потом второй, а оградили оба на весь период ремонта), или продолжающее стоять после того, как работы закончены, являет собой хорошую иллюстрацию избыточных блокировок. Далее в этой главе мы рассмотрим то, что называют «блокировками СУБД». Эти блокировки устанавливает менеджер блокировок СУБД, и устанавливает он их только для транзакций. О блокировках, которые устанавливаются платформой «1С:Предприятие» (как объектных, так и транзакционных, устанавливаемых собственным менеджером транзакционных управляемых блокировок), см. главу «Теория», раздел 3.8. Переходя к разбору понятия уровня блокировок, нельзя не отметить путаницу в терминах и попытаться хотя бы слегка с ней разобраться. Разное применение одинаковых терминов приведено в таблице 3.7.1. В данной работе мы будем придерживаться первого столбца, кроме случаев, где об этом будет специально сказано. Таблица 3.7.1. Разное применение одинаковых терминов, касающихся блокировок Термин, применяемый в «1С» сообществе Уровень блокировок Тип блокировок Термин документации SQL Server Что это на самом деле Режимы блокировок (Lock modes) Определяют доступ одновременных транзакций к ресурсам (материал этой главы) Нет Неаккуратное использование термина «Режим управления блокировкой данных» (автоматический или управляемый) Объем (уровень в иерархии) ресурсов, на который накладывается блокировка (напр., запись или таблица). При неаккуратном использовании термина «уровень блокировок» может теряться понимание, что на самом деле речь не об уровне блокировки, а об уровне блокируемых ресурсов Элемент Visual Studio Team Foundation Server 2012 Режим блокировок Режим блокировок Гранулярность блокировок Гранулярность блокировок (Lock granularity), Вид блокировок также Уровень блокировок (Lock level) Уровень блокировок (напр. в выражении «блокировка на уровне записей») Нет Тип блокировок (Lock type) В простейшем случае выделяют два уровня блокировок: исключительный (монопольный) и разделяемый. Исключительный уровень не дает работать с ресурсом никому, кроме захватившей его транзакции, используется для отметки о том, что в ресурс осуществляется запись. Разделяемый уровень позволяет работать с ресурсом другим транзакциям, если они также готовы ограничиться только разделяемым уровнем блокировки. Этот уровень используется для отметки, что осуществляется чтение ресурса. 52 Настольная книга 1С:Эксперта по технологическим вопросам На практике, однако, этих двух уровней иногда оказывается мало, и для решения некоторых прикладных задач могут быть введены дополнительные уровни. В таблице 3.7.2 показаны уровни блокировки ресурсов, применяемые компонентом Database Engine SQL Server 2005. В этом случае названия уровней применяются разные, но они являются только синонимами, и при их использовании нет разночтений, поэтому они все приведены вместе. Таблица 3.7.2. Режимы блокировки ресурсов, применяемые SQL Server 2005 Режим блокировки Shared Разделяемая, совмещаемая блокировка (S) Update Блокировка обновления (U) Exclusive Эксклюзивная, исключительная, монопольная блокировка (Х) Intent Блокировка с намерением (IS, IX, SIX) Описание Используется для операций считывания, которые не меняют и не обновляют данные, такие как инструкция SELECT Применяется к тем ресурсам, которые могут быть обновлены. Предотвращает возникновение распространенной формы взаимоблокировки, возникающей тогда, когда несколько сеансов считывают, блокируют и затем, возможно, обновляют ресурс Используется для операций модификации данных, таких как инструкции INSERT, UPDATE или DELETE. Гарантирует, что несколько обновлений не будет выполнено одновременно для одного ресурса Используется для создания иерархии блокировок. Типы намеренной блокировки: с намерением совмещаемого доступа (IS), с намерением монопольного доступа (IX), а также совмещаемая с намерением монопольного доступа (SIX). Блокировки с намерением называются так потому, что их получают до блокировок ресурсов более низкого уровня19, то есть они обозначают намерение поместить блокировку на более низком уровне ресурсов. Имеют особенность: устанавливаются на верхних уровнях иерархии (например, на уровне таблицы). Таким образом, если в графе взаимоблокировки встретилась блокировка с намерением, можно сразу говорить о том, что ею заблокирован большой объем данных, совершенно точно это не единичные записи ________________ 19 В данном предложении под высоким/низким уровнем понимается не Lock mode, а именно Lock level – объем (уровень) данных, на который накладывается блокировка. Речь идет, например, о том, что при постановке какой-то блокировки на запись таблицы на всю таблицу ставится соответствующая блокировка намерения. Благодаря этому предотвращается изменение ресурса более высокого уровня другими транзакциям таким образом, что это сделает недействительной блокировку более низкого уровня. И нет необходимости проверять блокировки в каждой строке и на каждой странице, чтобы убедиться, что транзакция может заблокировать всю таблицу, что повышает производительность. Теория Режим блокировки 53 Описание Используется во время выполнения операции, зависящей от схемы таблицы. Типы блокировки схем: блокировка изменения схемы (Sch-S) и блокировка стабильности схемы (Sch-M) Используется, если выполняется массовое копирование данных в таблицу и указана подсказка TABLOCK Защищает диапазон строк, считываемый запросом при использовании уровня изоляции транзакции Serializable. Запрещает другим транзакциям вставлять строки, что помогает запросам такой транзакции уточнять, были ли запросы запущены повторно Schema Блокировка схемы (Sch-S, Sch-M) Bulk Update Блокировка массового обновления (BU) Key-range Диапазон ключей На два режима блокировок SQL Server хотелось бы обратить особое внимание: 1. Блокировка обновления. На практике включается добавлением в текст запроса на языке запросов «1С:Предприятия» опции ДЛЯ ИЗМЕНЕНИЯ. Имеет смысл только в транзакциях с уровнями изоляции Serializable и Repeatable Read, т. е. только для автоматического режима управления блокировкой данных, потому что в случае использования Read Committed, если данные запросом не изменялись, блокировка все равно снимается после выполнения запроса. 2. Блокировка диапазона ключей. Используется только в транзакциях с уровнем изоляции Serializable. В системах «1С» такие транзакции используются только при автоматическом режиме управления блокировкой данных. Таким образом, если блокировка Key-range попала во взаимоблокировку, первый подходящий способ от этой взаимоблокировки избавиться – перейти в управляемый режим. Способность нескольких транзакций одновременно обзавестись блокировками на один и тот же ресурс определяется совместимостью блокировок. Если на ресурсе уже стоит блокировка от другой транзакции, новое требование на блокировку, полученное от другой транзакции, может быть удовлетворено, только если затребованный уровень блокировки совместим с уже установленным уровнем. В противном случае транзакция, запросившая новую блокировку, будет ждать, пока не истечет время ожидания существующей блокировки. В таблице 3.7.3 показана совместимость для наиболее распространенных уровней блокировки. Таблица 3.7.3. Совместимость наиболее распространенных уровней блокировки SQL Server Уже предоставленный уровень Запрашиваемый уровень Разделяемая (S) Обновления (U) Исключительная (Х) S Да Да Нет U Да Нет Нет X Нет Нет Нет 54 Настольная книга 1С:Эксперта по технологическим вопросам 3.8. Сведения об управляемых и объектных блокировках В платформе «1С:Предприятие» существуют два механизма, которые называются блокировками: транзакционные блокировки, объектные блокировки. Общего у них то, что они обе по сути обеспечивают внесение и контроль записей о том, что некие ресурсы заблокированы. Но и сами эти ресурсы, и ситуации, когда эти механизмы работают, различаются настолько, что эти два механизма надо рассматривать как совершенно разные и независимые, каковыми они на деле и являются. ■■ ■■ Транзакционные блокировки – это аналог блокировок СУБД, которые рассматривались в предыдущей главе. Они обеспечиваются менеджером транзакционных блокировок. Они используются, например, в дополнение к блокировкам СУБД, чтобы убирать побочные эффекты параллелизма, присущие уровню изоляции Read Committed, который устанавливается для СУБД при включении управляемого режима управления блокировкой данных в «1С» (это не единственное их назначение, в целом область применения управляемых блокировок намного шире). Транзакционные блокировки вместе с блокировками СУБД входят в сферу профессиональной деятельности 1С:Экспертов по технологическим вопросам. Конфликты этих блокировок – это такие же таймауты и взаимоблокировки. Как и конфликты блокировок СУБД, они обычно рассматриваются как критичные ошибки. Также и способ образования этих конфликтов соответствует способу их образования в СУБД. Напротив, объектные блокировки в эту сферу не входят20, но, чтобы было понятно, о чем речь, сначала уделим внимание им.14 Механизм объектных блокировок позволяет оповестить пользователей о захвате объектных данных «1С:Предприятия»: справочников, документов, планов видов характеристик, планов счетов, планов видов расчета, бизнес-процессов, задач, планов обмена. То есть это не столько механизм защиты, сколько механизм оповещения. Чаще всего пользователи видят сообщения от этого механизма, редактируя данные объектов в формах, и воспринимают их как ошибку (на самом деле если эти сообщения и можно считать сообщениями об ошибках, то только об ошибках организации работы пользователей): 1. 20 «Не удалось заблокировать запись. Действие (изменение, удаление или блокировка записи) не выполнено». События, происшедшие с момента выхода первого издания, показали, что и объектные блокировки могут являться предметом внимания 1С:Экспертов по технологическим вопросам, если имеет место неправильно организованная массовая работа с одними и теми же объектами. Например, массовый просмотр одних и тех же объектов через форму элемента не является ошибкой проектирования. А вот массовое закрытие этих форм кнопкой ОК, которая не только закрывает окно, но и перезаписывает объект, – это ошибка, и для форм, открывающихся только для целей просмотра, возможность записи тем или иным способом надо закрывать. Теория 2. 55 «Операция не может быть выполнена из-за несоответствия версии или отсутствия записи базы данных (возможно, запись была изменена или удалена)». Либо в последних версиях: «Данные были изменены или удалены другим пользователем». Если один пользователь начинает модификацию объекта в форме, а другой после этого тоже попытается начать редактирование того же объекта, то понятно, что одновременное редактирование одного и того же объекта приведет к нежелательным последствиям. Поэтому расширение формы устанавливает пессимистическую блокировку, не позволяющую редактировать кем-то уже редактируемые данные. И как только второй пользователь попытается этот объект модифицировать, он получит сообщение 1. Если теперь первый пользователь запишет изменения и закроет форму, то пессимистическая блокировка снимется. Но если другой пользователь опять попытается начать редактирование того же объекта в той же открытой ранее форме, он получит сообщение 2 – сработает оптимистическая блокировка, не позволяющая редактировать данные, измененные или удаленные за время, прошедшее с их считывания. Названия «пессимистическая» и «оптимистическая» взялись из следующего: пессимистическая блокировка исходит из предположения, что «если что-то плохое может случиться, это обязательно случится», то есть если мы выполняем действие, конкурентное выполнение которого может привести к «поломке» данных, то правильным будет исключить возможность конкурентного исполнения; ■■ оптимистическая блокировка предполагает, что во время обновления записи в базе мы будем единственными, кто ее меняет. В большинстве случаев так оно и есть (оптимизм оправдан). Но перед этим необходимо точно удостовериться, что запись с момента ее чтения не изменилась. Объектные блокировки снимаются при выгрузке объекта из памяти (например, при закрытии формы или в конце процедуры). Со стартом и окончанием транзакций это не связано никак21.15 ■■ Механизм транзакционных управляемых блокировок «1С» (механизм управляемых блокировок), как уже говорилось, обеспечивается своим собственным менеджером и решает вопросы, аналогичные вопросам менеджера блокировок СУБД. Точнее говоря, этот механизм позволяет при необходимости усилить изолированность транзакций, не меняя уровня изоляции в СУБД. И понятно, почему нет смысла его использовать в автоматическом режиме управления блокировками: там уровень изоляции для СУБД и так самый высокий – Serializable. Заметим, что данных механизма объектных блокировок этот механизм при работе не видит и не принимает в расчет вообще. 21 Кроме того, пессимистическая объектная блокировка может быть установлена программно методом <Объект>.Заблокировать() и снята методом <Объект>.Разблокировать(). Эти методы есть у объектных типов данных. Важно: не следует путать методы <Объект>.Заблокировать() и <БлокировкаДанных>.Заблокировать(). Первый устанавливает объектную пессимистическую блокировку, второй – транзакционную управляемую. 56 Настольная книга 1С:Эксперта по технологическим вопросам Как в простейшем случае для СУБД, для управляемых блокировок «1С» выделяют два уровня: исключительный и разделяемый. Их описание, приведенное в синтакс-помощнике, отражено в таблице 3.8.1. Таблица 3.8.1. Уровни блокировки ресурсов управляемыми блокировками «1С» Уровень блокировки (РежимБлокировкиДанных) Разделяемый (Shared) Исключительный (Exclusive) Описание Разделяемая блокировка позволит конкурирующему процессу установить разделяемую блокировку по этому же условию, но не позволит установить исключительную блокировку Исключительная блокировка не позволит конкурирующему процессу установить разделяемую или исключительную блокировку по этому же условию Совместимость уровней блокировок, приведенная в таблице 3.8.2, классическая. Таблица 3.8.2. Совместимость уровней управляемых блокировок «1С» Уже предоставленный уровень Запрашиваемый уровень Разделяемая (S) Исключительная (Х) S Да Нет X Нет Нет Установленные управляемые блокировки, как разделяемые, так и исключительные, держатся до конца транзакции22.16 Менеджер транзакционных управляемых блокировок «1С» ничего не знает и никак не взаимодействует с механизмом транзакционных блокировок СУБД. Это означает, например, что ресурсы, заблокированные исключительными управляемыми блокировками, могут оставаться доступными для чтения запросами на языке запросов. Это может помочь обходить некоторые неразрешимые конфликты управляемых блокировок (взаимоблокировки), но при таком способе обхода есть опасность, что возникнут побочные эффекты параллелизма, и это надо просчитывать. Аналогично в обратную сторону: управляемые блокировки «1С» могут быть установлены независимо от того, какие ресурсы заблокированы блокировками СУБД. Такую рассогласованность не всегда можно игнорировать. Поэтому при выполнении некоторых операций с базой данных платформа может ставить управляемые блокировки самостоятельно. Управляемые разделяемые блокировки устанавливаются платформой при чтении в объектной технике23 следующих видов объектов: 17 ■■ ■■ ■■ 22 23 набор записей регистра сведений, набор записей регистра накопления, набор записей регистра бухгалтерии, Самые глубокие извинения от автора всем читателям за ошибку в этом месте в первом издании книги. Пример из первого издания, содержавший ошибочный анализ, см. в разделе 4.25 «Работа с ТЖ. Как расследовать конфликт на управляемых блокировках». Чтение в объектной технике обладает еще одной особенностью: оно в ряде случаев выполняется в неявной транзакции. Подробнее см. раздел 3.15. Теория 57 набор записей регистра расчета, ■■ набор записей перерасчета, ■■ набор записей последовательности. При записи в объектной технике указанных выше видов объектов устанавливаются исключительные управляемые блокировки. ■■ Платформа НЕ устанавливает блокировок при чтении в объектной технике как минимум следующих объектов: констант и наборов констант; ■■ справочников (например, используя методы Справочники.ИмяСправочника.Выбрать(), СправочникВыборка.Следующий(), СправочникВыборка.ПолучитьОбъект(), СправочникСсылка.ПолучитьОбъект() и т. д.); ■■ документов (аналогично справочникам); ■■ других объектов (планов видов характеристик, планов счетов и т. д.). Методика получения точной информации, какие именно управляемые блокировки установлены в каждом конкретном случае, описана в разделе 4.24 «Работа с ТЖ. Как посмотреть, какие управляемые блокировки были установлены». ■■ Методика расследования конфликтов на управляемых блокировках описана в разделе 4.25 «Работа с ТЖ. Как расследовать конфликт на управляемых блокировках». В заключение расскажем еще раз о режимах управления блокировкой данных. Если требуется обеспечить должное качество работы информационной системы «1С» с высокими требованиями к параллельной работе пользователей, то использование автоматического режима управления блокировкой данных является ошибкой, без устранения которой другие работы по оптимизации системы могут не иметь смысла. При этом использование смешанного, «автоматического и управляемого» режима в таких случаях также чаще всего будет ошибкой, поскольку, как правило, основные прикладные объекты в таком переходном состоянии остаются с установленным автоматическим режимом управления блокировкой. 3.9. Ошибки блокировок: таймауты и взаимоблокировки Общие вопросы Если транзакция хочет установить блокировку на ресурс, но обнаруживает, что на ресурсе уже стоит несовместимая с ней блокировка, она ставится в очередь на установку блокировки. При наступлении определенных событий транзакция может быть удалена из очереди до того, как она дождется своего права установить блокировку. Если такое происходит, это приводит к возникновению исключительной ситуации, которая называется ошибкой (конфликтом) блокировок. Транзакция при этом откатывается, пользователь получает сообщение об ошибке. 58 Настольная книга 1С:Эксперта по технологическим вопросам Текст сообщения об ошибке зависит от того, был ли это конфликт управляемых блокировок или конфликт блокировок СУБД. Если конфликт произошел в СУБД, текст зависит от того, что это за СУБД, а также от ее версии и языка. Ключевые фразы, по которым на текущий момент можно определить текст ошибок блокировок, приведены в таблице 3.9.1. Причин такого удаления две: 1. Транзакция стоит в очереди с точки зрения системы уже слишком долго, не выполняя действий и, возможно, блокируя ресурсы, которые ей требовались на предыдущих шагах. Такая причина называется таймаутом, ошибкой превышения времени ожидания на блокировке. 2. Произошла ситуация, которая была квалифицирована как взаимная блокировка ресурсов (deadlock, взаимоблокировка). Таблица 3.9.1. Подстроки, идентифицирующие ошибки блокировок в текстах сообщений об ошибках (пользователям и в технологическом журнале «1С») Подстрока Превышено максимальное время ожидания Maximum idle time for lock access Неразрешимый конфликт блокировок Unresolved lock conflict in a session SQL Server: Lock request time out period exceeded SQL Server: Превышено время ожидания запроса на блокировку was deadlocked on lock resources with another process and has been chosen as the deadlock victim вызвала взаимоблокировку ресурсов SQL0911N The current transaction has been rolled back because of a deadlock or timeout SQL0911N Из-за тупиковой ситуации или из-за истечения срока ORA-00051: timeout occurred while waiting for a resource ORA-00051: Истекло время ожидания ресурса ORA-00060: deadlock detected while waiting for resource или ORA-00060: Deadlock detected ORA-00060: Возникла мертвая блокировка во время ожидания ресурса или ORA-00060: тупик обнаружено Рассмотрим каждую из ошибок подробнее. Ошибка таймаут на управляемых блокировках (1С- рус.) таймаут на управляемых блокировках (1С-англ.) взаимоблокировка на управляемых блокировках (1С-рус.) взаимоблокировка на управляемых блокировках (1С-англ.) таймаут СУБД SQL Server (англ.) таймаут СУБД SQL Server (рус.) взаимоблокировка СУБД SQL Server (англ.) взаимоблокировка СУБД SQL Server (рус.) любой конфликт блокировок СУБД IBM DB2 (англ.) любой конфликт блокировок СУБД IBM DB2 (рус.) таймаут СУБД Oracle Database (англ.) таймаут СУБД Oracle Database (рус.) взаимоблокировка СУБД Oracle Database (англ.) взаимоблокировка СУБД Oracle Database (рус.) Теория 59 Таймаут Время, которое транзакция может ждать освобождения ресурса, задается в свойствах системы. В системах на платформе «1С:Предприятие» оно по умолчанию равно 20 секундам и устанавливается в конфигураторе (Администрирование – Параметры информационной базы – Время ожидания блокировки данных (в секундах)). Это время действует и на управляемые блокировки «1С:Предприятия», и на блокировки СУБД. Если транзакции приходится ждать дольше, возникает таймаут. Казалось бы, ждать, так ждать, и первый приходящий в голову способ решить проблему – ускорить время обработки каждой транзакции, например, повысив характеристики оборудования или оптимизировав код с точки зрения его выполнения. Однако существуют дополнительные факторы, которые надо учитывать и которые в ряде случаев могут оказаться существенно более важными. Рассмотрим ситуации, происходящие в офисе, в котором работают две сотрудницы: Светочка и Леночка. Они приходят на работу примерно в одно время, а уходят ровно в 18:00, если нет начатой, но недоделанной работы. Они дружат, то есть у них существует договоренность, что документ24, лежащий на общем столе, читать можно, а документ, переложенный на личный стол или находящийся в руках, другой сотруднице трогать и смотреть нельзя25.1819 1. Обеим сотрудницам за сегодня нужно внести изменения в один и тот же документ. Леночка пришла чуть позже, и Светочка уже взяла документ и начала вносить в него изменения. Она не отдаст документ, пока не сделает свою работу с ним до конца (Светочка установила необходимую исключительную блокировку). Успеет ли Леночка до 18:00 начать вносить свои изменения в документ или уйдет домой, даже не начав работу, зависит от следующего: □□ □□ □□ □□ скорости работы Светочки; объема документа; объема вносимых изменений; не вызовут ли Светочку посередине дня на неопределенное время на совещание, а документ она унесет с собой – вызов модального окна из транзакции; □□ не потребуется ли для внесения изменений в этот документ много раз бегать к шкафу за дополнительной информацией – запрос в цикле; □□ не потребует ли внесение изменений в этот документ поездки в другой офис за дополнительной информацией – получение в транзакции данных из внешнего источника; □□ не потребует ли внесение изменений в этот документ вносить изменения в другие документы, за которыми придется бегать в лучшем случае в соседнюю комнату, а в худшем – в соседнее здание – вложенные транзакции. Но там другие документы могут оказаться еще и заняты другими 24 25 В данном случае понятию «документ» в тексте больше соответствует понятие «набор записей регистра» в терминах метаданных «1С», а не «документ». Блокировка – это не факт захвата ресурса, а запись о таком захвате. Но здесь в примерах для простоты будем считать, что факт захвата является и информацией о нем. 60 2. 3. 4. Настольная книга 1С:Эксперта по технологическим вопросам сотрудницами, так что Светочке придется ждать, пока они освободят их. Все документы с внесенными изменениями Светочка будет хранить у себя, пока не закончит работу с основным документом. Как видим, начнет ли Леночка сегодня работу, зависит не только от Светочки и от объема вносимых изменений, но и от Светочкиной должностной инструкции. Но и этим дело не ограничивается. На следующий день обеим сотрудницам нужно внести изменения в разные документы: Светочке – в новый, а Леночке – в не начатый вчера. Но документы лежали в одной стопке, Леночка опять пришла чуть позже, и Светочка уже взяла всю стопку документов и начала вносить изменения в свой документ, пропустив Леночкины, но и не отдавая его (Светочка установила избыточную исключительную блокировку). □□ Все, из-за чего Леночка ждала в предыдущий день, повторяется снова. Трагизм ситуации усиливается тем, что ее документ Светочке уже не нужен, но по правилам она не отдаст всю взятую стопку документов, пока не закончит с ней работать. Как видим, начнет ли Леночка сегодня работу, зависит не только от Светочки, от объема вносимых изменений и должностной инструкции Светочки, а в случае возможности избыточных блокировок еще и от того, не взяла ли Светочка не свой документ. Но и этим дело не ограничивается. На следующий день обеим сотрудницам нужно опять внести изменения в разные документы: Светочке – в новый, Леночке – в не начатые вчера и позавчера. Леночка решила, что теперь она возьмет себе всю стопку, но опять пришла чуть позже, и Светочка уже взяла один свой документ и начала с ним работать. Поскольку Леночка твердо решила брать стопку целиком (собирается установить избыточную исключительную блокировку), ей опять приходится ждать. Как видим, начнет ли Леночка сегодня работу, зависит не только от Светочки, от объема вносимых изменений, Светочкиной должностной инструкции, не взяла ли Светочка не свой документ, а еще и от того, не собирается ли Леночка взять не свои документы. Но и этим дело не ограничивается. У Светочки и Леночки есть начальник, который должен проверять за ними все измененные ими документы. Но поскольку документы приходят к нему только от Светочки, он и выполняет только половину работы (характерный спад загрузки после «бутылочного горлышка»). Переходя от примеров к теории, причинами таймаутов могут являться: ■■ ■■ ■■ ■■ неправильная организация рабочего процесса (конкуренция за одни и те же данные); выбор неправильного прикладного объекта метаданных конфигурации для хранения данных (тоже конкуренция за одни и те же данные, см. раздел 3.11); игнорирование особенностей работы ресурсов, в которые возможна только последовательная запись, см. раздел 3.11; неоптимальная работа запросов, как вызывающая избыточные блокировки, так и увеличивающая время выполнения самих этих запросов; Теория 61 использование механизмов, провоцирующих неоптимальную работу запросов; ■■ использование высокого уровня изоляции транзакций; ■■ включение в транзакцию механизмов, вызывающих непрогнозируемое увеличение ее времени и ставящих ее в зависимость от посторонних ресурсов (модальные окна, работа с внешними источниками, вложенные транзакции); ■■ увеличение времени транзакции, как за счет медленной работы кода, так и за счет объединения нескольких транзакций в одну (например, групповая обработка документов в одной транзакции). В качестве причин таймаутов иногда называется недостаточная производительность оборудования. Но надо понимать, что эта причина может явиться руководством к действиям по улучшению оборудования практически в единственном случае: когда оборудование явно не соответствует стоящим перед ним задачам, и показатели его загрузки при работе существенно превышают все рекомендованные значения. В подавляющем же большинстве ситуаций при проблемах параллельности оборудование сервера СУБД бывает недогружено, и рекомендации будут прямо противоположны: ■■ делать апгрейд оборудования при проблемах параллельности – плохая идея; ■■ ускорение оборудования, скажем, на 30 % приведет к уменьшению времени ожидания в очереди на те же 30 %. А устранение очереди (распараллеливание работы) ускорит процесс в N раз, где N – количество участников очереди. То есть эффект несопоставимый. Чтобы бороться с таймаутами, нужно выяснить, какая из перечисленных выше причин привела в данном случае к таймаутам, и либо устранить эту причину, либо перевести ее в приемлемые рамки. ■■ Надо иметь в виду, что, убрав избыточные блокировки (и избавившись от таймаутов), мы увеличиваем параллельность работы и как следствие можем увеличить загрузку оборудования. То есть если раньше оборудование справлялось, то теперь могут возникнуть проблемы. Взаимоблокировка (deadlock) Взаимоблокировка возникает, когда две или более транзакции ждут друг друга из-за того, что каждая из сторон блокирует ресурс, необходимый другой стороне. Иначе говоря, сущность взаимоблокировок в следующем: Светочка ждет Леночку, а Леночка ждет Светочку. Замкнутый круг. Решается только принудительным внешним воздействием. В СУБД это воздействие происходит так: при обнаружении взаимоблокировки монитор блокировок назначает жертву, производит откат ее транзакции и возвращает приложению ошибку. Остальные транзакции имеют возможность успешно завершиться. 62 Настольная книга 1С:Эксперта по технологическим вопросам Возникновение взаимоблокировок сводят к следующим ситуациям. 1. Захват ресурсов в разном порядке. X1 -> X2, X2-> X1. Светочке сказали: распишись сначала в договоре, потом в приложении и потом отдай оба листа. Леночке сказали несколько иначе: распишись сначала в приложении, потом в договоре и потом отдай оба листа. Если девушки будут работать по очереди, ничего страшного не произойдет. Если же они начнут работать одновременно, то ни одна из них не сможет завершить задачу: им не сказано «отдавать один лист», сказано – «отдать оба»26.20 В такой постановке это в чистом виде ошибка организации работы. Исправляется она организацией доступа к ресурсам в одинаковом порядке. Переходя к «1С», если есть такие подозрения, порядок доступа можно проверить (без использования ЦУП), например, через подписку на событие ПриЗаписи наборов записей всех регистров, тем или иным образом выводя сообщения об имени регистра, в который идет запись, и сравнивая последовательно записанные протоколы для разных типов документов. Особый случай этой же ситуации: чтение общей области после раздельной записи. X1 -> S12, X2 ->S12. Светочке сказали: распишись в договоре, потом прочитай и отдай оба листа. Леночке сказали: распишись в приложении, потом прочитай и отдай оба листа. Леночка и Светочка изменяют разные документы. Но потом им требуются ресурсы друг друга, как правило, объединенные вместе. В системах на платформе «1С:Предприятие» эти взаимоблокировки стали часто возникать после появления технологии разделения итогов, и происходит это чаще всего в двух случаях: □□ Проведение документа, контроль остатков после записи движений. Если разделение итогов включено, то запись движений осуществляется с учетом сплиттера (разделителя итогов, не путать с разделителем данных), и поэтому может производиться параллельно, даже при полностью совпадающих значениях периода, счета и измерений (рассматриваем регистр бухгалтерии). Но при контроле остатков сплиттер смысла не имеет, то есть считываются все итоги по данным значениям периода, счета и измерений. И получаем ту самую взаимоблокировку, описанную в примере. □□ Перепроведение документа, контроль остатков или другое чтение (расчет себестоимости списания) до записи движений или после него, не важно. Если разделение итогов включено, то запись движений при их удалении осуществляется с учетом сплиттера. Дальнейшее чтение приводит к взаимоблокировке. 26 Отличие работы СУБД от этого и следующих примеров состоит в том, что в СУБД транзакция, назначенная жертвой, откатывается, то есть девушке пришлось бы стереть свои изменения или подпись. Теория 63 В этом случае с взаимоблокировкой надо бороться с помощью свойства БлокироватьДляИзменения, которое есть у наборов записей регистров бухгалтерии и регистров накопления. Пример использования: Движения.Хозрасчетный.БлокироватьДляИзменения = Истина; Движения.Хозрасчетный.Записать(); 2. Согласно синтакс-помощнику установка этого свойства в Истину: «Устанавливает режим, при котором в процессе записи набора будет установлена управляемая блокировка для всех комбинаций измерений в соответствии с записями набора записей. Имеет смысл использовать, если проверка итогов регистра выполняется после записи и заблокировать нужно именно те комбинации, по которым записываются записи. В этом случае можно не использовать объект БлокировкаДанных». Особо обращаем внимание на то, что технически работа свойства БлокироватьДляИзменения реализована с помощью установки управляемой блокировки. В автоматическом режиме управления блокировками попытка использования БлокироватьДляИзменения не игнорируется (в отличие от ДЛЯ ИЗМЕНЕНИЯ в управляемом режиме), а приводит к исключительной ситуации. При этом разделитель итогов на уровне СУБД работает, т. е. возможна параллельная запись совпадающих наборов. Но дальше, если на самом деле имеет место высокая конкуренция за одни и те же данные (неправильная организация рабочего процесса или выбор неправильного прикладного объекта метаданных конфигурации для хранения данных), взаимоблокировка, вполне вероятно, превратится в таймаут. Однако на этом все не заканчивается. На другой день Светочка и Леночка изменяют каждая только свои документы. И каждая из них хочет принести начальнику на проверку всю стопку (обе собираются установить избыточную блокировку – не важно, исключительную или разделяемую). Такая взаимоблокировка может быть вызвана неоптимальной работой запроса на чтение. Неоптимальная работа запроса может быть вызвана как методическими ошибками, допущенными при его написании, так и спровоцирована, например, использованием механизмов, приводящих к появлению неоптимальных запросов, даже если сам запрос написан без явных ошибок (см. в этой главе ниже). Повышение уровня блокировки ресурса. S1 -> X1, S1-> X1. Светочка подошла к столу и начала читать документ. Сразу за этим к столу подошла Леночка и начала читать тот же документ. Светочка увидела, что ей надо внести в этот документ изменения, и хотела было его унести к себе, но Леночка ей не дала: она еще его не дочитала. А затем и Леночка увидела, что ей тоже надо внести в этот документ изменения, и тоже хотела было его унести к себе, но теперь уже Светочка не дала ей этого сделать. Эта ситуация, когда один и тот же ресурс блокируется сначала разделяемой блокировкой, а затем исключительной, и при параллельном обращении к этому ресурсу возникает взаимоблокировка, характерна для режима автоматического 64 Настольная книга 1С:Эксперта по технологическим вопросам управления блокировками «1С». В этом режиме используются уровни изоляции транзакции Serializable и Repeatable Read, и разделяемые блокировки не снимаются после чтения, а остаются до конца транзакции. Но и в управляемом режиме можно получить тот же эффект, поставив явную разделяемую блокировку на данные, на которые затем явно или неявно будет установлена исключительная блокировка. Для обхода этой взаимоблокировки в SQL Server был введен особый уровень блокировки: U (Update), см. раздел 3.7. Этот уровень совместим только с разделяемыми блокировками S, но сам с собой уже нет. Чтобы его задействовать, в запрос на языке запросов «1С» необходимо добавить опцию ДЛЯ ИЗМЕНЕНИЯ, при этом не забыв указать, какие таблицы блокировать, иначе запрос поставит эту блокировку на все таблицы, задействованные в нем. Если такая взаимоблокировка возникла на блокировках «1С», то перед чтением данных ресурса, в который потом будет идти запись, нужно ставить исключительную блокировку. Если разделяемая блокировка ставится явно и чтение производится на языке запросов, а не через объектную модель, нужно заменить ее сразу на исключительную блокировку. Для устранения взаимоблокировок нужно придерживаться следующих правил: □□ осуществлять запись ресурсов в одинаковом порядке; □□ избегать чтения ресурса после его записи, если включен режим разделения итогов; либо, если этого нельзя избежать, на время записи устанавливать свойство БлокироватьДляИзменения в Истину; □□ в режиме автоматического управления блокировками «1С» в запросах включать опцию ДЛЯ ИЗМЕНЕНИЯ на те ресурсы, которые будут потом записаны; □□ если есть необходимость поставить управляемую блокировку «1С» перед чтением данных ресурса, в который потом будет идти запись, нужно ставить не разделяемую блокировку, а исключительную. Далее, как и в случаях борьбы с таймаутами, помогает следующее: □□ правильная организация рабочего процесса (снижение конкуренции за одни и те же данные организационными мероприятиями); □□ выбор более подходящего прикладного объекта метаданных конфигурации для хранения данных (см. раздел 3.11); □□ правильная организация работы ресурсов, в которые возможна только последовательная запись, см. раздел 3.11; □□ оптимизация запросов, ликвидация избыточных блокировок и уменьшение времени выполнения самих этих запросов; □□ отказ от использования механизмов, провоцирующих неоптимальную работу запросов: это механизм разделения доступа на уровне записей при работе пользователя с ограниченными правами и механизм разделения данных при работе пользователя с незаданным общим реквизитом, если указано использование разделяемых данных «Независимо и совместно»; Теория 65 □□ снижение уровня изоляции транзакций (т. е. переход с режима автоматического управления блокировками «1С» на управляемый). Это, с одной стороны, уменьшит блокирование избыточных данных (снимется защита диапазона ключей), а с другой стороны, уменьшит время блокировки части ресурсов, т. к. все разделяемые блокировки будут сняты после выполнения запроса; □□ использование Read Committed Snapshot (при работе с SQL Server переход на платформу 8.3 без режима совместимости с 8.2). Разделяемые блокировки на уровне СУБД не будут ставиться вовсе; □□ отказ от включения в транзакцию механизмов, вызывающих непрогнозируемое увеличение ее времени и ставящих ее в зависимость от посторонних ресурсов (модальные окна, работа с внешними источниками, вложенные транзакции); □□ отказ от ошибочного рекурсивного вызова ЭтотОбъект.Записать() из транзакции записи этого же объекта. Платформа распознает такую ситуацию и не дает развиваться рекурсии, но ошибки блокировок при этом возникать могут; □□ снижение времени транзакции, как за счет оптимизации работы кода, так и за счет объединения нескольких транзакций в одну (например, групповая обработка документов в одной транзакции); □□ повышение производительности оборудования позволяет снизить вероятность взаимоблокировок, при этом, однако, не устраняя их причин. К сожалению, все это не гарантирует, что взаимоблокировок не будет. Нет методики, которая даст 100 % гарантию их отсутствия. Поэтому нужно уметь расследовать и устранять взаимоблокировки. В заключение еще об одном виде взаимоблокировок. Они могут возникать в СУБД Microsoft SQL Server и характеризуются следующими сообщениями об ошибке: "Intra-query parallelism caused your server command (process ID #XX) to deadlock. Rerun the query without intra-query parallelism by using the query hint option (maxdop 1)"; ■■ "Transaction (Process ID #XX) was deadlocked on thread communication buffer resources with another process and has been chosen as the deadlock victim". Причиной является то, что при работе на многопроцессорном компьютере Microsoft SQL Server может попытаться распараллелить процесс выполнения запроса на несколько процессоров. Обычно это происходит в том случае, если план запроса неоптимален. При параллельном выполнении нескольких частей одного запроса на разных процессорах возможна взаимоблокировка. Для решения проблемы необходимо установить значение параметра max degree of parallelism («Максимальная степень параллелизма») равным 1 ‑ SQL Management studio, свойства SQL server, закладка Дополнительно. Другим способом решения проблемы является оптимизация исполняемого запроса. ■■ Взаимоблокировки имеют характерную особенность поведения: при высокой интенсивности работы они появляются большими группами – по пять-шесть штук подряд. Это связано с тем, что, когда две транзакции зацепились, об них спотыкаются еще несколько, и образуется куча-мала. Значимость ЦУП для расследования подобных ситуаций переоценить сложно. 66 Настольная книга 1С:Эксперта по технологическим вопросам 3.10. Эскалация блокировок Эскалация (укрупнение) блокировок – это повышение гранулярности блокировки (lock granularity, в некоторых источниках – lock level, «уровень блокируемых данных»). Это процесс преобразования многих мелкогранулированных блокировок в меньшее число крупногранулированных блокировок при вероятном увеличении конкуренции параллелизма. Гранулярность – это объем (уровень в иерархии) ресурсов, на который накладывается блокировка. Упрощенно можно считать, что существуют следующие ресурсы, которые могут блокироваться СУБД27:21 строка: используется в управляемом режиме управления блокировками; ■■ ключ: блокировка строки в индексе, используемая для защиты диапазонов значений ключа в транзакциях с уровнем изоляции Serializable, используется в автоматическом режиме управления блокировками при работе с регистрами; ■■ страница; ■■ таблица; ■■ база (монопольный режим). Не важно, блокировались данные на уровне записей (строк), на уровне диапазона ключа или на уровне страницы. После эскалации они окажутся заблокированы на уровне таблицы, т. е. эскалация всегда происходит до уровня таблицы. ■■ Эскалация происходит, когда система решает, что заблокировать сразу более высокий уровень данных дешевле, чем продолжать набирать большое количество блокировок на нижнем уровне. Эскалация определяется, например, по наличию в трассировке профайлера SQL Server события Lock:Escalation (в стандартном шаблоне трассировки этого события нет, и его надо добавлять, а находится оно в группе событий Locks), см. главу «Инструкции», раздел 4.15. Перевод блокировки данных на уровень таблицы не позволит другим транзакциям параллельно работать с теми же данными. Она почти всегда избыточна, и это может привести к конфликтам блокировок, поэтому надо понимать, при каких условиях возникает эскалация. Эксперименты показывали, что в SQL server с установками по умолчанию эскалация блокировки начиналась примерно при 3 400–4 800 записях в наборе непериодического независимого регистра сведений (точное значение не установлено). В IBM DB2 9.7 она начиналась ровно при 20 000 записях. Платформа «1С:Предприятие» до версии 8.3 производила эскалацию, также начиная с 20 000 записей, а в версии 8.3, по данным с ИТС, она начинается со 100 000 записей в наборе. 27 Эскалации бывают на СУБД и в менеджере управляемых блокировок. Их поведение различно. Различие состоит в том, что если в момент попытки эскалации на СУБД MS SQL кто-то другой будет держать блокировку, то эскалации не произойдет, но при этом транзакция дальше продолжит свое выполнение. Если в «1С» кто-то другой будет держать блокировку, то «эскалирующаяся» транзакция попадет в ожидание от всех, кто еще держит блокировки на этом ресурсе. Если в «1С» не получится проэскалироваться в течение N (по умолчанию 20) секунд, то транзакция получит таймаут. Теория 67 Момент, когда это происходит, в SQL server регулируется значением параметра Locks («Блокировки») – SQL Management studio, свойства SQL server, закладка Дополнительно – и зависит от доступной памяти. Также эскалация SQL server может быть отключена. Если отключать ее, то глобально28, с помощью флага трассировки SQL 1211, например, выполнив следующий SQL запрос:22 DBCC TRACEON (1211, -1) Но если ее отключить, то накладные расходы останутся бесконтрольными, и значительная часть вычислительной мощности, возможно, будет расходоваться непроизводительно. Это может привести к очень заметному замедлению записи. Наличие технической возможности по отключению эскалацию отнюдь не означает, что этим надо пользоваться. СУБД делает эскалацию не от хорошей жизни. Это жест отчаянья. СУБД видит, что пользователи открыли огромные транзакции, и сама она тратит очень много ресурсов. Проблема не в СУБД, а в том, что транзакции захватывают слишком много ресурсов. Лечить надо именно это, а не отключать эскалации. В идеале транзакция должна быть крайне компактной – работать быстро, данных захватывать мало. Транзакция, которая длится 3 секунды, – это уже подозрительно. Транзакция на 10 секунд просто не должна иметь права на существование. Включить эскалацию обратно можно, деактивировав флажок 1211: DBCC TRACEОFF (1211, -1) На практике можно считать, что при использовании MS SQL Server документ «1С», имеющий свыше 1 000 строк в табличной части либо делающий свыше 1 000 движений по одному регистру, теоретически может при своем проведении вызывать эскалацию блокировок, поэтому при прочих равных условиях наличие больших документов – это потенциальная проблема параллельности работы. Это не значит, что такие документы нельзя провести. Просто нужно делать это не средствами платформы, а своим кодом – в нескольких относительно небольших транзакциях, обеспечив неделимость (атомарность) операции внешними средствами. 28 Если активация флага трассировки выполняется глобально на рабочем сервере, то выполнять DBCC TRACEON (trace# [, ....n],-1), чтобы избежать непредсказуемых последствий, рекомендуется только тогда, когда пользователи не выполняют запросов к серверу (фактически когда никто не работает). На рабочем сервере надежнее эти флаги включать, используя в командной строке параметр -T при запуске файла Sqlservr.exe. 68 Настольная книга 1С:Эксперта по технологическим вопросам 3.11. Сведения о параллельности операций с данными разных типов Общие сведения Система позволяет осуществлять параллельное чтение и параллельную запись данных. Разные типы данных имеют разные возможности и ограничения по параллельному выполнению операций чтения и записи с ними. Сразу скажем, что поскольку данные, относящиеся в информационной базе «1С» к разным прикладным объектам конфигурации, хранятся в разных таблицах (как именно организовано хранение, будет рассказано в следующей главе), будем считать, что такие записи могут быть прочитаны и записаны параллельно всегда. Операция чтения в транзакции сложностей также не вызывает: даже при уровне изоляции транзакции Serializable при чтении устанавливается разделяемая блокировка, а потому даже совпадающие записи одной таблицы могут быть прочитаны параллельно. К сложным ситуациям, когда в одной транзакции выполняются чтение и запись и когда в одной транзакции осуществляется запись в несколько разных прикладных объектов конфигурации, вернемся позднее. А сейчас разберем возможность только записи данных, относящихся к одному прикладному объекту (см. таблицу 3.11.1). Таблица 3.11.1. Сводные данные о параллельности Прикладной объект конфигурации Константы в версиях до 8.2.14, а также после – при использовании режимов совместимости «8.2.13» и «8.1» Константы после 8.2.14 (без использования режима совместимости) Возможности параллельной работы Только последовательно, притом даже разные константы Одну и ту же константу – только последовательно, но разные константы можно записывать параллельно Выгрузка сообщений обмена Выгрузка изменений, которые зарегистрированы для прикладного объекта метаданных (например, справочника «Номенклатура»), и запись данных такого типа НЕ могут происходить параллельно Набор записей регистра расчета с использованием Возможна параллельная запись, если отличафактического периода действия ется период действия (месяц) или измерение, у которого стоит признак «базовое». Уточнение по данному вопросу см. ниже Граница регистрации последовательности Возможна параллельная запись, если отличается хотя бы одно измерение. На практике, однако, измерение, как правило, у всех совпадает («Организация») Набор записей регистра сведений (независимый Возможна параллельная запись, если отличанепериодический) ется хотя бы одно измерение Набор записей регистра накопления (остатков), если Возможна параллельная запись, если отличаразделение итогов выключено и используются текущие ется хотя бы одно измерение, уточнение про итоги период см. ниже Набор записей регистра бухгалтерии, если разделение Возможна параллельная запись, если итогов выключено и используются текущие итоги отличается счет или хотя бы одно измерение, уточнение про период см. ниже Набор записей регистра сведений (независимый Возможна параллельная запись, если периодический) отличается период (месяц) или хотя бы одно измерение Теория Прикладной объект конфигурации Набор записей регистра накопления (остатков), если разделение итогов выключено, а текущие итоги не используются Набор записей регистра бухгалтерии, если разделение итогов выключено, а текущие итоги не используются 69 Возможности параллельной работы Возможна параллельная запись, если отличается хотя бы одно измерение, уточнение про период см. ниже Возможна параллельная запись, если отличается счет или хотя бы одно измерение, уточнение про период см. ниже Набор записей регистра накопления (оборотов), если Возможна параллельная запись, если разделение итогов выключено отличается период (месяц) или хотя бы одно измерение Набор записей регистра расчета без использования Возможна параллельная запись наборов фактического периода действия с разными регистраторами Набор записей регистра сведений (подчиненный Возможна параллельная запись наборов регистратору) с разными регистраторами Элементы объектных типов: справочников, документов, Возможна параллельная запись разных планов видов характеристик, планов счетов (т. е. счета), объектов, принадлежащих к одному типу планов видов расчета, бизнес-процессов, задач, планов обмена (т. е. узлы обмена) Набор записей регистра накопления (остатков) при Возможна параллельная запись разрешенном и включенном режиме разделения итогов Набор записей регистра накопления (оборотов) при Возможна параллельная запись разрешенном и включенном режиме разделения итогов Набор записей регистра бухгалтерии при разрешенном Возможна параллельная запись и включенном режиме разделения итогов Этим, однако, дело не вполне ограничивается. В автоматическом режиме управления блокировкой данных, когда используется уровень изоляции Serializable, сервером СУБД добавляется блокировка Key-range, которая защищает диапазон строк, считываемый запросом, т. е. запрещает другим транзакциям вставлять в него строки, при этом также блокируются данные, соседние с диапазоном модифицируемых записей. В результате конфликтов на границах диапазонов реальная параллельность записи может быть ниже, чем указано в таблице, т. е., записи, которые теоретически должны бы записываться параллельно, могут не записаться. В управляемом режиме управления блокировкой данных такой проблемы нет. Но в управляемом режиме существует другая проблема. Сведения по параллельности, приведенные в таблице 3.11.1, изначально (начиная с книги «Профессиональная разработка...») собирались по сведениям о параллельности для СУБД и не учитывали установки управляемых блокировок «1С» и принятия платформой решений о допустимости или недопустимости параллельной записи на их основе. Вопрос параллельности по периоду при включении и отключении текущих итогов в регистрах накопления (остатков) и регистрах бухгалтерии регулируется управляемыми блокировками «1С». Понятно, что установка управляемых блокировок параллельность улучшить не может, только снизить. Это и происходит с параллельностью по периоду в управляемом режиме, причем поведение системы в этом вопросе зависит от версии платформы и от установленного режима совместимости. В автоматическом режиме возможна параллельная запись, если отличается период (месяц) при любом режиме текущих итогов. Проблема эскалации блокировок рассматривалась в разделе 3.10. Если происходит эскалация, то параллельная работа с такой таблицей становится невозможной. 70 Настольная книга 1С:Эксперта по технологическим вопросам Узкие места Более подробно укажем узкие места и возможные решения проблем для самых тяжелых ситуаций. 1. Константы. До версии 8.2.14 узким местом была таблица констант целиком. Все значения констант, определенных в конфигурации, хранились в одной таблице. Начиная с версии 8.2.14 на каждую константу имеется собственная таблица, если не используется режим совместимости. Это позволяет записывать разные константы параллельно, но обычно проблема ошибочно написанного кода кроется как раз не в этом, а в том, что такой код пытается менять одну и ту же константу в разных сеансах, чего и новая структура делать тоже не позволяет. Назначение констант – хранить условно постоянные (очень редко изменяемые) данные, что следует из их названия. Общая рекомендация: не использовать константы для хранения данных, которые меняются чаще, чем раз в полгода, и никогда не использовать их для хранения быстро меняющихся данных (например, счетчиков). Причины ошибок блокировок, возникающих при неправильном использовании констант, диагностируются обычно очень просто: контекст кода, содержащий Константы.<имя>. Установить(...), будет виден в технологическом журнале, если настроить этот журнал, как указано в разделе 4.5. 2. Граница регистрации последовательности. Данные каждой последовательности хранятся в двух таблицах: таблица записей регистрации документов в последовательности, ■■ таблица границ последовательности. Как происходит блокировка в этих таблицах при работе с последовательностями в клиент-серверном варианте работы, указано в таблице 3.11.2. В файловом варианте при выполнении любого из перечисленных ниже действий таблицы блокируются целиком. ■■ Таблица 3.11.2. Блокировка данных при работе с последовательностями Действие Регистрация документа в последовательности Перемещение границы назад Перемещение границы вперед Что блокируется Таблица записей регистрации документов Таблица границ последовательности в последовательности Диапазон записей, соответствующий одному регистратору (в автом. режиме управления блокировками – еще две «соседние») ‑ ‑ По комбинации измерений последовательности. Если измерений нет – таблица целиком Диапазон от границы последовательПо комбинации измерений послености по момент времени регистрации довательности. Если измерений проводимого документа (с учетом нет – таблица целиком измерений последовательности) Судя по таблице, для последовательностей вроде бы существует возможность параллельного перемещения границы, которая достигается использованием измерений. Но в реальности сам смысл последовательностей очень часто либо не предполагает использования измерений вообще, либо предполагает использование единственного измерения «Организация», чего совершенно недостаточно для полноценной параллельной работы. Теория 71 Как видно по таблице, регистрация документов в последовательности не несет вреда, а проблемной операцией является любое перемещение границы последовательности – как назад (узкое место – таблица границ последовательности), так и вперед (узким местом может быть любая из двух таблиц). Поэтому неправильно перемещать границу последовательности при проведении документов, перемещение должно происходить, например, регламентным заданием или служебной обработкой либо в нерабочее время, либо очень маленькими порциями, но очень часто, и, что важно, заниматься этим может одно рабочее место, никому не мешая.23 При этом не следует путать обработку по такому служебному перемещению границ с собственно восстановлением последовательности документов – это разные вещи29. То, что ошибки блокировок возникают из-за автоматической регистрации документов в последовательностях, обычно сразу диагностируется по факту наличия таблиц с данными последовательностей в числе заблокированных. 3. Выгрузка сообщений обмена. Если для объекта (речь об объекте метаданных, например, Справочник.Номенклатура (целиком!)) включена регистрация изменений для обмена, к нему добавляется еще одна таблица: таблица регистрации изменений. Эта таблица всегда одна на каждый прикладной объект, для которого возможна регистрация изменений, вне зависимости от количества планов обмена, а также от того факта, имеем мы дело с распределенной базой или нет. Когда происходит выгрузка сообщений обмена, эта таблица блокируется для того, чтобы, пока данные выгружаются, никто не мог внести незарегистрированное изменение. То есть, пока мы выгружаем справочник Номенклатура, он целиком заблокирован, и тот факт, что заблокирована не основная таблица, а служебная, дела не меняет. Понятно, что при таком поведении системы говорить о возможности параллельной работы при выгрузке практически не приходится. Поэтому выгрузку сообщений обмена рекомендуется проводить либо в нерабочее время, либо очень часто, так, чтобы за прошедшее с момента выгрузки время в системе не успевал накопиться объем измененных данных, выгрузка которого могла бы занимать сколь-нибудь существенное время. Что касается загрузки сообщений обмена, она, в отличие от выгрузки, по своему характеру не является настолько узким местом и по создаваемым проблемам сопоставима с групповой обработкой справочников и документов.24 В завершение еще один очень важный момент. И у загрузки, и у выгрузки обычно (в типовых решениях – обязательно) есть параметр «Количество элементов в транзакции». Если речь не идет о совсем простых случаях, не рекомендуется ставить значение этого параметра равным 0, то есть вся выгрузка, как и вся загрузка, совершенно точно не должна проходить в одной транзакции30. Значение этого 29 30 А также не следует путать автоматическое перемещение границы при проведении (регулируется в свойствах последовательностей) и автоматическую регистрацию документах в последовательности (регулируется в свойствах документов). Приносим извинения читателям за ошибку в первом издании. Возможно, внешними по отношению к штатному транзакционному механизму средствами потребуется контролировать, что отработали все транзакции, и обеспечить целостность суммарных изменений, вносимых ими. Также иногда для обработок, состоящих из множества транзакций, есть смысл делать некоторую программную паузу между транзакциями. 72 Настольная книга 1С:Эксперта по технологическим вопросам параметра подбирается опытным путем, на практике нормально себя зарекомендовали значения от 1 до 100. 4. Набор записей регистра расчета с использованием фактического периода действия. По данному вопросу приходилось слушать и читать полярные мнения: от того, что запись наборов записей регистра расчета с использованием фактического периода действия возможна только последовательно, до того, что запись этих наборов допускает параллельность по периоду и всем измерениям. Практический опыт показал, что существуют решения, допускающие параллельную запись, если отличается период действия (месяц, к которому он относится) или измерение, у которого стоит признак «базовое». Примером такого решения может служить конфигурация «Зарплата и кадры бюджетного учреждения», редакция 1.0 и решения на ее основе. И поскольку признак «базовое» стоит у измерения «Сотрудник», реальную параллельность записи в такой конфигурации можно оценивать как высокую. 5. Набор записей регистра бухгалтерии. Если говорить только о записи в регистр бухгалтерии, следует отметить, что при прочих равных условиях скорость и параллельность записи в регистр бухгалтерии гораздо ниже, чем в регистры накопления. Например, при использовании бухгалтерского регистра работа по расчетам с покупателями возможна по одной организации только последовательная: есть всего два счета – 62.01 и 62.02, и вся запись идет в них. Если для регистра бухгалтерии разрешено и включено разделение итогов, то запись движений осуществляется с учетом сплиттера (разделителя итогов) и поэтому может производиться параллельно, даже при полностью совпадающих значениях периода, счета и измерений.25 Но параллельность увеличивается для записи, не для чтения31. Что происходит, когда кроме записи есть чтение, уже описывалось выше, в разделе 3.9, в части, посвященной взаимоблокировкам. Если нужно осуществлять чтение, то разделитель итогов смысла не имеет, потому что читать надо все итоги по данным значениям периода, счета и измерений. Чтобы не получить взаимоблокировку, необходимо пользоваться свойством БлокироватьДляИзменения32, которое есть у набора записей регистра бухгалтерии (подробнее описано в разделе 3.9). Таким образом, если идет чтение остатков, разделитель итогов параллельность не увеличивает.26 Кроме того, бухгалтерские документы, а именно они обычно являются источником записей в регистр бухгалтерии, могут в реальности перепроводиться пользователями в хаотичном порядке. Про эффект такого подхода см. ниже, в описании транзакций Запись + Запись. Про нюансы перепроведения документов, связанные с разделением итогов, см. в разделе 3.9. 31 32 Замечание про чтение справедливо, если не используется Read Committed Snapshot. Необходимо помнить, что свойство БлокироватьДляИзменения реализовано с помощью установки управляемой блокировки в процессе записи набора, подробнее см. раздел 3.9. Теория 73 6. Набор записей регистра накопления. Когда разделение итогов выключено, при использовании регистра накопления есть гораздо больше возможностей организовать параллельную работу пользователей, чем при использовании регистра бухгалтерии – то, что было аналитическими разрезами (субконто), становится измерениями, и параллельная запись становится возможной там, где это было закрыто для регистра бухгалтерии. Нюансы работы, когда для регистра накопления разрешено и включено разделение итогов, полностью совпадают с аналогичными нюансами для регистра бухгалтерии, описанными выше, исключая наличие счета в регистрах накопления: разделитель перестанет увеличивать параллельность, если идет чтение остатков. Чтобы не получить взаимоблокировку, необходимо пользоваться свойством БлокироватьДляИзменения. Перепроведение документов для регистров накопления вызывает те же трудности, что и для регистра бухгалтерии. Реальные транзакции Запись + Запись Как правило, реальные транзакции содержат запросы на запись не только для одного объекта или только для одного набора записей, а для нескольких. И каждая новая блокировка уменьшает возможности по параллельной работе. Поэтому возможности параллельного выполнения транзакций определяются, во-первых, самой низкой возможностью из числа прикладных объектов конфигурации, запись которых в данной транзакции осуществляется, а во-вторых, конкретными (наихудшими) условиями записи конкретных объектов или наборов записей. Говоря проще, если в транзакции кроме прочего меняется значение константы или допускается эскалация блокировок на регистре бухгалтерии, этим сводятся на нет все возможности параллельной работы для прочих объектов метаданных, записываемых в той же транзакции. Существует хорошая рекомендация осуществлять запись движений и контроль остатков как можно ближе к концу транзакции. Она, однако, теряет смысл, когда документы разрешается перепроводить, но при этом никогда не выполняется анализ, надо ли очищать движения и записывать новые. В такой ситуации всегда имеет место установка исключительной блокировки на ресурсы практически в самом начале транзакции. Реальные транзакции Чтение + Запись3327 Про нюансы работы режима, когда в регистре бухгалтерии или в регистре накопления разрешено и включено разделение итогов, говорилось выше. Но этот механизм работает так, как было описано, даже когда речь идет не об избыточных блокировках, а о необходимых. Далее же речь пойдет именно об избыточных блокировках. Потому что, в отличие от запросов на запись, при написании запросов на чтение у разработчика прикладного решения (конфигурации) есть много возможностей поставить избыточные блокировки. Как говорилось ранее в разделе 3.9, посвященном ошибкам 33 Если вы используете уровень изоляции Read Committed Snapshot (8.3 без режима совместимости + MS SQL Server 2005 и старше), вы можете забыть про сложности с разделяемыми блокировками СУБД, они не устанавливаются. 74 Настольная книга 1С:Эксперта по технологическим вопросам блокировок, это приводит к таким ошибкам даже тогда, когда запись может осуществляться и осуществляется параллельно. Далее, как отмечалось там же, работа некоторых механизмов «1С» приводит к избыточным блокировкам именно, точнее чаще, при чтении. 1. Разделение доступа к данным на уровне записей. RLS – Record Level Security. При этом каждая новая роль, содержащая ограничение, добавляет к каждому запросу к базе, содержащему реквизит, по которому идет разделение, свое соединение в соответствии с дополнительным запросом, написанным в конфигураторе (в типовых конфигураций их обычно размещают в шаблонах ролей). Пример такого запроса приведен на рис. 3.11.1. В итоге каждый запрос отличается от «чистого» запроса тех же данных. Поскольку ограничение чаще устанавливается на чтение, а на запись реже (но тоже иногда встречается), то частая ситуация – запрос на чтение отличается от «чистого» запроса, а запрос на запись соответствует «чистому»34. 28 Если &ИспользоватьОграничениеПоОрганизации #Тогда ТекущаяТаблица ИЗ #ТекущаяТаблица КАК ТекущаяТаблица ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РАЗЛИЧНЫЕ СоставГруппы.Ссылка КАК ГруппаПользователей ИЗ Справочник.ГруппыПользователей.ПользователиГруппы КАК СоставГруппы ГДЕ СоставГруппы.Пользователь = &ТекущийПользователь) КАК ГруппыПользователей ПО (ИСТИНА) ГДЕ НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL И (НЕ 1 В (ВЫБРАТЬ ПЕРВЫЕ 1 1 ИЗ РегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступа ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей ПО НастройкиПравДоступаПользователей.ОбъектДоступа = ТекущаяТаблица.#Параметр(1) И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа И НастройкиПравДоступаПользователей.ОбластьДанных = ЗНАЧЕНИЕ( Перечисление.ОбластиДанныхОбъектовДоступа.ПустаяСсылка) И НастройкиПравДоступаПользователей.Пользователь = ГруппыПользователей.ГруппаПользователей ГДЕ НазначениеВидовОбъектовДоступа.ГруппаПользователей = ГруппыПользователей.ГруппаПользователей И НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа В ( ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)) И НастройкиПравДоступаПользователей.ОбъектДоступа ЕСТЬ NULL)) #КонецЕсли Рис. 3.11.1. Пример запроса, дописываемого к основному подсистемой RLS. 1С:УПП 1.3.39.1, роль «Бухгалтер МСФО», ограничение чтения по организации (для указанной роли, в частности, используется на регистр бухгалтерии «Хозрасчетный») 34 Примечание ко второму изданию: на текущий момент работу механизма RLS можно отследить в профайлере по наличию характерных конструкций в тексте запроса, в частности, по наличию «SDBL_DUMMY». Мы, разумеется, не готовы утверждать, что так было всегда и что это будет продолжаться и дальше, но сейчас это так. Теория 75 Такие дописываемые запросы осложняют жизнь не только тем, что приходится получать дополнительные данные, и даже, можно сказать, что совсем не тем. Основная проблема, которую они создают, состоит в том, что наличие подобных соединений очень сильно мешает использовать поиск по индексу и очень часто приводит к сканированию индекса или таблицы, то есть и к избыточным блокировкам, и к увеличению длительности выполнения запросов. Вспомним Светочку с Леночкой из раздела 3.9. Для борьбы за повышение производительности труда бумажные документы, с которыми работали Светочка и Леночка, «проиндексировали». Для этого, во-первых, документы стали класть в пластиковые файлы отдельного цвета, в зависимости от того, за какой месяц документ; во-вторых, цветной скрепкой стали обозначать, к какой организации документ относится (периодический регистр сведений с одним измерением или регистр накопления с одним измерением). После этого стало достаточно давать каждой из девушек задания по работе со своими отдельными организациями, и работа наладилась (возможность параллельной работы). Однако систему решили улучшить: работу с документами решили не только регулировать заданием, но и ограничением доступа. В один прекрасный день Светочка получила следующее задание: «обработать документы за сентябрь (пластиковые файлы красного цвета) по организации «А-один» (синяя скрепка), учтя при этом, что она может работать только с документами организаций «А-один» и «Б-два» (красная скрепка)». Леночка получила задание: «обработать документы за сентябрь (пластиковые файлы красного цвета) по организации «В-три» (зеленая скрепка), учтя при этом, что она может работать только с документами организаций «В-три» и «Г-четыре» (желтая скрепка)». Девушки напряглись. Светочка смогла сопоставить второе условие с третьим и сразу взяла только красные файлы с синей скрепкой. Леночка не смогла. Она сначала взяла красные файлы с зелеными и желтыми скрепками, но почти сразу файлы с желтыми скрепками вернула на место (избыточная блокировка на чтение, не приведшая к конфликту). Поскольку обе девушки выполнили работу, эксперимент был признан удачным, и вскоре его распространили на всю фирму. Придя на работу, Светочка получила следующее задание: «обработать документы за сентябрь (пластиковые файлы красного цвета) по организации «А-один» (синяя скрепка), учтя при этом, что список ограничений (организаций, контрагентов, видов документов и др.), с которыми она может работать, висит на стенде в административном здании». Периодов (месяцев) в качестве ограничений указано не было. Кроме того, все файлы были отсортированы по цветам, и пластиковые файлы красного цвета лежали рядом (кластерный индекс). Что это за условия, Светочка не знала, и сможет ли она их запомнить, сомневалась. Поэтому она, не задумываясь, взяла все красные файлы, пошла с ними в административный корпус, там прочитала условие и, постоянно с ним сверяясь, выбрала по нему те документы, с которыми ей можно работать, из них выбрала файлы с синей скрепкой, остальные вернула на место. 76 Настольная книга 1С:Эксперта по технологическим вопросам Леночка это видела. Она заметила, что вся эта операция не заняла особенно много времени и что ходить в административный корпус Светочке пришлось только один раз. Поэтому она решила применить ту же самую тактику. Одна незадача: ее тоже попросили обработать документы за сентябрь (пластиковые файлы красного цвета), хотя и по другой организации. Но поскольку Леночке согласно ее тактике для проверки условий требовались все документы из красных файлов (попытка установить избыточную блокировку на чтение), она их снова так и не дождалась и ушла в шесть вечера домой, так и не начав работать (таймаут). Данный пример, кроме иллюстрации возникновения избыточной блокировки при чтении, использующем ограничения на уровне записей, демонстрирует еще одну закономерность. Чем более сложные и универсальные механизмы ограничения доступа строятся, тем менее следует надеяться, что оптимизатор СУБД распознает эти ограничения как имеющиеся у таблиц индексированные поля, хотя бы они и были таковыми, и тем выше вероятность, что будет иметь место сканирование индекса или таблицы. Одним из вариантов решения проблем, когда видно, что избыточные блокировки возникают именно при чтении и именно при работе RLS, может быть отключение RLS, притом только на время транзакции, с отработкой исключительной ситуации, например, следующим кодом35:29 ТекущееЗначениеПараметра = ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей; Попытка ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = Ложь; Запрос.Выполнить(); ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = ТекущееЗначениеПараметра; Исключение ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = ТекущееЗначениеПараметра; ВызватьИсключение; КонецПопытки; 2. Использование разделения данных. Сразу надо предупредить, что использование разделения данных для целей, приведенных ниже, нигде не рекомендовано. Напротив, пример приведен специально для предупреждения о возможных последствиях такого подхода. Рассмотрим частный и, повторим, заведомо ошибочный случай, когда разделение данных используется как разграничитель доступа по организациям. Ситуация поворачивается наоборот: теперь пользователь с максимальными полномочиями оказывается в проигрыше. 35 Пример взят из практики, в нем нормально отрабатываются случаи с ошибкой и разрывом соединения, потому что RLS отключается только на время одного запроса на чтение. Пример, однако, не идеален, он не будет корректно работать, в частности, в ситуации, когда в транзакции ранее уже была ошибка, заключенная в скобки «Попытка – Исключение», а Запрос.Выполнить() – первое чтение после этой ошибки, которое вернет сообщение «в данной транзакции уже происходили ошибки!». Лучше, хотя и не всегда проще, использовать привилегированный режим. Этот режим как раз существует для таких случаев, но в клиентсерверном варианте при выполнении на клиенте данный метод не выполняет никаких действий, и при работе с обычным приложением потребуются дополнительные усилия по переносу кода в серверные общие модули. Теория 77 Светочке и Леночке выделили по шкафу. Их документы теперь кладут только в эти шкафы. Девушкам не приходится ждать друг друга, они могут нормально работать. Но теперь проблемы начались у их начальника. Чтобы работать с документами, ему надо открыть и держать открытыми оба шкафа, он не может эффективно использовать поиск и брать стопку документов одним движением. Если использовать независимый разделитель, то ни у одного пользователя физически не будет доступа ко всем данным. Например, Светочка будет иметь доступ к документам организации «А-один», Леночка к документам организации «В-три», но невозможно будет создать роль, которая имела бы доступ ко всем документам. Если использовать независимый и совместный разделитель, то такая роль будет возможна. Появится возможность разрешить некоторым пользователям заходить в базу без указания значения разделителя, и эти пользователи будут видеть все данные. Но эффективной работы с этими данными не получится. Поскольку во всех индексах первым полем будет идти разделитель (точнее хеш-функция разделителей, см. раздел 3.13 «Сведения об индексах базы»), а пользователь с максимальными полномочиями будет работать без указания разделителя, то все запросы будут выполняться со сканированием: медленно и с избыточными блокировками. Это будет очень печально, потому что максимальные полномочия обычно предоставляют не рядовым пользователям, а наиболее толковым из них, а также начальству. И выйдет так, что именно у наиболее грамотных пользователей и у начальства запросы будут работать хуже. Как описывалось раньше, избыточные блокировки приведут к тому, что возможности параллельной работы транзакций серьезно уменьшатся36.30 3.12. Сведения о размещении данных. Способ получения этих сведений С самого начала этого раздела скажем, что сведения, приведенные в нем, совершенно не обязательно учить наизусть или носить с собой в виде шпаргалки. Чтобы не зависеть от особенностей базы, связанных с версией релиза, режимом совместимости и др., нужно просто помнить, что их всегда можно вызвать из вашей базы кодом: ТаблицаСоСтруктурой = ПолучитьСтруктуруХраненияБазыДанных(); ТаблицаСоСтруктурой.Сортировать("Метаданные, ИмяТаблицыХранения"); Функция глобального контекста ПолучитьСтруктуруХраненияБазыДанных() возвращает таблицу значений, доступна на сервере, в толстом клиенте и внешнем соединении. Полученную таблицу значений сразу есть смысл отсортировать и затем любым известным способом вывести на форму. Также можно просто посмотреть ее на останове в отладчике и сразу там же вывести в табличный документ, чтобы иметь все возможности и удобства по работе с полученным списком: поиск, сохранение и др. 36 Теоретически эта проблема может быть решена путем добавления индексов, таких же по составу, но без разделителя, если используется независимый и совместный разделитель. До реализации дело пока не дошло. 78 Настольная книга 1С:Эксперта по технологическим вопросам Создадим пустую базу37. В ней создадим три прикладных объекта: Константа1, Константа2 и Справочник1. Сохраним изменения в базе и посмотрим на ее структуру описанным выше способом (в таблице 3.12.1 приведены только интересующие нас столбцы). 31 Таблица 3.12.1. Имена таблиц, изначально созданных при организации с нуля базы с двумя константами и справочником Имя таблицы хранения Имя таблицы Метаданные "SystemSettings" "CommonSettings" "RepSettings" "" "" "" "" "" "" "RepVarSettings" "FrmDtSettings" "UsersWorkHistory" "Const8" "Const10" "Reference7" "" "" "" "" "" "Справочник. Справочник1" "" "" "" "Константа.Константа1" "Константа.Константа2" "Справочник.Справочник1" Назначение "ХранилищеСистемныхНастроек" "ХранилищеОбщихНастроек" "ХранилищеПользовательскихНастроекОтчетов" "ХранилищеВариантовОтчетов" "ХранилищеНастроекДанныхФорм" "ИсторияРаботыПользователей" "Константа" "Константа" "Основная" Мы работаем с релизом 8.2.18, без использования режима совместимости, поэтому каждая константа хранится в своей таблице. Если переключить режим совместимости, останется одна таблица, отвечающая за все константы38. 32 Как будут выглядеть эти таблицы, если на эту же базу в клиент-серверной версии «1С» посмотреть средствами SQL, показано на рис. 3.12.1. Рис. 3.12.1. Имена таблиц, изначально созданных файловой версией при создании с нуля базы с двумя константами и справочником после загрузки в клиент-серверную версию и просмотре через SQL Server Management Studio 37 38 Поведение в файловой и клиент-серверной версии должно быть одинаковым. При другом составе метаданных будут и другие изменения состава таблиц, возникшие вследствие изменения режима совместимости. Теория 79 Из приведенных выше таблицы 3.12.1 и рисунка 3.12.1 делаем выводы: 1. Функция глобального контекста ПолучитьСтруктуруХраненияБазыДанных() показывает не все таблицы (не показаны обязательные39 таблицы: Config, ConfigSafe и т. д.).33 2. Нам для решения практических задач по нашей теме и понимания структуры хранения данных вполне достаточно и того, что она показывает. 3. Названия таблиц в колонке ИмяТаблицыХранения и имена таблиц в СУБД сопоставимы. 4. Имя таблицы состоит из префикса и номера. По префиксу можно понять, что это за таблица (или посмотреть колонку Метаданные). Номер присваивается системой в сквозном порядке, но с пропусками. В предыдущей главе обсуждалась выгрузка сообщений обмена как узкое место при параллельной работе. Создадим план обмена и включим в него Константу2 и Справочник1, а Константу1 включать не будем. В таблице 3.12.2 видно, какие таблицы для каких объектов метаданных добавились. При добавлении еще одного плана обмена и включении регистрации в нем Константы2 и Справочника1 новые таблицы для них не появятся. В дальнейшем новые объекты включать в план обмена не будем, чтобы не загромождать материал. Скажем только, что ровно по одной таблице с назначением «РегистрацияИзменений» и подстрокой «ChngR» в имени будет создано для каждого из объектов метаданных, зарегистрированных хотя бы в одном плане обмена. Таблица 3.12.2. Имена таблиц, добавленных к таблицам объектом метаданных после включения их в план обмена Имя таблицы хранения Имя таблицы Метаданные Назначение "SystemSettings" "" "" "CommonSettings" "RepSettings" "" "" "" "" "RepVarSettings" "" "" "FrmDtSettings" "" "" "UsersWorkHistory" "" "" "Const8" "Const10" "ConstChngR15" "" "" "" "Константа.Константа1" "Константа.Константа2" "Константа.Константа2" "Node13" "ПланОбмена. ПланОбмена1" "Справочник. Справочник1" "" "ПланОбмена.ПланОбмена1" "ХранилищеСистемныхНастроек" "ХранилищеОбщихНастроек" "ХранилищеПользовательскихНастроекОтчетов" "ХранилищеВариантовОтчетов" "ХранилищеНастроекДанныхФорм" "ИсторияРаботыПользователей" "Константа" "Константа" "РегистрацияИзмененийКонстанты" "Основная" "Справочник.Справочник1" "Основная" "Справочник.Справочник1" "РегистрацияИзменений" "Reference7" "ReferenceChngR14" 39 Обязательными они называется потому, что при их отсутствии система не считает имеющуюся базу базой «1С:Предприятия». 80 Настольная книга 1С:Эксперта по технологическим вопросам Создадим по одному объекту каждого вида. Объектам, которые могут иметь табличные части, добавим их (одному из документов – две). Обратим внимание на то, что, когда мы получаем информацию о структуре через останов на отладчике (см. рис. 3.12.2), элементами строки, отвечающей за таблицу, являются также вложенные таблицы значений: «Индексы» и «Поля». Через них можно получить сведения о структуре индексов и структуре полей, и в двух следующих главах мы эти средством воспользуемся. Рис. 3.12.2. Просмотр структуры базы через останов на отладчике. Видны вложенные таблицы «Индексы» и «Поля» В таблице 3.12.3 представлены созданные таблицы базы. В столбце «Назначение» для некоторых таблиц курсивом добавлено условие, при котором эта таблица добавляется, если такое условие требует пояснения. Таблица 3.12.3. Пример имен таблиц, созданных в базе. В базу добавлены все возможные объекты Имя таблицы хранения Имя таблицы "CommonSettings" "ExtDataSrcPrms" "FrmDtSettings" "RepSettings" "" "" "" "" "RepVarSettings" "SystemSettings" "UsersWorkHistory" "" "" "" "BPr23" "BPrPoints24" "BPr23.VT60" "Document16" "Document16.VT47" "Document16.VT49" "DocumentJournal37" Метаданные Служебные "" "" "" "" "" "" "" Бизнес-процессы "БизнесПроцесс.БизнесПроцесс1" "БизнесПроцесс.БизнесПроцесс1" "" "БизнесПроцесс.БизнесПроцесс1" "БизнесПроцесс.БизнесПроцесс1. "БизнесПроцесс.БизнесПроцесс1. ТабличнаяЧасть1" ТабличнаяЧасть.ТабличнаяЧасть1" Документы "Документ.Документ1" "Документ.Документ1" "Документ.Документ1. "Документ.Документ1. ТабличнаяЧасть1" ТабличнаяЧасть.ТабличнаяЧасть1" "Документ.Документ1. "Документ.Документ1. ТабличнаяЧасть2" ТабличнаяЧасть.ТабличнаяЧасть2" Журналы документов "ЖурналДокументов. "ЖурналДокументов. ЖурналДокументов1" ЖурналДокументов1" Назначение "ХранилищеОбщихНастроек" "Основная" "ХранилищеНастроекДанныхФорм" "ХранилищеПользовательскихНастроекОтчетов" "ХранилищеВариантовОтчетов" "ХранилищеСистемныхНастроек" "ИсторияРаботыПользователей" "Основная" "ТочкиМаршрута" "ТабличнаяЧасть" "Основная" "ТабличнаяЧасть" "ТабличнаяЧасть" "Основная" Теория Имя таблицы хранения "Task25" "Task25.VT62" "Const8" "Const10" "ConstChngR15" "Enum26" "CKinds21" "CKindsDN86" "CKinds21.BaseCK" "CKinds21. LeadingCK" "CKinds21. DisplacedCK" "CKinds21.VT58" "Chrc27" "Chrc27.VT51" "Node13" "Node13.VT56" Планы счетов "Acc22" "Acc22.ExtDim72" "Acc22.VT53" "Seq41" "SeqB42" "AccRg28" Имя таблицы Метаданные Задачи "Задача.Задача1" "Задача.Задача1.ТабличнаяЧасть. ТабличнаяЧасть1" Константы "" "Константа.Константа1" "" "Константа.Константа2" "" "Константа.Константа2" Перечисления "Перечисление.Перечисление1" "Перечисление.Перечисление1" Планы видов расчета "ПланВидовРасчета.ПланВидовРас"ПланВидовРасчета.ПланВидовРасчета1" чета1" "" "ПланВидовРасчета.ПланВидовРасчета1" "Задача.Задача1" "Задача.Задача1.ТабличнаяЧасть1" 81 Назначение "Основная" "ТабличнаяЧасть" "Константа" "Константа" "РегистрацияИзмененийКонстанты" "Основная" "Основная" "ПорядокВытеснения" (создается, если у плана видов расчета установлен флажок ИспользуетПериодДействия) "ПланВидовРасчета.ПланВидовРасче- "ПланВидовРасчета.ПланВидовРас- "БазовыеВидыРасчета" (создается, та1.БазовыеВидыРасчета" чета1.ТабличнаяЧасть.БазовыеВи- если у плана видов расчета свойдыРасчета" ство "Зависимость от базы" не "Не зависит") "ПланВидовРасчета.ПланВидовРасче- "ПланВидовРасчета.ПланВидовРас- "ВедущиеВидыРасчета" та1.ВедущиеВидыРасчета" чета1.ТабличнаяЧасть.ВедущиеВидыРасчета" "ПланВидовРасчета.ПланВидовРасче- "ПланВидовРасчета.ПланВидовРас- "ВытесняющиеВидыРасчета" та1.ВытесняющиеВидыРасчета" чета1.ТабличнаяЧасть.Вытесняю(создается, если у плана видов расщиеВидыРасчета" чета установлен флажок ИспользуетПериодДействия) "ПланВидовРасчета.ПланВидовРасче- "ПланВидовРасчета.ПланВидовРас- "ТабличнаяЧасть" та1.ТабличнаяЧасть1" чета1.ТабличнаяЧасть.ТабличнаяЧасть1" Планы видов характеристик "ПланВидовХарактеристик.ПланВи"ПланВидовХарактеристик.ПланВи- "Основная" довХарактеристик1" довХарактеристик1" "ПланВидовХарактеристик.ПланВи"ПланВидовХарактеристик.План"ТабличнаяЧасть" довХарактеристик1.ТабличнаяЧасть1" ВидовХарактеристик1.ТабличнаяЧасть.ТабличнаяЧасть1" Планы обмена "ПланОбмена.ПланОбмена1" "ПланОбмена.ПланОбмена1" "Основная" "ПланОбмена.ПланОбмена1.Таблич- "ПланОбмена.ПланОбмена1.Та"ТабличнаяЧасть" наяЧасть1" бличнаяЧасть.ТабличнаяЧасть1" "ПланСчетов.ПланСчетов1" "ПланСчетов.ПланСчетов1" "ПланСчетов.ПланСчетов1.ВидыСуб- "ПланСчетов.ПланСчетов1.Табличконто"(создается, если максимальное наяЧасть.ВидыСубконто" количество субконто больше 0) "ПланСчетов.ПланСчетов1.Таблич"ПланСчетов.ПланСчетов1.ТабличнаяЧасть1" наяЧасть.ТабличнаяЧасть1" Последовательности "Последовательность.Последователь- "Последовательность.Последованость1" тельность1" "" "Последовательность.Последовательность1" Регистры бухгалтерии "РегистрБухгалтерии.РегистрБухгал"РегистрБухгалтерии.РегистрБухтерии1" галтерии1" "Основная" "ВидыСубконто" "ТабличнаяЧасть" "Основная" "ГраницыПоследовательности" "Основная" 82 Настольная книга 1С:Эксперта по технологическим вопросам Имя таблицы хранения Имя таблицы Метаданные Назначение "AccRgAT030" "" "РегистрБухгалтерии.РегистрБухгалтерии1" "ИтогиПоСчетам" "AccRgAT174" "" "РегистрБухгалтерии.РегистрБухгалтерии1" "ИтогиПоСчетамССубконто1" (создается, если максимальное количество субконто у плана счетов больше 0) "AccRgAT275" "" "РегистрБухгалтерии.РегистрБухгалтерии1" "ИтогиПоСчетамССубконто2" (создается, если максимальное количество субконто у плана счетов больше 1) "AccRgCT65" "" "РегистрБухгалтерии.РегистрБухгалтерии1" "ИтогиМеждуСчетами" " (создается, если регистр поддерживает корреспонденцию) "AccRgED77" """ "РегистрБухгалтерии.РегистрБухгалтерии1" "ЗначенияСубконто" (создается, если максимальное количество субконто у плана счетов больше 0) "AccRgOpt34" "" "РегистрБухгалтерии.РегистрБухгалтерии1" "НастройкиХраненияИтоговРегистраБухгалтерии" "AccumRg17" "РегистрНакопления.РегистрНакопления1" Регистры накопления типа «Остатки» "РегистрНакопления.РегистрНакопления1" "Основная" "AccumRgAggGrid92" "" "РегистрНакопления.РегистрНакопления1" "СписокАгрегатовРегистровНакопления" (создалась после создания агрегатов для Регистра накопления2) "AccumRgAggOpt94" "" "РегистрНакопления.РегистрНакопления1" "НастройкиРежимаАгрегатовРегистровНакопления" " (создалась после создания агрегатов для Регистра накопления2) "AccumRgOpt20" "" "РегистрНакопления.РегистрНакопления1" "НастройкиХраненияИтоговРегистраНакопления" "AccumRgT19" "" "РегистрНакопления.РегистрНакопления1" "Итоги" "AccumRg78" "РегистрНакопления.РегистрНакопления2" "РегистрНакопления.РегистрНакопления2" "Основная" "AccumRgAgg31h97" "" "РегистрНакопления.РегистрНакопления2" "АгрегатРегистраНакопления" (создалась после создания агрегатов) "AccumRgAggGrid93" "" "РегистрНакопления.РегистрНакопления2" "СписокАгрегатовРегистровНакопления" (создалась после создания агрегатов) "AccumRgAggOpt95" "" "РегистрНакопления.РегистрНакопления2" "НастройкиРежимаАгрегатовРегистровНакопления" (создалась после создания агрегатов) "AccumRgBf99" "" "РегистрНакопления.РегистрНакопления2" "БуферОборотов" (создалась после создания агрегатов) "AccumRgDl98" "" "РегистрНакопления.РегистрНакопления2" "НовыеОбороты" (создалась после создания агрегатов) Регистры накопления типа «Обороты» Теория Имя таблицы хранения Имя таблицы Метаданные 83 Назначение "AccumRgOpt79" "" "РегистрНакопления.РегистрНакопления2" "НастройкиХраненияИтоговРегистраНакопления" "AccumRgSt100" "" "РегистрНакопления.РегистрНакопления2" "СтатистикаЗапросов" (создалась после создания агрегатов) "AccumRgTn85" "" "РегистрНакопления.РегистрНакопления2" "Обороты" (создается, если есть хоть одно измерение) "CRg36" "РегистрРасчета.РегистрРасчета1" "РегистрРасчета.РегистрРасчета1" "Основная" "CRgActP88" "" "РегистрРасчета.РегистрРасчета1" "ПериодыДействия" (создается, если установлено свойство "Период действия" ) "CRgRecalc87" "РегистрРасчета.РегистрРасчета1. Перерасчет.Перерасчет1" "РегистрРасчета.РегистрРасчета1. Перерасчет.Перерасчет1" "Основная" (создается, если добавлен перерасчет ) "InfoRg38" "РегистрСведений.РегистрСведений1" "РегистрСведений.РегистрСведений1" "Reference7" "Справочник.Справочник1" "Справочник.Справочник1" "Основная" "ReferenceChngR14" "" "Справочник.Справочник1" "РегистрацияИзменений" "Reference7.VT45" "Справочник.Справочник1.ТабличнаяЧасть1" "Справочник.Справочник1.ТабличнаяЧасть.ТабличнаяЧасть1" "ТабличнаяЧасть" Регистры расчета Регистры сведений "Основная" Справочники Несколько комментариев к таблице: 1. Табличная часть объекта в первой части префикса содержит префикс объекта, см., напр., «Document16» и «Document16.VT47». 2. К таблице точек маршрута бизнес-процесса и к некоторым другим таблицам это не относится. 3. Понятно, что в условиях другой конкретной базы нумерация таблиц и их количество будут другими. После изменения релиза могут измениться и их имена, хотя бы и незначительно. Могут появляться новые виды таблиц, как появились отдельные таблицы под каждую константу и таблицы, связанные с агрегатами. Главное – понимать, как и откуда вы эти данные можете получить и как полученные из вашей базы особенности размещения данных влияют на параллельность работы. 84 Настольная книга 1С:Эксперта по технологическим вопросам 3.13. Сведения об индексах базы. Способ получения этих сведений. Кластерный и некластерные индексы Подход к получению сведений об индексах может быть таким же, как тот, что мы использовали в предыдущей главе: не имея справочников, с помощью кода получить в отладчике структуру хранения данных: ТаблицаСоСтруктурой = ПолучитьСтруктуруХраненияБазыДанных(); ТаблицаСоСтруктурой.Сортировать("Метаданные, ИмяТаблицыХранения"); Далее, спускаясь по структуре (расшифровываемые поля на рис. 3.13.1 подсвечены), узнать, какие есть индексы: Теория 85 Рис. 3.13.1. Получение сведений об индексе непосредственно из базы В примере на рисунках выше выяснено, что у таблицы документов один из индексов идет по номеру и ссылке. Также из рисунков этого примера видно, как вообще добраться до информации об индексах. Нужно из первоначальной таблицы значений, в которую была получена структура базы, пройти по вложенной в нее таблице «Индексы», а из «Индексов» – пройти по таблице значений «Поля». Написание обработки, проходящей два уровня вложенных таблиц, затруднений вызвать не должно. Запустив ее, получим реально существующий состав индексов для нашей базы (в таблице 3.13.1 приведен его фрагмент). В колонке «Имя поля» курсивом дописаны описания на русском языке, не формирующиеся автоматически. Таблица 3.13.1. Индексы, созданные в базе (фрагмент) Имя таблицы хранения Метаданные + назначение Имя индекса Имя поля хранения Имя поля "Const8" "Константа.Константа1Константа" "" "" "Const10" "Константа.Константа2Константа" "" "" "ConstChngR15" "Константа.Константа2РегистрацияИзмененийКонстанты" "" "" "ByNodeMsg" "Node, MessageNo, ConstID" "" "" "ByDataKey" "ConstID, Node" "Document16" "Документ.Документ1Основная" "" "" "ByDocNum" "Number, ID" "Номер, Ссылка" "" "" "ByDocDate" "Date_Time, ID" "Дата, Ссылка" "DocumentJournal37" "ЖурналДокументов.ЖурналДокументов1Основная" "" "" "ByDocDate" "Date_Time, Document" "Дата, Ссылка" "" "" "ByDoc" "Document" "Ссылка" "Enum26" "Перечисление.Перечисление1Основная" "" "" "Seq41" "Последовательность.Последовательность1Основная" "" "" "ByRecorder" "Recorder" "Регистратор" "" "" "ByDims" "Period, Recorder" "Период, Регистратор" "AccumRg17" "РегистрНакопления.РегистрНакопления1Основная" "" "" "ByKey" "ByKey" "ByOrder" "ByPeriod" "RecordKey" "" "RecordKey" "" "EnumOrder, ID" "Period, Recorder, LineNo" ", , " (Узел + Номер сообщения + Ключ данных) ", " (Ключ данных + Узел) "Порядок, Ссылка" "Период, Регистратор, НомерСтроки" 86 "" Настольная книга 1С:Эксперта по технологическим вопросам Имя таблицы хранения Метаданные + назначение Имя индекса Имя поля хранения Имя поля "" "ByRecorder" "AccumRgAggGrid92" "Регистратор, НомерСтроки" "РегистрНакопления.РегистрНакопления1СписокАгрегатовРегистровНакопления" "" "" "ByID" "AccumRgAggOpt94" "RegID, DefaultPeriodic, ", , , " ID, Updated" "РегистрНакопления.РегистрНакопления1НастройкиРежимаАгрегатовРегистровНакопления" "" "" "ByID" "AccumRgOpt20" "РегистрНакопления.РегистрНакопления1НастройкиХраненияИтоговРегистраНакопления" "" "" "AccumRgT19" "РегистрНакопления.РегистрНакопления1Итоги" "" "" "InfoRg38" "РегистрСведений.РегистрСведений1Основная" "" "" "Reference7" "Справочник.Справочник1Основная" "" "" "" "" "ReferenceChngR14" "Справочник.Справочник1РегистрацияИзменений" "" "" "ByNodeMsg" "Node, MessageNo, ID" "" "" "ByDataKey" "ID, Node" "ByRegID" "Recorder, LineNo" "RegID" "" "RegID" "" "Period, Fld96, Splitter" ", Измерение1, " "Fld39" "Измерение1" "Code" "Code, ID" "Код, Ссылка" "Descr" "Description, ID" "Наименование, Ссылка" "ByDims" "ByDims" ", , " (Узел + Номер сообщения + Ключ данных) ", " (Ключ данных + Узел) Описанный способ получения существующих индексов не выводит, однако, есть нескольких важных вещей: 1. Для всех объектных типов данных (справочники, документы и т. д.) в базе автоматически определяется кластерный индекс по полю Ссылка. И вот его в этой таблице вы не увидите, но про него надо просто помнить. 2. При использовании общего реквизита к большинству индексов первым столбцом ключа индекса добавляется DataSeparationHash. Этого факта, к сожалению, через ПолучитьСтруктуруХраненияБазыДанных() вы тоже не увидите, и про него тоже надо помнить40.34 3. Также в этой таблице вы не увидите индекса simplekey для регистра сведений, но он для наших целей важности не имеет. Кластерным называется индекс, по значению которого отсортирована таблица в базе. Остальные индексы называются некластерными. Таблица может иметь только один кластерный индекс или не иметь ни одного. Некластерных индексов может быть несколько, или может не быть совсем. Кластерный индекс для необъектных типов данных, в отличие от объектных, в таблицу, получаемую через ПолучитьСтруктуруХраненияБазыДанных(), попадает. В таблице выше кластерные индексы выделены жирным шрифтом. Данные по тому, какие индексы являются кластерными, получены как из литературы, так и через просмотр свойств базы средствами SQL Server Management Studio. Этот альтернативный предложенному ранее способ получения информации о струк40 Также см. сноску в конце раздела 3.11. Теория 87 туре базы более точен (видны все таблицы, все индексы, все реквизиты, по которым индекс строится), но значительно менее удобен в том, что нет привязки к именам таблиц в терминах метаданных, а также в том, что годится только для SQL Server. К слову, создание индексов не через конфигуратор, а средствами сервера СУБД строго не рекомендуется и, кроме прочего, нарушает лицензионное соглашение. Далее, хотя мы описали методику получения фактического состава индексов в базе, нелишним будет привести сведения по текущим правилам построения индексов хотя бы для справочников, документов, регистров сведений, накопления и бухгалтерии41, т. е. для того, с чем чаще всего приходится иметь дело. Использованы фрагменты статьи http://its.1c.ru/db/metod8dev#content:1590:hdoc с сайта ИТС, статья находится в открытом доступе. 35 <...> Индексы таблиц создаются неявным образом при создании объектов конфигурации, а также при тех или иных настройках объектов конфигурации. Для тех случаев, когда создание индексов зависит от настроек объектов конфигурации, приведены условия создания индексов. В приведенных ниже таблицах имена индексных полей приведены так, как они описаны в разделе документации «Таблицы запросов». Для измерений, реквизитов и т. д. применяются условные имена Измерение1, Реквизит1 и т. д. Для общих реквизитов, являющихся разделителями в режиме «независимо», будем использовать имена ОРНР (ОРНР1, ОРНР2, и т. д.). Для общих реквизитов, являющихся разделителями в режиме «независимо и совместно», будем использовать имена ОРСР. Если режим разделения не имеет значения, то для общих реквизитов, являющихся разделителями, будем использовать имена ОРР. Если в конфигурации определены разделители, то в индексы может входить поле, которое содержит значение хеш-функции набора значений разделителей. Такое поле будем обозначать именем ОРРХ. Те индексные поля, которые не являются обязательными, приведены в квадратных скобках, а если в индексе присутствует набор однотипных полей, это описывается многоточием, например: Реквизит + Измерение1 + [Измерение2 +...]. Данным материалом следует руководствоваться при написании текстов запросов с целью оптимизации времени их исполнения. 41 Мы не проводили работ по полному сличению материала статьи с ИТС и фактически имеющихся в базах индексов. Но то, что мы сравнивали, позволяет говорить о том, что это точное и очень полезное описание для версий 8.2.14–8.3.5. Как мы говорили, фактический состав индексов надо уметь получать самостоятельно, но в данном материале описаны еще и закономерности, касающиеся разделителей и сплиттера, которые трудно обобщить, анализируя экспериментальные данные. 88 Настольная книга 1С:Эксперта по технологическим вопросам Справочник4236 Основные индексы Индекс [ОРНР1 + ... +] Ссылка (Кластерный)43 [ОРРХ | ОРНР1 +] Код + Ссылка [ОРРХ | ОРНР1 +] Наименование + Ссылка [ОРРХ | ОРНР1 +] Реквизит + Ссылка [ОРРХ | ОРНР1 +] Реквизит + Код + Ссылка [ОРРХ | ОРНР1 +] Реквизит + Наименование + Ссылка [ОРРХ | ОРНР1 +] Реквизит Условие Всегда. В индекс входят поля независимых разделителей, которые разделяют этот справочник Свойство «Длина кода» не равно 0. Если справочник разделяется одним независимым разделителем, тип которого не Строка, то индекс содержит поле этого разделителя. Если тип разделителя – Строка, или разделитель независимый и совместный, или разделителей больше одного, то индекс содержит поле значения хеш-функции значений разделителей. Это правило справедливо для всех индексов, в составе которых указано [ОРРХ | ОРНР1 +] Свойство «Длина наименования» не равно 0 Для реквизита «Реквизит» свойство «Индексировать» установлено в значение «Индексировать» Для реквизита «Реквизит» свойство «Индексировать» установлено в значение «Индексировать с доп. Упорядочиванием», и при этом свойство «Длина кода» не равно 0, а свойство «Основное представление» равно «В виде кода» Для реквизита «Реквизит» свойство «Индексировать» установлено в значение «Индексировать с доп. упорядочиванием», и при этом свойство «Длина наименования» не равно 0, а свойство «основное представление» равно «В виде наименования» Справочник включен в критерий отбора через реквизит «Реквизит» Документ Индекс [ОРНР1 + ... +] Ссылка (Кластерный) [ОРРХ | ОРНР1 +] Дата + Ссылка [ОРРХ | ОРНР1 +] Номер + Ссылка [ОРРХ | ОРНР1 +] Реквизит + Ссылка [ОРРХ | ОРНР1 +] Реквизит + Дата + Ссылка [ОРРХ | ОРНР1 +] Реквизит [ОРРХ | ОРНР1 +] ПрефиксНомера + Номер + Ссылка <...> 42 43 Условие Всегда. В индекс входят поля независимых разделителей, которые разделяют этот документ Всегда Свойство «Длина номера» не равно 0 Для реквизита «Реквизит» свойство «Индексировать» установлено в значение «Индексировать» Для реквизита «Реквизит» свойство «Индексировать» установлено в значение «Индексировать с доп. упорядочиванием» Документ включен в критерий отбора через реквизит «Реквизит» Свойство «Длина номера» не равно 0 Кластерные индексы выделены полужирным. Для справочников приведены не все индексы, а только наиболее важные для наших целей. Дополнительные индексы для иерархических и подчиненных справочников см. в оригинале статьи. Теория 89 Табличная часть Индекс Условие [ОРНР1 + ... +] Ссылка + Ключ (Кластерный) [ОРНР1 + ... +] Реквизит + Ссылка Всегда. В индекс входят поля независимых разделителей, разделяющих объект, которому принадлежит табличная часть Объект конфигурации включен в критерий отбора через реквизит «Реквизит» табличной части, или для реквизита табличной части установлено свойство «Индексировать». В индекс входят поля независимых разделителей, разделяющих объект, которому принадлежит табличная часть Для всех таблиц, которые предоставляют доступ к табличным частям объектов. Регистр сведений Непериодический регистр сведений Индекс Условие и описание Есть хоть одно измерение регистра. [ОРРХ | ОРНР1 +] Измерение1 + Индекс, включающий все измерения в том порядке, в котором они [Измерение2 +...] (Кластерный) заданы при конфигурировании. Индекс кластерный, если регистр независимый Измерению «ИзмерениеN» задано свойство «Индексировать» или свойство «Ведущее», и при этом это не первое и не единственное [ОРРХ | ОРНР1 +] ИзмерениеN + измерение. Измерение1 + [Измерение2 +...] Индекс, включающий все измерения. Первое поле – «ИзмерениеN», затем все остальные измерения в том порядке, в котором они заданы при конфигурировании Реквизиту «Реквизит» задано свойство «Индексировать». [ОРРХ | ОРНР1 +] Реквизит + Индекс, в котором первое поле – «Реквизит», затем все измерения Измерение1 + [Измерение2 +...] в том порядке, в котором они заданы при конфигурировании Количество измерений больше одного. Используется для обхода 44 регистра при реструктуризации, а также для выборки записей [ОРРХ | ОРНР1 +] SimpleKey с использованием оптимального порядка обхода Ресурсу «Ресурс» задано свойство «Индексировать». [ОРРХ | ОРНР1 +] Ресурс + Индекс, в котором первое поле – «Ресурс», затем все измерения Измерение1 + [Измерение2 +...] в том порядке, в котором они заданы при конфигурировании Периодический регистр сведений Индекс [ОРРХ | ОРНР1 +] Период + [Измерение1 + ...] (Кластерный) (для 8.2) [ОРРХ | ОРНР1 +] [Измерение1 + ...] + Период (Кластерный) (для 8.3) [ОРРХ | ОРНР1 +] Измерение1 + [Измерение2 +...] + Период (для 8.2) [ОРРХ | ОРНР1 +] Период + Измерение1 + [Измерение2 +...] (для 8.3) [ОРРХ | ОРНР1 +] ИзмерениеN + Период + Измерение1 + [Измерение2 +...] ________________ 44 Условие и описание Всегда Есть хоть одно измерение регистра. Индекс, включающий все измерения в том порядке, в котором они заданы при конфигурировании и поле «Период» Измерению «ИзмерениеN» задано свойство «Индексировать» или свойство «Ведущее», и при этом это не единственное измерение. Индекс, включающий поле «Период» и все измерения. Первое поле – «ИзмерениеN», затем поле «Период», затем все остальные измерения в том порядке, в котором они заданы при конфигурировании SimpleKey – короткий ключ записи регистра. Поле присутствует у непериодических регистров, имеющих хотя бы одно измерение. 90 Настольная книга 1С:Эксперта по технологическим вопросам Индекс Условие и описание Реквизиту «Реквизит» задано свойство «Индексировать». Индекс, в котором первое поле – «Реквизит», затем поле «Период», затем все измерения в том порядке, в котором они заданы при конфигурировании Ресурсу «Ресурс» задано свойство «Индексировать». Индекс, в котором первое поле – «Ресурс», затем поле «Период», затем все измерения в том порядке, в котором они заданы при конфигурировании [ОРРХ | ОРНР1 +] Реквизит + Период + [Измерение1 + ...] [ОРРХ | ОРНР1 +] Ресурс + Период + [Измерение1 + ...] Дополнительный индекс для регистра сведений, подчиненного регистратору Индекс Условие и описание Всегда. [ОРНР1 + ... +] Регистратор + НомерСтроки В индекс входят поля независимых разделителей, которые (Кластерный) разделяют этот регистр. Индекс кластерный, если регистр непериодический Регистр сведений с периодичностью «По позиции регистратора» Индекс [ОРРХ | ОРНР1 +] Период + Регистратор + НомерСтроки (Кластерный) Условие и описание Всегда Всегда. В индекс входят поля независимых разделителей, которые разделяют этот регистр Есть хоть одно измерение регистра. [ОРРХ | ОРНР1 +] Измерение1 + [ИзмеИндекс, включающий все измерения в том порядке, рение2 + ...] + Период + Регистратор + в котором они заданы при конфигурировании, поле «Период» НомерСтроки и поле «Регистратор» [ОРРХ | ОРНР1 +] Измерение + Период Измерению «Измерение» задано свойство «Индексировать» + Регистратор + НомерСтроки [ОРРХ | ОРНР1 +] Реквизит + Период + Реквизиту «Реквизит» задано свойство «Индексировать» Регистратор + НомерСтроки [ОРРХ | ОРНР1 +] Ресурс + Период + Ресурсу «Ресурс» задано свойство «Индексировать» Регистратор + НомерСтроки [ОРНР1 + ... +] Регистратор + НомерСтроки Регистр накопления4537 Основная таблица регистра Индекс [ОРРХ | ОРНР1 +] Период + Регистратор + НомерСтроки (Кластерный) Условие Всегда Всегда. [ОРНР1 + ... +] Регистратор + НомерСтроки В индекс входят поля независимых разделителей, которые разделяют этот регистр [ОРРХ | ОРНР1 +] Измерение + Период + Измерению «Измерение» задано свойство «ИндексироРегистратор + НомерСтроки вать» [ОРРХ | ОРНР1 +] Реквизит + Период + Реквизиту «Реквизит» задано свойство «Индексировать» Регистратор + НомерСтроки 45 Для регистров накопления приведены не все индексы, а только наиболее важные для наших целей. Индексы для таблицы агрегатов, таблицы статистики регистра накопления и пр. см. в оригинале статьи. Теория 91 Таблица остатков Индекс Условие [ОРРХ | ОРНР1 +] Период + Измерение1 + Для регистров вида «Остатки» ... + ИзмерениеN (Кластерный) ) + Splitter46 Измерению «Измерение» задано свойство «Индексиро[ОРРХ | ОРНР1 +] Измерение + Период вать» Таблица оборотов Индекс [ОРРХ | ОРНР1 +] Период + Измерение1 + ... + ИзмерениеN (Кластерный) + Splitter [ОРРХ | ОРНР1 +] Измерение + Период Условие Для регистров вида «Обороты» Измерению «Измерение» задано свойство «Индексировать» <...> Регистр бухгалтерии Основная таблица регистра без корреспонденции Индекс [ОРРХ | ОРНР1 +] Период + Регистратор + НомерСтроки (Кластерный) Условие и описание Всегда Всегда. [ОРНР1 + ... +] Регистратор + НомерСтроки В индекс входят поля независимых разделителей, которые разделяют этот регистр [ОРРХ | ОРНР1 +] Счет + Период + Регистру назначен план счетов Регистратор [ОРРХ | ОРНР1 +] Измерение + Период + Измерению «Измерение» задано свойство «ИндексироРегистратор + НомерСтроки вать» [ОРРХ | ОРНР1 +] Реквизит + Период + Реквизиту «Реквизит» задано свойство «Индексировать» Регистратор + НомерСтроки Основная таблица регистра с корреспонденцией От вышеприведенного состава индексов отличается лишь тем, что вместо индекса по счету создаются два индекса по счету дебета и счету кредита. Индекс [ОРРХ | ОРНР1 +] СчетДт + Период + Регистратор [ОРРХ | ОРНР1 +] СчетКт + Период + Регистратор Условие Регистру назначен план счетов Регистру назначен план счетов Таблица итогов по счету Индекс [ОРРХ | ОРНР1 +] Период [+ Счет] + ИзмерениеБезПризнакаУчета1 + ... + ДополнительноеИзмерение1 + ... + ИзмерениеСПризнакомУчета1 + ... [+ ХэшИзмерений] [+ РазделительИтогов47] Условие Поле «Счет» добавляется в случае, если регистру определен план счетов. Поле «ХэшИзмерений» добавляется, количество других полей больше 15. Поле «РазделительИтогов» добавляется, если включено разделение итогов ________________ 46 47 Splitter – указано для регистра накопления. Для регистра бухгалтерии указано «РазделительИтогов». На практике можно убедиться, что поле добавляется в индекс, если для регистра разрешено разделение итогов в конфигураторе (и неважно, включено разделение итогов или нет). См. выше примечание к полю Splitter для регистров накопления. 92 Настольная книга 1С:Эксперта по технологическим вопросам Таблица итогов между счетами Только для регистров, поддерживающих корреспонденцию. Индекс [ОРРХ | ОРНР1 +] ИзмерениеДт1 + ИзмерениеКт1 + ... Измерение1 + ... [+ ХэшИзмерений] [+ РазделительИтогов] Условие Для небалансовых измерений. Для балансовых измерений. Поле «ХэшИзмерений» добавляется, количество других полей больше 15. Поле «РазделительИтогов» добавляется, если включено разделение итогов Таблица со значениями субконто Индекс [ОРРХ | ОРНР1 +] Регистратор + НомерВсегда Строки + Корреспонденция [ОРРХ | ОРНР1 +] Период + Регистратор + НомерСтроки + ВидСубконто + Корреспон- Всегда денция (Кластерный) [ОРРХ | ОРНР1 +] ВидСубконто + Значение Всегда <...> Условие Важное дополнение по индексам для 8.3 без режима совместимости Приведенные выше сведения справедливы для 8.2 и для 8.3 в режиме совместимости с 8.2. В 8.3 у периодических регистров кластерный индекс выглядит: Измерение 1 + .... + Период, а не Период + Измерение 1 + ... Всегда проверяйте, какие именно индексы созданы для вашей базы. Сравните рис. 3.13.2, 3.13.3, 3.13.4. Рис. 3.13.2. Кластерный индекс периодического (периодичность – секунда) независимого регистра сведений в 8.2 Теория 93 Рис. 3.13.3. Он же, если базу открыть в 8.3 и даже отключить режим совместимости (применив изменения). Ничего не изменилось Рис. 3.13.4. Он же после принудительного выполнения реиндексации и реструктуризации через режим «Тестирование и исправление» Видно, что структура кластерного индекса периодического регистра сведений поменялась: поле Период было первым, стало последним. 94 Настольная книга 1С:Эксперта по технологическим вопросам 3.14. Планы запросов. Получение плана запроса в профайлере SQL. Операторы плана, наиболее важные для нас Получение плана запроса в профайлере SQL План выполнения запроса – это последовательность операций, необходимых для получения результата запроса в СУБД. По фактическому плану можно понять, какой именно алгоритм СУБД выбрала для решения поставленной перед ней задачи, какие операторы решила использовать. Проанализировав, как выполнился каждый из операторов, можно определить, не ошиблась ли СУБД в этом выборе. Чтобы получить текст запроса так, как его получает SQL Server, и увидеть план запроса, нужно сделать следующее: 1. Запустить SQL Server Profiler. 2. Создать трассировку. Можно использовать стандартный шаблон. 3. В свойствах трассировки: □□ Убедиться, что в нее входят события SQL:BatchStarted, SQL:BatchCompleted, RPC:Completed. □□ Установить галочку «все события». □□ Добавить события Showplan Statistics Profile и Showplan XML Statistics Profile48 из узла Performance.38 □□ Снять галочку «все события», останутся только выбранные. □□ Установить галочку «все столбцы». □□ Добавить столбец «DatabaseName». □□ Зайти в «фильтры столбцов», поставить фильтр «DatabaseName» «Похоже на (Like)» <написать_имя_своей_базы>. □□ Убедиться, что у события Showplan Statistics Profile включен столбец BinaryData. □□ Снять галочку «все столбцы», останутся только выбранные. □□ В итоге настройка трассировки как минимум должна содержать все поля, показанные на рис. 3.14.1. 4. Если запрос выполняется из «1С», в конфигураторе «1С» установить один останов на отладчике на строке интересующего нас запроса, и второй – сразу после него. Дойти до первого останова. 5. Запустить трассировку. 6. Позволить приложению выполнить запрос (если запрос выполняется из «1С», это значит продолжить отладку и дойти до следующего останова на отладчике; если запрос выполняется из SQL Management Studio, это значит запустить его). 48 В узле Performance находятся также другие события Showplan, но по большей части они относятся к ожидаемым планам и не содержат важной для нас информации о фактическом количестве строк и количестве выполнений операторов. Теория 7. 95 Остановить трассировку в приложении SQL Server Profiler («Паузой», если нужно, чтобы при следующем выполнении трассировки запроса строки, полученные при нынешней трассировке, остались; «Стопом», если нужно, чтобы они очистились). 8. Найти свой запрос в трассировке. Обычно ориентируются по наибольшему значению в поле Duration для событий SQL:BatchCompleted или RPC:Completed, потому что есть основания считать, что именно исследуемый запрос имеет наибольшую длительность. События Showplan Statistics Profile и Showplan XML Statistics Profile, относящиеся к исследуемому запросу, находятся непосредственно над ними. 9. Выбрать событие SQL:BatchStarted, SQL:BatchCompleted или RPC:Completed, просмотреть текст запроса так, как его получает SQL Server. 10. Выбрать событие Showplan Statistics Profile, просмотреть план запроса, обратить внимание на используемые операторы и столбцы Rows (количество строк) и Executes (количество выполнений) для них.39 11. Выбрать событие Showplan XML Statistics Profile, просмотреть графический план запроса с помощью всплывающей подсказки (подробности по ней будут ниже)49. 12. При необходимости сохранить трассировку. 13. По совокупности полученных показателей сделать вывод об оптимальности выбранного плана. Рис. 3.14.1. Настройка трассировки для получения планов запроса 49 В MSDN описан другой способ. Графический план фактического выполнения можно получить так же, выполнив запрос в SQL Management Studio, если включить там опцию «Запрос» – «Включить действительный план выполнения». Текст запроса можно скопировать туда, например, из SQL:BatchCompleted, тогда в конец текста запроса будут включены еще и значения параметров. Этот способ содержит два важных ограничения: он прост только для простых запросов, когда нет временных таблиц, и он не выводит план в текстовом виде с важными для нас столбцами Rows и Executes (как получить из него для SQL Server 2005 количество выполнений каждого оператора, мы так и не нашли). 96 Настольная книга 1С:Эксперта по технологическим вопросам Проиллюстрируем это на примерах. Возьмем демобазу «Бухгалтерии предприятия», редакция 3.0 (3.0.19.15). Пример 1 Выполним из SQL Management Studio следующий запрос, включив трассировку профайлером (_AccRg7172 – это основная таблица регистра бухгалтерии «Хозрасчетный»). SELECT * FROM _AccRg7172 План запроса, полученный через Showplan Statistics Profile, будет следующим50:40 Rows ---1181 Executes -------1 StmtText -------Clustered Index Scan (OBJECT:([unt3].[dbo].[_AccRg7172].[_AccRg7172_ByPeriod_TRN])) Пример 2 Теперь выполним, казалось бы, точно такой же запрос, но уже средствами «1С»: ВЫБРАТЬ * ИЗ РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный План запроса, полученный через Showplan Statistics Profile, будет следующим: Rows Executes StmtText -----------------1181 1 Clustered Index Seek (OBJECT:([unt3].[dbo].[_AccRg7172].[_AccRg7172_ByPeriod_TRN] AS [T1]), SEEK:([T1].[_Fld10847]=[@P1]) ORDERED FORWARD) Сразу видим, что в плане используется другой оператор. Посмотрим на текст запроса, как он попадает в RPC:Completed51.41 exec sp_executesql N'SELECT T1._Period, T1._RecorderTRef, T1._RecorderRRef, T1._LineNo, T1._Active, T1._AccountDtRRef, T1._AccountCtRRef, T1._Fld7173RRef, T1._Fld7174DtRRef, T1._Fld7174CtRRef, T1._Fld7175DtRRef, T1._Fld7175CtRRef, T1._Fld7176, T1._Fld7177Dt, T1._Fld7177Ct, T1._Fld7178Dt, T1._Fld7178Ct, T1._Fld7179Dt, T1._Fld7179Ct, 50 51 В примерах планов в этой главе выводятся только первые 3 столбца. На самом деле их больше, но нам сейчас и важны только первые 3. Собственно запрос начинается со слова SELECT. Инструкции 97 T1._Fld7180Dt, T1._Fld7180Ct, T1._Fld7181Dt, T1._Fld7181Ct, T1._Fld7182, T1._Fld7183 FROM _AccRg7172 T1 WITH(NOLOCK) WHERE (T1._Fld10847 = @P1)',N'@P1 numeric(1)',0 То, что «*» заменена на перечень полей, это нормально. Но откуда взялось условие по полю _Fld10847? Понятно, что это из-за него мог быть выбран другой оператор. Когда мы рассматривали структуру хранения базы, то обращали внимание, что через метод ПолучитьСтруктуруХраненияБазыДанных() можно получить не только имена таблиц, но и индексы (правда, как было показано, с некоторыми ограничениями), и имена полей. На рис. 3.14.2 показано, как это сделать для расшифровки полей. 98 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 3.14.2. Получение структуры полей в терминах метаданных «1С» Теперь, расшифровав имена полей таблицы _AccRg7172, получим, что поле _Fld10847 – это ОбщийРеквизит.ОбластьДанныхОсновныеДанные. Посмотрев конфигурацию, убеждаемся, что этот общий реквизит там действительно есть. Мы таким образом встретились с работой механизма разделения данных там, где этого совсем не ждали. Нам это, впрочем, сейчас не мешает, и просто примем это как данность. Посмотрим теперь на графический план запроса из примера 2, встав в трассировке на Showplan XML Statistics Profile. Наведя курсор на значок оператора, увидим всплывающую подсказку, как это показано на рис. 3.14.3, которая показывает детали для каждого из операторов. Что собой представляет каждая из строк всплывающей подсказки, описано в таблице 3.14.1. Порядок следования, состав и даже названия этих строк в действительности могут несколько отличаться от примеров, представленных в таблице 3.14.1, например, из-за того, что используется другая версия SQL Server. План запроса состоит из операторов. Фактически план запроса – это дерево физических операторов. Операторы описывают, как SQL Server выполняет запрос. Оптимизатор запросов использует операторы для построения плана запроса, чтобы создать результат, заданный в запросе. Операторы классифицируются как логические и физические. Логические операторы описывают операции реляционной алгебры, используемые для обработки запроса: описывают концепцию, какие действия надо совершить. Физические операторы реализуют действия, описанные логическими операторами. Каждый физический оператор является объектом или процедурой, выполняющей операцию. Физическим операторам соответствует их стоимость. Оптимизатор строит дерево логических операций, а затем, используя подход, основанный на стоимости, подбирает физические операторы в дерево плана. Обычно логическую операцию можно реализовать несколькими способами, используя разные физические операторы. Наоборот, один физический оператор очень редко может реализовывать несколько логических операций. Инструкции Рис. 3.14.3. Графический план запроса и всплывающая подсказка 99 100 Настольная книга 1С:Эксперта по технологическим вопросам Таблица 3.14.1. Дополнительная информация о плане запроса, выводимая в том числе в виде всплывающей подсказки Элемент всплывающей подсказки (англ. и рус.) Physical Operation Физическая операция Logical Operation Логическая операция Actual Rows Фактическое количество строк Estimated I/O Cost Предполагаемая стоимость операций ввода-вывода Estimated CPU Cost Предполагаемая стоимость процессного ресурса Estimated Operator Cost Предполагаемая стоимость оператора Estimated Subtree Cost Предполагаемая стоимость поддерева Estimated Number of Rows Предполагаемое количество строк Estimated Row Size Предполагаемый размер строки ActualRebinds Фактическое число повторных привязок Описание Используемый оператор Логический оператор, который соответствует физическому оператору Фактическое количество строк Приблизительные затраты на выполнение действий ввода-вывода для данной операции. С точки зрения СУБД это значение должно быть как можно меньше Приблизительные затраты на всю работу процессора (CPU) для данной операции Затраты оптимизатора запросов на выполнение этой операции. Затраты на выполнение этой операции в процентном отношении к общим затратам на выполнение запроса отображаются в скобках. С точки зрения СУБД это значение должно быть как можно меньше Общие затраты оптимизатора запросов на выполнение этой и всех предшествующих операций в данном поддереве Ожидаемое количество строк, выдаваемых оператором52 Предполагаемый размер строки, получаемой на выходе оператора (в байтах) Счетчики указывают на число инициализаций физического оператора (вызовов метода Init()). Физический оператор может получать много вызовов Init(), хотя обычно получает лишь один. Графический план отображает нули для действительных ActualRewinds повторных привязок и сбросов на начало, когда те отсутФактическое число сбросов на начало ствуют Ordered Отсортировано или нет Отсортировано Node ID Номер узла (оператора) в плане текущего запроса Идентификатор узла ________________ 52 В MSDN сказано (дословно): «Эта всплывающая подсказка выглядит так же, как Количество строк в реальном плане выполнения». В английской версии: «This ToolTip item displays as Number of Rows in an Actual Execution Plan». Если заранее не знать, о чем речь, смысл фразы может быть понят неоднозначно, даже в английском варианте. Мы понимаем эту фразу так: если вы смотрите реальный (действительный) план выполнения, а не ожидаемый, то вам в поле «Ожидаемое количество строк» будет выведено то же самое, что уже есть в поле «Фактическое количество строк». А чтобы узнать, сколько их ожидалось, нужно смотреть ожидаемый план, например, через событие Showplan XML, которое, как и вообще работу с ожидаемыми планами, мы в этой книге не рассматриваем. Инструкции 101 Наиболее важные для нас операторы Далее рассмотрим наиболее важные для нас операторы, разбитые по способу выполнения ими действий. Сканирующие операторы Сканирование – это получение всех записей. Разница состоит только в том, что именно проходится: кластерный индекс, некластерный индекс или сама таблица. Просмотрев все записи, сканирующие операторы возвращают ту их часть, которая подходит под условие, если оно задано необязательным предикатом WHERE:(). Детали по таким операторам приведены в таблице 3.14.2. Пример плана можно посмотреть в этой главе выше (см. пример 1). Таблица 3.14.2. Сканирующие операторы плана запроса Значок Название Описание Оператор Clustered Index Scan сканирует кластерный индекс, указанный Clustered Index в столбце Argument53. Clustered Index Scan является логическим и физичеScan ским оператором Оператор Index Scan получает все записи некластерного индекса, указанного Index Scan в столбце Argument. Index Scan является логическим и физическим оператором Оператор Table Scan получает строки из таблицы, указанной в столбце Table Scan Argument плана выполнения запроса. Table Scan является логическим и физическим оператором Опасность сканирования состоит в двух вещах: времени выполнения (особенно для Table Scan) и избыточных блокировках. Время выполнения операторов сканирования линейно растет с ростом сканируемых объектов. Сканирование не приводит к избыточным блокировкам в двух случаях: ■■ ■■ на самом деле нужна вся таблица; сканируется временная таблица; тогда, если посмотреть на объект, будет видно, что она временная: Table Scan OBJECT:([tempdb].[dbo].[#tt3] AS [T2]) [T2].[_Q_000_F_000RRef], [T2].[_Q_000_F_001] План запроса может считаться неоптимальным, если в нем встречается оператор сканирования, и при этом: время выполнения оператора очень большое, как в абсолютном, так и в процентном выражении (в книге «Профессиональная разработка...» в качестве заслуживающей внимания называется величина, превышающая 20 % от общего времени); ________________ ■■ 53 Здесь и далее: столбец Argument выводится в Showplan Statistics Profile, но из-за большой длины строк мы не имеем возможности приводить его в примерах. Однако, с чем идет работа, можно понять и из столбца StmtText в Showplan Statistics Profile, а в графическом плане – из поля «Объект» («Object»). 102 Настольная книга 1С:Эксперта по технологическим вопросам количество строк, возвращаемых оператором, несопоставимо меньше количества строк в таблице; ■■ количество строк, возвращаемых оператором, может быть, и не намного меньше количества строк в таблице, но установлено, что конфликты блокировок возникают именно из-за избыточного блокирования не используемых на самом деле строк. Особо следует указать оператор Constant Scan. В основном потому, что из-за его имени ему могут приписывать несвойственную ему функциональность. Подробности приведены в таблице 3.14.3. ■■ Таблица 3.14.3. Оператор Constant Scan Значок Название Constant Scan Описание Оператор Constant Scan вводит в запрос одну или несколько константных строк. После выполнения оператора Constant Scan часто используется оператор Compute Scalar, который добавляет столбцы в строки, полученные в результате выполнения оператора Constant Scan. Оператор Constant Scan никак не связан с таблицей (таблицами) констант «1С» Операторы поиска по индексу Эти операторы первоначально считывают только строки, найденные по индексу с указанным в предикате SEEK:() условием поиска. Если этого не хватает для полного выполнения условий, может включаться необязательный предикат WHERE:(), в котором подсистема хранилища вычисляет выражение для всех строк, удовлетворяющих предикату SEEK:(). Предикат WHERE:() уже не использует индекс. Детали по таким операторам приведены в таблице 3.14.4. Примеры плана можно посмотреть в этой главе выше (см. пример 2) и ниже (см. примеры 3 и 4). Таблица 3.14.4. Операторы плана запроса, использующие поиск по индексу Значок Название Clustered Index Seek Index Seek Описание Оператор Clustered Index Seek использует поисковые возможности индексов для получения строк из кластерного индекса, указанного в столбце Argument. Clustered Index Seek – это логический и физический оператор Оператор Index Seek использует возможности поиска по индексам для получения строк из некластерного индекса, указанного в столбце Argument. Index Seek является логическим и физическим оператором Оператор поиска по индексу может приводить к избыточным блокировкам, если в нем есть необязательный предикат WHERE:(), потому что в этом случае все равно блокируются все строки, прочитанные по условию предиката SEEK:(). План запроса может считаться неоптимальным, если в нем встречается оператор поиска по индексу, и при этом: ■■ ■■ количество строк, возвращаемых оператором по совокупности условий предикатов SEEK:() и WHERE:(), несопоставимо меньше количества строк, возвращаемого только по условию предиката SEEK:(), см. пример 4; количество строк, возвращаемых оператором по совокупности условий предикатов SEEK:() и WHERE:(), может быть и ненамного меньше количества строк, возвращаемого только по условию предиката SEEK:(), но установлено, что Инструкции 103 конфликты блокировок возникают именно из-за избыточного блокирования не используемых на самом деле строк. Пример 3 В той же самой базе «Бухгалтерии предприятия» выполним запрос: ВЫБРАТЬ * ИЗ РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный ГДЕ Хозрасчетный.Период = &Период У основной таблицы регистра бухгалтерии, с которой мы работаем, есть подходящий54 индекс (Разделитель данных) + Период + Регистратор + НомерСтроки. Все условия могут быть проверены с помощью этого кластерного индекса. План запроса:42 Rows ---17 Executes StmtText --------------1 Clustered Index Seek(OBJECT:([unt3].[dbo].[_AccRg7172].[_AccRg7172_ByPeriod_TRN] AS [T1]), SEEK:([T1].[_Fld10847]=[@P1] AND [T1].[_Period]=[@P2]) ORDERED FORWARD) Пример 4 Допишем еще одно условие в запрос: ВЫБРАТЬ * ИЗ РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный ГДЕ Хозрасчетный.Период = &Период И Хозрасчетный.НомерСтроки = 3" У основной таблицы регистра бухгалтерии, с которой мы работаем, как говорилось выше, есть кластерный индекс (Разделитель данных) + Период + Регистратор + НомерСтроки. Но поля не идут подряд, то есть между ними «вклинивается» поле Регистратор, не участвующее в условии запроса. Поэтому оптимизатор добавляет предикат WHERE:(). План запроса: Rows ---1 Executes -------1 StmtText -------Clustered Index Seek (OBJECT:([unt3].[dbo].[_AccRg7172].[_AccRg7172_ByPeriod_TRN] AS [T1]), SEEK:([T1].[_Fld10847]=[@P1] AND [T1].[_Period]=[@P2]), WHERE:([unt3].[dbo].[_AccRg7172] .[_LineNo] as [T1].[_LineNo]=[@P3]) ORDERED FORWARD) Как было видно из примера 3, по условию из предиката SEEK:() считываются и блокируются 17 строк. Из результатов текущего запроса видно, что по совокупности условий предикатов SEEK:() и WHERE:() на самом деле нужна только одна строка, то есть запрос приводит к избыточным блокировкам. 17 строк это само по себе не много, но это число может расти. План запроса при этом нельзя считать неоптимальным: видно, что оптимизатор действительно сделал все, что мог, и виноват в избыточных блокировках не план, а автор запроса. 54 Подходящим является индекс, удовлетворяющий следующим требованиям: 1. Индекс содержит все поля, перечисленные в условии. 2. Эти поля находятся в самом начале индекса. 3. Эти поля идут подряд, то есть между ними не «вклиниваются» поля, не участвующие в условии запроса. Об этом еще будем говорить в разделе 4.20, посвященном оптимизации запросов. 104 Настольная книга 1С:Эксперта по технологическим вопросам Операторы соединения Эти операторы выполняют логические операции соединения результатов выполнения других операторов, также интерпретируемых как таблицы. Обычно рассматриваются в противопоставлении: Nested Loops (вложенные циклы, вложенные петли) либо любой другой оператор соединения, одним из которых является оператор Merge Join. Детали по этим операторам приведены в таблице 3.14.5. Таблица 3.14.5. Операторы соединения Значок Название Nested Loops Merge Join Описание Оператор Nested Loops выполняет логические операции внутреннего соединения, левого внешнего соединения, левого полусоединения и антилевого полусоединения55. Операции соединения вложенных циклов выполняют поиск во внутренней таблице для каждой строки внешней таблицы. Возвращается результат выполнения логической операции над любыми строками, удовлетворяющими необязательному предикату в столбце Argument. Nested Loops является физическим оператором Оператор Merge Join выполняет внутреннее соединение, левое внешнее соединение, левое полусоединение, левое антиполусоединение, правое внешнее соединение, правое полусоединение, правое антиполусоединение, а также логические операции соединения. В столбце Argument оператор Merge Join содержит предикат MERGE:(), если операция устанавливает соединение «один ко многим», или предикат MANYTO-MANY MERGE:(), если операция устанавливает соединение «многие ко многим». Столбец Argument содержит также список столбцов, используемых для выполнения операции с разделителями-запятыми. Соединение слиянием особенно эффективно в случаях, когда явной сортировки не требуется, например, когда в базе данных имеется подходящий индекс, Merge Join является физическим оператором Nested Loops – самый простой способ соединения таблиц. Затраты на его выполнение минимальны. Из-за этого оптимизатор SQL Sever использует этот оператор всегда, когда не может определить, как именно правильнее соединять таблицы. Это может происходить просто по ошибке, но обычно причина все-таки есть. Такой причиной может быть неактуальная статистика. Чаще всего, однако, это не неактуальная статистика, а ее отсутствие, что всегда имеет место, когда в запросе на языке «1С» используются соединения с вложенными запросами, соединения с виртуальными таблицами, подзапросы в условиях или в условиях соединения. Пример 5 В той же самой базе «Бухгалтерии предприятия» выполним запрос: ВЫБРАТЬ * ИЗ РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный ГДЕ Хозрасчетный.Регистратор В (ВЫБРАТЬ Документ.РеализацияТоваровУслуг.Ссылка ИЗ Документ. РеализацияТоваровУслуг) ________________ 55 Непривычные для специалистов по «1С» термины: полусоединение – semi-join возвращает строки только одной из соединяемых таблиц, без выполнения соединения полностью. Антиполусоединение возвращает те строки таблицы, которые не годятся для соединения с другой таблицей; т. е. они в обычном внешнем соединении выдавали бы NULL. Инструкции 105 В условии используется подзапрос, поэтому логично ожидать появления оператора Nested Loops. Планы показаны на рисунках 3.14.4 и 3.14.5. Рис. 3.14.4. Текстовый план запроса для примера 5 (фрагмент) Рисунок 3.14.5. Графический план запроса для примера 5 Недостаток использования оператора Nested Loops заключается в том, что при соединении таблиц запрос к внутренней (в обоих планах ниже расположенной) таблице выполняется столько раз, сколько строк во внешней (выше расположенной). Если речь идет о соединении таблиц, по которым нет статистики, вся работа предоставлена на волю случая (это на самом деле и произошло в примере), что может прямо явиться причиной критической деградации производительности при выполнении таких запросов. В текстовой форме плана запроса в примере видно, что запрос в самой нижней строчке выполняется 51 раз, при этом он возвращает 51 строку, то есть 1 строку за обращение. Тот самый случай: 51 раз ходить к шкафу, доставая оттуда по листочку. Кроме того, с ростом базы верхняя таблица может становиться все больше, и это является объективным фактором роста вероятности деградации производительности. Пример 6 В заключение продемонстрируем, как работает другой способ соединения. Для этого выполним запрос: ВЫБРАТЬ Хозрасчетный.*, ХозрасчетныйСубконто.* ИЗ РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Субконто КАК ХозрасчетныйСубконто ПО Хозрасчетный.Период = ХозрасчетныйСубконто.Период И Хозрасчетный.Регистратор = ХозрасчетныйСубконто.Регистратор И Хозрасчетный.НомерСтроки = ХозрасчетныйСубконто.НомерСтроки Планы показаны на рис. 3.14.6 и 3.14.7. Рис. 3.14.6. Текстовый план запроса для примера 6 (фрагмент) 106 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 3.14.7. Графический план запроса для примера 6 Такое соединение работает хорошо, даже несмотря на значительно больший, чем в предыдущих примерах, размер таблиц, с которыми приходится иметь дело, потому что каждый оператор выполняется только по одному разу. 3.15. Особенности чтения в объектной модели Собственно, чтение в объектной технике – это запрос к базе, текст которого генерируется платформой. Если, например, выполнять такой запрос в цикле, это будет ничуть не меньшая, а иногда даже более серьезная ошибка, чем выполнение запроса, написанного на языке запросов. У чтения в объектной модели есть три особенности. 1. Иногда ставятся управляемые блокировки. 2. Иногда чтение происходит в неявной транзакции. 3. Считываются все данные. Разберем их по очереди. 1. Иногда ставятся управляемые блокировки. Как указано в разделе 3.8 «Сведения о блокировках «1С», платформой устанавливаются управляемые разделяемые блокировки при чтении в объектной технике следующих видов объектов: набор записей регистра сведений, ■■ набор записей регистра накопления, ■■ набор записей регистра бухгалтерии, ■■ набор записей регистра расчета, ■■ набор записей перерасчета, ■■ набор записей последовательности. 2. Иногда чтение происходит в неявной транзакции.43 ■■ Как указано в разделе. 3.6, чтение в объектной технике объектов, имеющих табличные части56, будет выполняться в неявной транзакции. Например, запрос 56 Анонсирован отказ от использования транзакций для этих целей в будущем, но есть ожидания, что на многих продуктивных системах еще на какое-то время сохранится существующее положение дел. Инструкции 107 ДокументПроведен = ДокументСсылка.Проведен; выполнится в транзакции, если для документа данного типа в конфигураторе определена табличная часть, но этот же запрос будет выполняться вне транзакции, если табличных частей у документа нет. 3. Считываются все данные. Если посмотреть с помощью замера на отладчике, как выполняется следующий код, то можно увидеть, что основное время всегда тратится на выполнение первой строки: ДокументПроведен = ДокументСсылка.Проведен; ДокументДата = ДокументСсылка.Дата; ДокументНомер = ДокументСсылка.Номер; Если пройти код пошагово отладчиком и при этом посмотреть трассировку в профайлере SQL Server, можно увидеть, что запрос (если есть еще и табличная часть, то несколько запросов в транзакции) выполняется только на первой строке, при этом тексты запросов содержат имена всех реквизитов и все табличные части. На второй и на третьей строке запросы к базе уже не выполняются. На практике это приводит к следующему: если реквизит имеет тип ХранилищеЗначения и в конкретном документе хранится файл размером 500 МБ, то при первом чтении любого реквизита этого документа будет происходить считывание этого файла со всеми сопутствующими затратами времени; ■■ если объект имеет табличную часть размером в 50 000 строк, то при первом чтении любого реквизита этого документа будет происходить считывание всех реквизитов всех табличных частей со всеми сопутствующими затратами времени; ■■ если вы пытаетесь избавиться от запроса в цикле, в топе будет только одна строка (первое получение реквизита), далее топ-строка в отладчике будет переползать с вызова одного реквизита на другой до тех пор, пока вы не избавитесь от получения в цикле всех реквизитов. По совокупности особенностей можно дать как минимум следующие рекомендации: ■■ 1. Не делать у объектов реквизитов с типом ХранилищеЗначения, особенно не допускать этого в табличных частях. Следует использовать отдельные справочники для установки соответствия ссылки и хранилища, а в реквизитах объектов хранить ссылки. 2. Если не получается отказаться от использования запросов к базе из обработчиков событий ПриВыводеСтроки и ПриПолученииДанных, то по крайней мере следует получать эти данные запросом на языке запросов, а не через объектную модель. Код увеличится в объеме, но выиграет в скорости и перестанет генерировать транзакции. 108 Настольная книга 1С:Эксперта по технологическим вопросам 3.16. Работа с SQL Server. Где хранятся временные таблицы. Где хранятся снимки Snapshot для уровня изоляции Read Committed Snapshot Временные таблицы хранятся в базе Tempdb. Снимки Snapshot для уровня изоляции Read Committed Snapshot хранятся там же. Tempdb – это служебная база SQL Server. Ее расположение при установке по умолчанию показано на рисунках 3.16.1 и 3.16.2. Ее можно перенести в другое место (как это сделать, см. раздел 3.17 «Работа с SQL Server. Где размещать базы. Как переносить базы»). Рис. 3.16.1. Хранение и свойства базы tempdb и ее журнала транзакций в файловой системе, см. файлы tempdb.mdf и templog.ldf Инструкции 109 Рис. 3.16.2. Представление базы tempdb в Management Studio 3.17. Работа с SQL Server. Где размещать базы. Как переносить базы При создании базы средствами «1С» она создается в каталоге по умолчанию. Каталог по умолчанию задается в свойствах сервера SQL. Для этого нужно открыть Management Studio, в обозревателе объектов на имени сервера правой кнопкой мыши вызвать контекстное меню, выбрать Свойства (Properties), перейти на страницу Параметры базы данных (Database settings), отредактировать поля Места хранения, используемые базой данных по умолчанию (Database default locations). Базу можно перенести в другой каталог или на другой диск (как это сделать, описано в этом же разделе ниже). Прежде чем поднимать вопрос о размещении баз, отличающемся от расположения по умолчанию, необходимо понять, для чего конкретно это нужно. В работающих продуктивных системах всегда есть возможность понять, чего не хватает: ■■ если задача не успевает выполниться за отведенное время даже в однопользовательском режиме, то не хватает скорости собственно диска с накладными расходами на передачу данных до него и с него; 110 Настольная книга 1С:Эксперта по технологическим вопросам задача не успевает выполниться за отведенное время только в многопользовательском режиме – не хватает параллельно работающих дисков; причем речь может идти и про параллельно работающие диске в массиве, и про разные диски под разные базы, и про разнесение базы и журнала транзакций. При построении архитектуры новой системы понятно, что найти узкие места из постановки задачи возможно не всегда, и подходящие для всех ветки алгоритма выбора дисковой подсистемы нарисовать не выйдет. ■■ Правильным подходом можно считать следующий: выбрать гарантированно неошибочный вариант, начать работать на нем и затем с учетом фактических узких мест искать пути по их расшивке исходя из имеющихся возможностей. Для баз в тестовых средах, когда конкретика неясна, гарантированно неошибочным подходом мы считаем следующий: если нам дают возможность выбирать, мы выбираем RAID 10 (1+0), находящийся в нашем монопольном владении, и размещаем на нем все базы; ■■ во всех других случаях при наличии выбора – работать на простых дисках или на массиве, выбираем диски без RAID, если: □□ диски без RAID будут у нас в монопольном владении, а RAID придется делить с кем-то еще57; 44 □□ RAID заведомо медленный (5 и 6); □□ не понимаем, кто и в какие сроки восстановит информацию средствами RAID; □□ понимаем, кто и в какие сроки восстановит информацию средствами RAID, но видим, что восстановление с бэкапа быстрее и дешевле (бэкап всегда храним на другом носителе!); □□ имеем дело с RAID 0 для чего-то, кроме Tempdb. Если после анализа выясняется, что базу имеет смысл перенести, можно заняться переносом. Если база переносится в порядке эксперимента, необходимо обеспечить замеры объективных показателей, позволяющих сравнивать работу до и после переноса. ■■ Чтобы перенести базу Tempdb, нужно сделать следующее: 1. Создать каталог, в котором хотим ее видеть (например, C:\TEMPDB). 2. Войти в Management Studio, выполнить запрос, убедиться, что он успешно отработал: USE master GO ALTER DATABASE tempdb MODIFY FILE (NAME = tempdev, FILENAME = 'C:\TEMPDB\tempdb.mdf') 57 При выделении места на СХД и в других случаях на дисках под управлением средств виртуализации основное условие, чтобы аппаратные ресурсы, «нарезанные» виртуализацией, были закреплены за нами «жестко», без динамического перераспределения, и чтобы никто, кроме нас, с этими аппаратными ресурсами не работал. В противном случае мы не сможем адекватно оценить загрузку дисковой подсистемы и в некоторых ситуациях окажемся заложниками посторонней активности. Инструкции 111 GO ALTER DATABASE tempdb MODIFY FILE (NAME = templog, FILENAME = ' C:\TEMPDB\templog.ldf') GO 3. Перезапустить SQL Server. 4. Убедиться, что в новом каталоге появились нужные файлы, и удалить файлы, оставшиеся от Tempdb из прежнего каталога. Чтобы перенести любую пользовательскую (не служебную) базу, нужно сделать следующее: 1. Создать бэкап. 2. Убедиться, что с базой никто не работает. 3. В Management Studio вызвать правой кнопкой мыши контекстное меню на имени нужной базы, выбрать Задачи (Tasks) – Отсоединить (Detach) и далее нажать ОК. 4. Переместить файлы базы и журнала транзакций в нужный каталог. 5. В Management Studio вызвать правой кнопкой мыши контекстное меню на узле базы данных (Databases), выбрать Присоединить (Attach), в поле Базы данных для присоединения (Databases to attach) добавить новый путь, убедиться, что база и сведения соответствуют переносимой, и далее нажать ОК. Чтобы перенести только файл журнала транзакций, нужно сделать следующее: 1. Создать бэкап. 2. Убедиться, что с базой никто не работает. 3. В Management Studio вызвать правой кнопкой мыши контекстное меню на имени нужной базы, выбрать Задачи (Tasks) – Отсоединить (Detach) и далее нажать ОК. 4. Переместить файл журнала транзакций в нужный каталог. 5. В Management Studio вызвать правой кнопкой мыши контекстное меню на узле базы данных (Databases), выбрать Присоединить (Attach). 5.1. В поле Базы данных для присоединения (Databases to attach) добавить новый путь, убедиться, что база и сведения соответствуют переносимой. 5.2. В поле Сведения о базе данных (Database details) изменить путь к файлу журнала транзакций на новый. 5.3. Нажать ОК. 112 Настольная книга 1С:Эксперта по технологическим вопросам 3.18. Работа с SQL Server. Различия между полной (FULL) и простой (SIMPLE) моделями восстановления базы. Особенности сжатия журнала транзакций SQL Server поддерживает 3 модели восстановления базы: полная (FULL). Требует резервного копирования журнала транзакций и обеспечивает возможности для этого; ■■ с дополнительным протоколированием (BULK_LOGGED). «Тяжелые» (BULK) операции протоколируются по минимуму, и поэтому под их логирование задействуется меньше места. «Обычные» операции протоколируются так же, как в полной модели; ■■ простая (SIMPLE). Резервных копий журналов транзакций нет, операции по управлению ими не поддерживаются. Для каждой из этих моделей имеются доводы за и против, исходящие только из того, какие резервные копии возможны (или необходимы) и на какие моменты времени нужно иметь возможность восстановления. ■■ Если вы не намерены использовать резервные копии журнала и вам не нужна возможность восстановления состояния базы данных на точно определенный момент времени, не следует использовать модель восстановления FULL. На практике это в первую очередь относится к тестовым базам, а также (внимание!) к ЦУП. Это так, поскольку места под журналы транзакций там может требоваться очень много, но крайне малореальна ситуация, что кто-то станет пытаться восстанавливать базу ЦУП по журналу транзакций на момент середины анализа. Достаточно полных копий (или dt) на момент начала анализа (для ЦУП) или начала теста (для тестовых баз). Для общего понимания, как работает журнал транзакций, надо представлять, что в действительности до тех пор, пока записи в его начале получается обрезать (или очищать), он является кольцевым файлом. Если это получается, то, когда процедура ведения журнала достигает конца журнала транзакций, она снова поворачивает в начало и начинает писать поверх того, что было там ранее. Запись перестает быть нужной, если для нее истинно все из нижеперечисленного: ■■ ■■ ■■ транзакция, к которой относится эта запись, зафиксирована; все измененные ею страницы базы записаны на диск; запись лога не нужна для бэкапа (полного, разностного или бэкапа журнала); Инструкции 113 запись лога не нужна компонентам, читающим журнал (таким как зеркалирование58 или репликация).45 Третий пункт списка выше очень важен для понимания следующего: ■■ в полной модели записи журнала транзакций хранятся до тех пор, пока они нужны для бэкапа. Чтобы снять необходимость их хранения, нужно сделать бэкап журнала транзакций59;46 ■■ в простой модели хранится только то, что нужно для текущей жизни, а не для бэкапа. Также он подводит к пониманию, почему: ■■ интенсивность записи журнала на диск для моделей с неполным протоколированием (BULK_LOGGED) и модели простой (SIMPLE) не различается вообще; ■■ интенсивность записи журнала на диск для моделей полная (FULL) и простая (SIMPLE) (как и с дополнительным протоколированием (BULK_LOGGED)), различается только для «тяжелых» (BULK) операций, которые для большинства случаев в «1С» можно пересчитать по пальцам (загрузка из dt, реструктуризация таблиц, перестроение индекса). Таким образом, переключение модели не прибавляет и не отнимает производительности, если речь идет об информационных системах на платформе «1С:Предприятие». Речь только о месте на диске. ■■ И еще выходит, что оснований для использования модели с дополнительным протоколированием (BULK_LOGGED) в информационных системах на платформе «1С:Предприятие» почти нет, поэтому про нее далее не пишем. Нужно выбирать из полной (FULL) или простой (SIMPLE) моделей. Модель восстановления можно указать в Management Studio, вызвав правой кнопкой мыши контекстное меню на имени нужной базы, выбрав Свойства (Properties) и перейдя на страницу Параметры (Options). Нужное значение задается в поле Модель восстановления (Recovery model), см. рис. 3.18.1. Обратите внимание также на поле Автоматическое сжатие (Auto shrink). MSDN рекомендует не трогать этот параметр, оставив его в False. Модель восстановления базы данных можно в любой момент переключить с полной на простую и обратно. При этом надо придерживаться простых правил: 1. 58 59 Перед переключением с модели полного восстановления создать резервную копию журнала транзакций. Зеркалирование поддерживается только для полной (FULL) модели. Именно бэкап журнала транзакций, а не полную резервную копию. 114 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 3.18.1. Изменение модели восстановления базы 2. После переключения с простой модели восстановления: □□ сразу же после переключения на модель полного восстановления создать полную или разностную резервную копию базы данных, чтобы начать цепочку журналов. Переключение на модель полного восстановления вступает в силу только после создания первой резервной копии данных; □□ создать в планах обслуживания регулярное резервное копирование журнала. Если резервные копии журнала создаются недостаточно часто, журнал транзакций может разрастаться до тех пор, пока не переполнит диск. 3. После переключения на простую модель восстановления: □□ отменить все запланированные задания резервного копирования журнала транзакций; □□ убедиться, что запланировано периодическое резервное копирование базы данных. Резервное копирование базы данных очень важно как для защиты данных, так и для усечения (truncation) неактивной части журнала транзакций. Теперь рассмотрим сжатие журнала транзакций. Если вам известно, что файл журнала транзакции содержит неиспользуемое пространство, которое вам Инструкции 115 не нужно, можно освободить его, уменьшив размер журнала. Этот процесс называется сжатием (Shrink) файла журнала. Выполнить его можно в Management Studio, вызвав правой кнопкой мыши контекстное меню на имени нужной базы: Задачи (Tasks) – Сжать (Shrink) – Файлы. Дальше в поле Тип файла (File type) выбрать Журнал (Log). Остальные настройки можно оставить по умолчанию, как на рис. 3.18.2, после чего нажать ОК. Рис. 3.18.2. Настройки по умолчанию для сжатия журнала транзакций Сжатие может производиться только в том случае, если база данных находится в оперативном режиме и пока свободен хотя бы один виртуальный файл журнала (что это такое, см. TechNet). Важно то, что в ряде случаев сжатие невозможно до тех пор, пока не выполнена следующая операция усечения (truncation) журнала. Принудительно усечение можно попробовать выполнить при использовании простой модели восстановления, создав резервную копию базы данных, при использовании модели полного восстановления – резервную копию журнала транзакции, потому что обычно усечение при выполнении этих действий происходит автоматически. Если же сжатие не выполнится с первого раза с нужным эффектом (сжатие ждет усечения, а усечение может быть отложено по ряду причин, см. TechNet), на практике достаточно немного подождать и повторить создание копии нужного вида и сжатие. 116 Настольная книга 1С:Эксперта по технологическим вопросам На практике различия можно увидеть следующим образом. Для базы, использующей модель FULL, создадим полную резервную копию. Размеры файлов показаны на рис. 3.18.3. Рис. 3.18.3. Начальное состояние Выполним перепроведение документов Расходный кассовый ордер с помощью групповой обработки справочников и документов, как показано на рис. 3.18.4. Рис. 3.18.4. Выполнение групповой обработки Инструкции 117 После ее выполнения свойства файлов будут выглядеть, как показано на рис. 3.18.5. Рис. 3.18.5. Свойства файлов базы и журнала транзакций после выполнения действий в базе с полной моделью восстановления Мы попытались создать резервную полную копию базы, но сжать журнал транзакций это почти не помогло (см. рис. 3.18.6). Рис. 3.18.6. Размер журнала транзакций после сжатия без предшествующего ему создания резервной копии журнала транзакций Если же создать резервную копию журнала транзакций и попытаться сжать журнал транзакций, размер его файла изменится значительно (см. рис. 3.18.7). Рис. 3.18.7. Размер журнала транзакций после сжатия с предшествующим ему созданием резервной копии журнала транзакций 118 Настольная книга 1С:Эксперта по технологическим вопросам Восстановим базу на начало эксперимента, см. рис. 3.18.8 (сравните с рис. 3.18.3). Рис. 3.18.8. Базу вернули в исходное состояние Далее базу переведем на использование простой модели восстановления (см. рис. 3.18.1) и выполним в ней те же самые действия (см. рис. 3.18.4). Размер файла базы и дата его изменения изменятся, размер и дата изменения журнала транзакций – нет (см. рис. 3.18.9). Рис. 3.18.9. Свойства файлов базы и журнала транзакций после выполнения действий в базе с простой моделью восстановления 3.19. Работа с SQL Server. Настройка и использование бэкапов различных видов SQL Server позволяет делать резервные копии трех видов: полную (full)60;47 ■■ разностную (differential). Грубо говоря, в разностной копии хранится разница между текущим состоянием базы и ее состоянием на момент полной копии; ■■ копию журнала транзакций (не используется и не поддерживается для базы при простой модели восстановления). Наглядно это видно, например, при настройке плана обслуживания через мастер планов обслуживания (см. рис. 3.19.1). Запустить мастер можно в Management ■■ 60 Не путать с одноименной моделью восстановления. Инструкции 119 Studio, вызвав правой кнопкой мыши контекстное меню на узле Планы обслуживания (Maintenance plans) в ветке Управление (Management), см. рис. 3.19.2. Рис. 3.19.1. Этап настройки плана обслуживания Сделать планы обслуживания для операций создания резервных копий удобнее, чем каждый раз вызывать их из меню, даже если план обслуживания вызывается не по расписанию, а только принудительно. Рис. 3.19.2. Узел «Планы обслуживания» с планами создания резервных копий разных видов 120 Настольная книга 1С:Эксперта по технологическим вопросам Для работы с ними нужно понимать следующее. Восстановить базу при простой модели восстановления можно на строго фиксированные точки с помощью: полной копии; ■■ полной копии и одной разностной копии из числа ее «наследниц»61, являющейся последней перед требуемой точкой восстановления.48 Применительно к тестовым системам и к ЦУП это означает, что необязательно делать и хранить полную копию базы после каждого теста. Можно существенно сэкономить место на диске, используя разностные копии. Из минусов – требуется как минимум ведение журнала учета копий и мест их хранения, иначе можно запутаться. ■■ Применительно к продуктивным системам использование разностных копий также позволяет экономить время на проведение копирования и уменьшать износ резервных носителей. Восстановить базу при полной модели восстановления можно аналогично простой модели на строго фиксированные точки с помощью полной копии или полной копии и одной разностной копии (см. выше). Но также можно это сделать, если к полной копии или полной копии и одной разностной копии добавить цепочку копий журналов транзакций с момента последней полной или разностной копии. Пример такого восстановления показан на рис. 3.19.3. При таком способе база может быть восстановлена как на последнее доступное состояние по этой цепочке, так и на любой момент времени внутри нее. Для этого нужно в поле К моменту времени (To a point in time) (рис. 3.19.3) указать нужное время. После него восстановление записей журнала транзакций остановится. 61 Т. е. разностная копия не должна предшествовать полной, и между ними не должно быть сделано других полных копий. Инструкции 121 Рис. 3.19.3. Пример восстановления базы по нескольким наборам данных Пример хранения файлов резервных копий при установках по умолчанию приведен на рис. 3.19.4. Заметны различия между полными и разностными копиями (размер файлов) и отличие от них копий журналов транзакций (тип и размер файлов). Рис. 3.19.4. Хранение файлов с резервными копиями 122 Настольная книга 1С:Эксперта по технологическим вопросам В заключение следует еще раз обратить внимание на то, что при использовании полной модели восстановления операция резервного копирования журнала транзакций является обязательной для регулярного выполнения, даже если вы не собираетесь делать резервные копии средствами SQL Server (без этого журнал транзакций будет расти, пока не займет весь диск). ГЛАВА 4 Инструкции 4.1. Как настроить сбор информации о загрузке оборудования и как оценить эту загрузку На двух проектах, загрузка оборудования с которых приведена на рис. 4.1.1, были проблемы производительности. Про первый говорили: «У нас сервер перегружен, хотим новый – втрое мощнее». Про второй: «Мы купили новый сервер, он очень хороший». С помощью Performance monitor в простых случаях достаточно контролировать следующие параметры: 1. Memory (Память) – Committed bytes in use (% использования выделенной памяти) – счетчик показывает процент относительно суммы размера оперативной памяти и файла подкачки, а не только использование оперативной памяти. Не должен превышать размер оперативной памяти. 2. Memory (Память) – Available Mbytes (Доступно, Мбайт) – счетчик показывает объем свободной физической оперативной памяти. Приближение к нулю свидетельствует о недостатке оперативной памяти. 3. Processor [_Total] (Процессор [_Total]) – % Processor Time (% загрузки процессора) – рекомендованный максимум – не более 70 % в течение длительного времени. 4. System (Система) – Processor Queue Length (Очередь к процессорам) – рекомендованный максимум – не более 2 * количество ядер процессоров в течение длительного времени. 5. Physical Disk (Физический диск) – Avg. Disk Queue Length (Средняя длина очереди к дискам) – обязательно для системных дисков отдельно, для диска с базой отдельно, для диска с журналом транзакций (если такой есть) отдельно. Рекомендованный максимум – не более 2 * количество дисков, работающих параллельно (при этом всегда надо иметь в виду, что RAID0, обеспечивающий 124 Настольная книга 1С:Эксперта по технологическим вопросам параллельность работы дисков, на дисках с базой собирают крайне редко). На практике этот счетчик достаточно сложно применять при оценке загруженности дискового хранилища. По этой причине этот счетчик может быть заменен на \PhysicalDisk(_Total)\Avg. Disk Sec/Read и \PhysicalDisk(_Total)\ Avg. Disk Sec/Write. При работе с дисковым кешем нормальное время на чтение или запись обычно составляет менее 10 мс. В случае работы с дисками время на чтение или запись не должно превышать 50–200 мс. Если вы видите, что есть периоды, в которые среднее время значительно возрастает и превышает 200 мс, то это серьезный повод задуматься о производительности дискового хранилища, с которым вы работаете. 6. LogicalDisk – % Free Space – показатель наличия свободного места на диске и динамики его изменения. 7. Network Interface (Сетевой интерфейс) – Bytes Total/sec (всего байт/с). Рекомендованный максимум – не более 65 % от пропускной способности адаптера в течение длительного времени. Практика показала, что показатель Memory (Память) – Pages/sec (обмен страниц/с), рекомендованный для контроля достаточности оперативной памяти, слишком часто дает ложноположительное срабатывание. Его можно включать в состав контролируемых параметров (рекомендованная норма – 0, максимум – не более 20), но обращать на него внимание надо по факту постоянно ненулевого значения и в совокупности с параметрами «% использования выделенной памяти» и «Средняя длина очереди к дискам». Тогда будет видно, например, идет ли речь о свопинге. Если же этот показатель имеет высокое среднее значение, но речь идет о «гребенке» из пиков и нулей с интервалом в несколько шагов замера, без загрузки диска и при большом запасе свободной оперативной памяти, то, вероятнее всего, ситуация нормальная, а не проблемная. Важное дополнение: в системах, использующих виртуализацию, надо уточнять, что именно показывают счетчики Performance monitor. На текущий момент для систем Hyper-V они показывают загрузку физического оборудования, а не его виртуальной части. Напротив, для систем VMware они показывают загрузку именно виртуальной машины. Эти уточнения необходимо отслеживать и учитывать при анализе. Инструкции 125 Рис. 4.1.1. Пример неосведомленности сотрудников заказчиков о загрузке оборудования. На нижнем скриншоте средняя длина очереди к диску >50 в течение всего рабочего дня, и сохраняется исключительно высокой, с небольшими перерывами, до 4 утра 126 Настольная книга 1С:Эксперта по технологическим вопросам Если показатели, особенно следующие: % загрузки процессора, средняя длина очереди к дискам, % использования выделенной памяти, превышают рекомендованные максимумы, это означает, что оборудование не справляется с нагрузкой. Надо понимать, что речь идет о систематическом превышении, а не о кратковременных пиках. Кроме того, если вы получили высокие показатели загрузки в период, когда выполнялись заведомо ресурсоемкие операции, например, шло восстановление базы из dt-файла, и вы об этом знаете, то и решение о нехватке мощностей надо принимать с учетом этого. Однако не спешите радоваться, если загрузка близка к нулю. Это может означать следующее: 1. Вы переплатили за оборудование, которое используете всего на 5–10 %. Но это не самое плохое. Следующий пункт намного хуже. 2. В системе есть очень серьезные проблемы параллельности. В этом случае, как правило, есть и другие симптомы, например, ошибки блокировок, о подсчете которых поговорим позже. Можно руководствоваться следующим правилом: если информационная система «1С» работала нормально, а потом стала работать хуже, и если нет явной нехватки производительности оборудования (например, 100 % загрузки процессора в течение длительного времени), то апгрейд оборудования исправить ситуацию не поможет. Это приходится утверждать вопреки распространенной практике. Как настроить сбор логов perfmon (для Windows Server 2008 и Windows 7) 1. Если вы не администратор, попросите включить вас в группы Performance monitor users и Performance log users. 2. Пуск – Выполнить – Perfmon. 3. Группы сборщиков данных – Особый (правой кнопкой) – Создать – Группа Сбор- щиков данных. 4. Ввести имя (например, 1s, как показано на рис. 4.1.2), переключатель установить на Создать вручную (для опытных), нажать Далее. 5. Создать журналы данных – установить флажок на Счетчик производительности, как показано на рисунке 4.1.3, – Далее. 6. Используя кнопку Добавить интерфейсов добавления счетчиков, показанных на рис. 4.1.4, добавить счетчики из списка: □□ Memory (Память) – Committed bytes in use (% использования выделенной памяти); □□ Memory (Память) – Available Mbytes (Доступно, Мбайт); □□ Processor [_Total] (Процессор [_Total]) – % Processor Time (% загрузки процессора); □□ System (Система) – Processor Queue Length (Очередь к процессорам); Инструкции Рис. 4.1.2. Ввод имени группы сборщиков данных Рис. 4.1.3. Выбор типа журнала 127 128 7. 8. 9. Настольная книга 1С:Эксперта по технологическим вопросам □□ Physical Disk (Физический диск) – Avg. Disk Queue Length (Средняя длина очереди к дискам) – обязательно для системных дисков отдельно, для диска с базой отдельно, для диска с журналом транзакций (если такой есть) отдельно; □□ PhysicalDisk (Физический диск) – Avg. Disk Sec/Read (Среднее время чтения с диска в секундах); □□ PhysicalDisk (Физический диск) – Avg. Disk Sec/Write (Среднее время записи на диск в секундах); □□ LogicalDisk (Логический диск) – % Free Space (процент свободного места); □□ Network Interface (Сетевой интерфейс) – Bytes Total/sec (всего байт/с); □□ Memory (Память) – Pages/sec (обмен страниц/с). Если он нужен, см. уточнение в начале главы. Когда набрали все счетчики, нажать ОК и Далее. Если не хотите задать другой путь к файлам логов, предложенный путь оставить как есть, нажать Готово (в некоторых версиях – Далее). Но если вы не администратор, в окне «корневая папка», показанном на рис. 4.1.5, лучше выбрать свою папку для логов там, куда гарантированно есть права на запись, например, в библиотеке «Документы», или на другом, не системном диске, потому что вам, скорее всего, не хватит прав на C:\PerfLogs. Если будет задан дополнительный вопрос, поставить переключатель на СохранитьИЗакрыть, нажать Готово. Инструкции Рис. 4.1.4. Интерфейсы добавления счетчиков Рис. 4.1.5. Назначение папки сохранения логов 129 130 Настольная книга 1С:Эксперта по технологическим вопросам 10. Встать на имя группы сборщиков (1s) – Действие – Пуск (или нажать на зеленую стрелку). Рис. 4.1.6. Запуск группы сборщиков данных 11. После этого, даже если завершить сеанс пользователя, сборщик продолжит работу. 12. Если надо остановить счетчик или отослать файл, там же надо выполнить пункт меню Действия – Стоп (или нажать на черный квадрат рядом с зеленой стрелкой). Для старта перезагружать сервер не требуется. Файлы по умолчанию собираются в папке %systemdrive%\PerfLogs\Admin\1s (это 1s – имя группы сборщиков, заданное выше при настройке) или в папке, которую вы указали в качестве пути в п. 8. Каждый перезапуск счетчика начинает новый файл. Длительность замера при указанных настройках неограниченна – счетчик работает, пока его не остановят или не произойдет перезагрузки сервера. Просматривать записанные логи можно, выбирая нужный файл в качестве источника в свойствах окна: Средства наблюдения – Системный монитор на закладке Источник, как показано на рис. 4.1.7. Аналогичную настройку можно создать, создав и выполнив от имени администратора bat-файл, листинг которого приведен на рис. 4.1.8. При необходимости что-либо изменить или поправить это можно сделать вручную в уже созданной этим bat-файлом группе 1s, используя описанный выше оконный интерфейс. Если нет навыков, но прав хватает, в первый раз настройка может занять полчаса. Собранные за любой период данные можно затем просматривать, в том числе для того, чтобы оценивать их соответствие рекомендованным значениям, приведенным в данном разделе. Инструкции 131 Рис. 4.1.7. Выбор источника данных для анализа @ECHO OFF ECHO Adding counter "1C_counter"... logman create counter 1s –f bincirc -c "\Processor(_Total)\%% Processor Time" "\Memory(_Total)\Pages/sec" "\Memory(_ Total)\%% Committed Bytes In Use" "\Memory(_Total)\Available Bytes" "\System(_Total)\Processor Queue Length" "\ PhysicalDisk(_Total)\Avg. Disk Queue Length" "\PhysicalDisk(*)\Avg. Disk Queue Length" "\Network Interface(*)\Bytes Total/ sec" "\PhysicalDisk(_Total)\Avg. Disk Sec/Read" "\PhysicalDisk(_Total)\Avg. Disk Sec/Write" -si 15 -v mmddhhmm C:\Windows\System32\perfmon.exe ECHO done Рис. 4.1.8. Листинг bat-файла Описанных счетчиков, как правило, хватает для общей оценки загруженности системы. Другие счетчики используются для детального расследования проблем, если установлено, что проблема имеет или может иметь отражение в использовании аппаратных ресурсов. 132 Настольная книга 1С:Эксперта по технологическим вопросам Утилиты сбора информации о загрузке оборудования для других операционных систем49 Для операционных систем Linux и AIX62 нами использовалась утилита nmon. Для операционной системы HP-UX63 мы использовали команды sar и top.50 Для операционной системы Linux по рекомендации из статьи А. Бурмистрова, размещенной на сайте технологических вопросов крупных внедрений, следует использовать утилиту vmstat. Для этого нужно запустить команду со следующими параметрами: vmstat -n 15 480 > StatResult.txt, где: n – предотвращает повторный вывод заголовка; ■■ 15 – информация будет собираться раз в 15 секунд; ■■ 480 – команда будет выполнена 480 раз; ■■ StatResult.txt – результат работы утилиты будет сохранен в файл StatResult.txt. Полученный файл StatResult.txt необходимо проанализировать с помощью любого табличного редактора. ■■ Первую строку после заголовка нужно удалить, т. к. это усредненные статистические данные, собранные с начала работы системы. Нужна следующая информация: среднее значение колонки si, ■■ максимальное значение колонки si, ■■ максимальное значение колонки us, ■■ максимальное значение колонки sy, ■■ среднее значение колонки r, ■■ среднее значение колонки b. В таблице 4.1.1 приведены описания значений и предельные значения для каждого из них. При превышении этих значений следует рассмотреть вопрос об увеличении производительности соответствующего аппаратного компонента. ■■ Для анализа загруженности сети в той же статье рекомендуется использовать утилиту PktStat. PktStat необходимо запускать только под пользователем root. Интересует только один показатель – максимальное количество переданных байт (Max Bps). Таблица 4.1.1. Описание значений и предельные значения показателей производительности, полученных утилитой vmstat Описание Значение Интенсивность обмена Колонка между дисковой подсистемой si и оперативной памятью Загруженность процессоров 62 63 Колонки us и sy Критерий Узкое место Среднее: около 0 Максимальное: не более 20 Недостаточно оперативной памяти Максимальное значение us: не более 70 Максимальное значение sy: не более 35 Недостаточная производительность процессоров На AIX была развернута СУБД IBM DB2. На HP-UX была развернута СУБД Oracle Database. Инструкции Описание Очередь к процессорам Очередь к дискам Скорость передачи данных через сеть Значение Критерий Не более 2 * количество Колонка r ядер процессоров в течение длительного времени Не более 2 * количество Колонка дисков, работающих паралb лельно Max Bps 133 Узкое место Недостаточная производительность процессоров Недостаточная производительность дисковой подсистемы Недостаточная пропускная Не более 65 % от пропускной способность сетевого способности сетевого адаптера интерфейса 4.2. Выяснение скорости диска Если работы ведутся на нескольких стендах, нужно иметь количественные характеристики этих стендов, позволяющие их сравнивать. Это бывает полезно, если одно и то же действие на одном стенде выполняется в несколько раз быстрее, чем на другом, и нужно понять, в чем между ними разница. Процессорные мощности, объем оперативной памяти, параметры сетевого адаптера – все это можно определить по характеристикам оборудования. Производительность же дисковой подсистемы требуется определять экспериментально. Партнерам, участвующим в проекте ЦКТП, известна утилита SQLIO (также известная как disk.zip). SQLIO – это очень простой инструмент эталонного тестирования производительности операций ввода – вывода дисковой подсистемы для SQL Server. Этот инструмент доступен для свободного скачивания и применения всем легальным пользователям SQL Server. Инструмент разработан сотрудником Microsoft – Gert E.R. Drapers. Устанавливать его можно практически на всех операционных системах Windows, начиная с Windows 2000 и Windows XP, и в том числе на 64-разрядных системах. Скачать его можно с сайта Microsoft. Запуск: 1. Запустить файл SQLIO.bat. 2. Примерно через 30 минут результат будет показан на экране в виде диалогового окна. Будут отображены два показателя: Скорость чтения MB/sec и Скорость записи MB/ sec. Настройка: по умолчанию замеряется скорость для логического диска С. Чтобы измерить скорость другого диска, нужно внести изменения в файл param.txt. 134 Настольная книга 1С:Эксперта по технологическим вопросам 4.3. Настройка автоматического перезапуска сервера «1С» Перезапуск средствами платформы Рабочие процессы сервера «1С» перезапускать надо регулярно. Это простое действие позволяет обходить достаточно большое количество неприятных проблем. И, наоборот, от того, что процессы «1С» работают в непрерывном режиме месяцами, никаких бонусов нет. На рис. 4.3.1 показано меню настройки свойств локального кластера для платформы «1С:Предприятие» версии 8.3. Рис. 4.3.1. Свойства локального кластера Секция «Перезапускать рабочие процессы» позволяет настроить их автоматический перезапуск. Инструкции 135 Описание параметров (с ИТС): «Интервал перезапуска __ секунд Интервал времени после запуска процесса, по истечении которого рабочий процесс перезапускается. Нулевое значение означает, что рабочие процессы не будут перезапускаться автоматически. Допустимый объем памяти __ KB Устанавливает предельный объем виртуального адресного пространства, после постоянного превышения которого в течение определенного времени (см. следующий параметр) рабочий процесс будет автоматически перезапущен. Нулевое значение означает, что критический объем памяти не задан и автоматический перезапуск рабочих процессов не выполняется. Интервал превышения допустимого объема памяти __ секунд Определяет интервал времени постоянного превышения предельного объема виртуального адресного пространства, занимаемого рабочим процессом (см. предыдущий параметр), после которого выполняется автоматический перезапуск рабочего процесса. Нулевое значение означает, что автоматически перезапуск рабочих процессов не выполняется. Выключенные процессы останавливать через __ секунд Интервал времени, по истечении которого выключенный рабочий процесс принудительно останавливается, независимо от наличия соединений. Работа всех соединений с этим процессом завершается аварийно. Значение свойства может быть изменено во время работы кластера. Нулевое значение означает, что принудительное завершение процесса не выполняется. Уровень отказоустойчивости Уровень отказоустойчивости определяет максимальное количество рабочих серверов, входящих в состав кластера, одновременный выход из строя которых не приведет к аварийному завершению сеансов подключенных пользователей. <...> (появилось в 8.3. Для системы из одного сервера «1С» нет смысла ставить не 0. Более подробное описание данного свойства см. на ИТС. – Примеч. авт.). Режим распределения нагрузки Параметр определяет, по какому критерию будет выбираться рабочий процесс при установке нового соединения. <...> (появилось в 8.3. Допускается выбор: приоритет по производительности или приоритет по памяти. Более подробное описание данного свойства см. на ИТС. – Примеч. авт.). Перезапуск службы средствами операционной системы Если по каким-то причинам требуется настроить перезапуск служб средствами операционной системы, а не использовать штатную перезагрузку средствами платформы, сделать рестарт службы можно через планировщик задач с помощью команд "net start" и "net stop". Перезапускаться в этом случае будет агент, а не рабочие процессы. Синтаксис: net start [Имя_службы] и net stop [Имя_службы]. 136 Настольная книга 1С:Эксперта по технологическим вопросам Задача, состоящая из команд net stop "1C:Enterprise 8.2 Server Agent" и net start "1C:Enterprise 8.2 Server Agent", перезапустит сервер «1С:Предприятия». В качестве примера опишем порядок создания этих задач для Windows 7 в самом простом случае: 1. Через управление компьютером войти в планировщик задач, создать новую задачу. 2. На закладке Общие ввести имя, например, «Перезапуск агента 1С» и уточнить, от имени какой учетной записи будет выполняться задача, а также можно поставить флажок Выполнять с наивысшими правами. 3. На закладке Триггеры создать новый триггер – указать, что задача выполняется по расписанию, ежедневно, например, в 22:40. 4. На закладке «Действия»: □□ создать новое действие, ○○ оставить действие «Запуск программы», ○○ имя программы указать: net, ○○ аргументы указать: stop "1C:Enterprise 8.2 Server Agent", □□ создать новое действие, ○○ оставить действие «Запуск программы», ○○ имя программы указать: net, ○○ аргументы указать: start "1C:Enterprise 8.2 Server Agent". Зайти в Библиотеку планировщика задач, попробовать выполнить задачу, убедиться, что выполняется то, что требуется. Там же, в библиотеке, можно при необходимости что-то донастроить или изменить как в расписании, так и в других параметрах задачи. 4.4. Регламентные операции SQL Server и настройка их автоматического выполнения Общие вопросы Создать план обслуживания можно при помощи конструктора либо при помощи мастера планов обслуживания. Мастер лучше подходит для создания простых планов обслуживания, а конструктор позволяет использовать расширенные возможности работы с потоком операций (нам это пригодится для связывания задач обновления статистики и очистки процедурного кеша). Для создания планов обслуживания и работы с ними пользователь должен быть членом фиксированной серверной роли sysadmin. Чтобы иметь возможность создавать планы обслуживания, нужно, чтобы был запущен не только сам SQL Server, но и его агент. Инструкции 137 Сам план обслуживания создают следующим образом: 1. Запустить SQL Management Studio. 2. Открыть ветку Management (Управление), в ней Maintenance Plans (Планы обслуживания), из него вызвать через контекстное меню New Maintenance Plan... (Создать план обслуживания...). Имя плану можно оставить по умолчанию («MaintenancePlan») или дать новое («Регламентные операции»). Обновление статистики SQL Server Чтобы правильно выбирать план запроса, SQL Server должен иметь актуальную информацию о таблицах базы. Просто для примера: если вам нужны какие-то бумаги из шкафа, вы можете ходить за каждым листиком, можете взять несколько папок и разобрать их у себя на столе, а можете передвинуть к своему столу весь шкаф целиком (потом не забыв вернуть). В каждом случае вы будете принимать решение, соотнося количество бумаг, которые вам нужны, с количеством бумаг в шкафу и их размещением там. Если вы ошибетесь, вы можете 100 раз ходить к шкафу, доставая оттуда по листочку, потому что будете думать, что там 10 миллионов бумаг, и все разложены по разным местам, а на самом деле их там всего 100 и было. Или, напротив, ради 10 листов перетащить к себе весь шкаф, считая, что там только эти 10 листов и есть, а там их окажется 10 тысяч. Но человек имеет возможность корректировать свои действия, а SQL Server, который может ошибиться примерно так же, должен будет выполнить работу в соответствии с назначенным планом, не имея возможности до следующего раза его поменять. Если говорить более точно, то каждый объект статистики создается для списка из одного или нескольких столбцов каждой таблицы и содержит гистограмму, в которой отображается распределение значений в первом из этих столбцов. Если построение идет для нескольких столбцов, то еще статистика содержит сведения о корреляции значений между столбцами. Эти статистические данные корреляции называются значениями плотности и получаются из числа уникальных строк значений столбцов. Для обновления статистик по всем таблицам базы данных необходимо выполнить следующий SQL запрос (базу надо выбирать свою, а не master и не какую-либо еще): exec sp_msforeachtable N'UPDATE STATISTICS ? WITH FULLSCAN' Рекомендуется выполнять его не реже раза в день. Время выполнения этой и следующей операций тем больше, чем реже их делают, и если делать их несколько раз в день, они будут проходить быстро. И даже если при этом произойдет снижение производительности на 10–15 %, очень немногие его смогут на себе ощутить. Чтобы обновление статистик выполнялось по расписанию автоматически, нужно сделать следующее: 1. В ранее созданный план обслуживания (он у нас назывался «MaintenancePlan» или «Регламентные операции») добавить новый вложенный план кнопкой Add Subplan (Добавление вложенного плана). Имя можно дать свое: «Обновление статистик и очистка процедурного кеша» (почему так, станет ясно позднее). 138 Настольная книга 1С:Эксперта по технологическим вопросам 2. Сразу же в форме создания можно задать расписание (Schedule). Как уже говорилось, рекомендуется выполнять это задание ежедневно. 3. Перетащить на поле плана с панели элементов задачу Update Statistics Task (Обновление статистики). 4. Открыть появившуюся задачу двойным щелчком. В появившемся окне выбрать (или потом в поле Database(s) (Базы данных) отметить) нужные базы, остальные поля заполнить, как приведено на рис. 4.4.1: Рис. 4.4.1. Настройка свойств задачи обновления статистики 1. Сохранить задачу, нажав ОК. 2. Сохранить план, например в меню Файл выбрав Сохранить выбранные элементы. 3. Убедиться, что в срок, указанный в расписании, задание отработало. Очистка процедурного кеша (кеша планов) Как говорилось раньше, SQL Server должен будет выполнить работу в соответствии с назначенным планом, не имея возможности до следующего раза его поменять. Однако SQL Server может даже этой возможностью не воспользоваться – он запомнит этот план в процедурный кеш, и возможна ситуация, что если будет вызван точно такой же запрос, будет использован план из кеша, даже если статистика поменялась. Поэтому после обновления статистики этот кеш имеет смысл очищать. Очистить процедурный кеш можно следующим запросом (в отличие от запроса обновления статистики, поскольку кеш является принадлежностью сервера, а не конкретной базы, базу в Management Studio можно использовать любую): DBCC FREEPROCCACHE Чтобы процедурный кеш всегда очищался сразу после обновления статистики, его есть смысл включить в тот же план обслуживания «Обновление статистик и очистка процедурного кеша», который выше был настроен для обновления статистики. Инструкции 139 1. На поле того же вложенного плана надо перетащить задачу Execute T-SQL Statement Task (задача «Выполнение инструкции T-SQL»). Ее надо разметить под предыдущей задачей, и от предыдущей протянуть к ней стрелочку. 2. Открыть свойства новой задачи двойным щелчком, в поле T-SQL Statement (инструкция T-SQL) ввести текст DBCC FREEPROCCASHE. 3. Сохранить задачу, нажав ОК. 4. Сохранить план, например, в меню Файл выбрав Сохранить выбранные элементы. 5. Убедиться, что задача выполняется. Дефрагментация индексов В разделе, посвященном общему списку регламентных работ («Теория», раздел 3.5), не упоминается дефрагментация индексов, поскольку там указывается ежедневное выполнение реиндексации базы, а после реиндексации необходимость делать дефрагментацию индексов отпадает. Тем не менее реиндексация – это операция, почти не позволяющая во время ее выполнения кому-то еще полноценно работать (реиндексация таблиц блокирует их на все время своей работы). А дефрагментация индексов не блокирует таблицы, а только создает дополнительную нагрузку на SQL Server. Поэтому если нет возможности ежедневно выполнять реиндексацию, то следует делать по крайней мере дефрагментацию индексов. Смысл этой операции состоит в том, что устраняется эффект фрагментации индексов, который возникает при интенсивной работе с таблицами базы данных и который может привести к снижению эффективности работы запросов. Дефрагментация всех индексов всех таблиц базы данных выполняется путем запуска SQL-запроса (в нем необходимо указать имя базы): sp_msforeachtable N'DBCC INDEXDEFRAG (<имя базы данных>, ''?'')' При необходимости также можно проводить дефрагментацию не для всех таблиц, а только для некоторых. Чтобы дефрагментация индексов выполнялась по расписанию автоматически, нужно сделать следующее: 1. В ранее созданный план обслуживания (он у нас назывался «MaintenancePlan» или «Регламентные операции») добавить новый вложенный план (Subplan). 2. Задать ему имя, например «Дефрагментация индексов» и расписание. 3. На поле этого вложенного плана надо перетащить задачу Reorganize Index Task («Реорганизация индекса»). 4. Открыть свойства задачи двойным щелчком, при необходимости в поле Database(s) («Базы данных») отметить нужные базы, остальные поля настроить, как показано на рис. 4.4.2. 5. Сохранить задачу, нажав ОК. 140 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.4.2. Настройка свойств задачи дефрагментации индексов 6. Сохранить план, например в меню Файл выбрав Сохранить выбранные элементы. 7. Убедиться, что задача выполняется. Реиндексация таблиц базы Эту регламентную операцию можно выполнять как средствами конфигуратора «1С» (через «тестирование и исправление»), так и через запрос к СУБД. Результат будет точно такой же. Есть, однако, два соображения, по которым удобнее делать это средствами СУБД, когда речь идет о настройке регулярно выполняющихся действий: 1. Если вы уже настраиваете план обслуживания базы средствами СУБД, включение в него еще одного вложенного плана займет менее полуминуты. 2. Реиндексация средствами «1С» требует монопольного захвата базы, работа других пользователей невозможна. Реиндексация средствами СУБД не требует монопольного захвата. Поскольку она блокирует таблицы на все время своей работы, ее надо проводить во время минимальной активности пользователей. Но, например, чтение данных вне транзакций и другие ограниченные возможности остаются для пользователей доступными. Реиндексация всех таблиц базы выполняется SQL-запросом (базу надо выбирать свою): sp_msforeachtable N'DBCC DBREINDEX (''?'')' Инструкции 141 Чтобы реиндексация базы выполнялась по расписанию автоматически, нужно сделать следующее: 1. В ранее созданный план обслуживания (он у нас назывался «MaintenancePlan» или «Регламентные операции») добавить новый вложенный план (Subplan). 2. Задать ему имя, например «Реиндексация базы» и расписание. 3. На поле этого вложенного плана надо перетащить задачу Rebuild Index Task («Перестроение индекса»). 4. Открыть свойства задачи двойным щелчком, при необходимости в поле Database(s) («Базы данных») отметить нужные базы, остальные поля настроить, как показано на рис. 4.4.3: Рис. 4.4.3. Настройка свойств задачи реиндексации 5. Сохранить задачу, нажав ОК. 6. Сохранить план, например в меню Файл выбрав Сохранить выбранные элементы. 7. Убедиться, что задача выполняется. Контроль выполнения регламентных заданий 1. После того как пройдет срок, назначенный для первого выполнения регламентного задания каждого вида, открыть ранее созданный план обслуживания (он у нас назывался «MaintenancePlan» или «Регламентные операции») и выбрать из контекстного меню пункт «View History» (Просмотр журнала). 2. Проставить соответствующие журналов»). флажки в дереве «Select logs» («Выбор Убедиться, что в журнале есть запись о выполнении и что отметка говорит об успешном выполнении. Если возникла ошибка, о ней нужно там же получить более подробную информацию и принять меры по исправлению. 142 Настольная книга 1С:Эксперта по технологическим вопросам 4.5. Как включить технологический журнал «1С» и как его можно разбирать Технологический журнал позволяет получать технологическую информацию о работе приложений, как сервера, так и клиентов. Например, позволяет посчитать количество ошибок блокировок64.51 Чтобы его включить, нужно выполнить следующие действия: 1. Завести на локальных дисках серверов приложений «1С» специальную папку для технологического журнала. Например, как показано на рис. 4.5.1, <C:\LOG>. И для дампов, например <C:\dumps>. Рис. 4.5.1. Содержимое папки C:\LOG после создания 2. Настроить журнал, чтобы сбор сообщений об ошибках (см. ниже пункт 10 про файл logcfg.xml) происходил в подкаталог этого каталога. Подкаталог будем называть по дате: <C:\LOG\2011-02-16> и т. д. 3. Сам файл logcfg.xml надо положить в каталог conf папки установки сервера «1С:Предприятия» (например, как показано на рис. 4.5.2, в C:\Program Files\1cv82\8.2.15.301\bin\conf). 4. Обратить внимание, что файл нужно помещать в каталог установки сервера, а не клиента, т. к. в зависимости от разрядности ОС это может быть либо один и тот же каталог, либо разные. То есть, например, если у вас 64-битный сервер, то сервер «1C» по умолчанию ставится в C:\Program Files\(...), а клиент в C:\Program Files (x86)\(...). 64 Подробно организация и настройка технологического журнала «1С:Предприятия» описаны в книге «1С:Предприятие 8.2. Руководство администратора», глава 6 «Администрирование информационной базы», раздел «Технологический журнал». Инструкции 143 Рис. 4.5.2. Файл logcfg.xml помещен в нужный каталог 5. После этого примерно через минуту убедиться, что в каталоге <C:\LOG> создалась папка C:\LOG\2011-02-16, и в ней еще подпапки с именами rphost_XXXX, ragent_XXXX, rphost_XXXX, а в них файлы. Пример с правильными папками показан на рисунке 4.5.3. Если же создаются только подпапки с именами 1с8_ ХХХХ, это означает, что файл logcfg.xml поместили в конфигурационный каталог клиента, а не сервера. Рис. 4.5.3. Папки, автоматически сформированные после старта записи технологического журнала 144 Настольная книга 1С:Эксперта по технологическим вопросам 6. Если папки, показанные на рисунке выше, создались, то все нормально, если не создались, то что-то не так. 7. Если что-то не так, то наиболее распространенные ошибки: 8. 9. □□ большие/маленькие буквы в именах каталогов (регистр должен совпадать); □□ в файле настройки (logcfg.xml) написали слеш на конце имени каталога (не нужен); □□ требуется донастроить права пользователей на папки C:\LOG, C:\dumps, C:\Program Files\1cv82\8.2.13.205\bin\conf, если их не хватает, а такое может быть по умолчанию. По этой же причине лучше создавать каталог хранения логов не на диске (C:). Если надо хранить данные за каждый день отдельно, каждый день в одно и то же время (например, в начале рабочего дня) нужно менять имя каталога в файле logcfg на новое (подставлять другую дату). Данные за прошлый день архивировать в один файл с соответствующим именем, при необходимости высылать туда, где их могут обработать. После этого данные за прошлый день удалять. Если не надо хранить данные за каждый день отдельно, можно ничего не делать, данные хранятся определенное количество часов (в нашей настройке, указанной ниже, – 240, после чего сами удаляются). На настройку, если с правами все в порядке, понадобится минут пять вместе со следующим пунктом. 10. Настройка logcfg.xml. Файл logcfg.xml сам по себе является семафором. Его присутствие в нужном каталоге включает запись технологического журнала «1С», а его содержимое определяет, что, как и куда пишется. Запись журнала начинается примерно через минуту после помещения корректного файла в нужный каталог. Перезапускать сервер не требуется. Редактировать файл можно «Блокнотом». Содержимое файла для наших целей должно быть примерно таким: <?xml version="1.0" encoding="UTF-8"?> <config xmlns="http://v8.1c.ru/v8/tech-log"> <dump create="true" location="C:\dumps" type="0"/> <log history="240" location="C:\LOG\2011-02-16"> <property name="all"/> <event> <eq property="name" value="excp"/> </event> </log> </config> В этом случае в технологический журнал пишутся только ошибки: eq property="name" value="excp" Данные хранятся 240 часов, потом удаляются: log history="240" Инструкции 145 Они пишутся в каталог C:\LOG\2011-02-16: location="C:\LOG\2011-02-16" Дампы при падении создаются: dump create="true" Такая настройка наиболее подходит для ежедневного мониторинга. Она делает возможным ручной визуальный контроль ошибок (сам технологический журнал – это текстовые файлы). Она не вызывает дополнительной нагрузки на систему, поскольку в файл пишутся только ошибки (повышение нагрузки на систему не фиксируется, оно на уровне ошибок измерения). Также такая настройка не забивает место на диске при создании дампов. При указании type="0" дамп занимает очень мало места на диске. Дампы нужны, если вы собираетесь их посылать на разбор или умеете обрабатывать сами. Можно совсем не записывать дампы, если вам не нужно их считать: dump create="false". Для целей мониторинга ошибок указанной настройки вполне достаточно. Обработкой НастройкаТехнологическогоЖурнала.epf с ИТС можно настроить более продвинутый мониторинг, однако каждое новое событие нужно включать, только если вы четко понимаете, что вы хотите с его помощью увидеть. Может произойти такое, что избыточная информация сделает недоступным визуальный ручной контроль или ее вывод потребует от системы значительных ресурсов. Если происходит ошибка блокировок, она записывается в файл в текстовом виде, и выглядит она примерно так, как показано на рис. 4.5.4: 00:05.8840-0,EXCP,6,process=rphost,p:processName=ut,t:clientID=66,t:applicationName=1CV8,t:computerName=MS-11, t:connectID=49,SessionID=794,Usr=Иванов Петя,Exception=DataBaseException,Descr='Конфликт блокировок при выполнении транзакции:Microsoft OLE DB Provider for SQL Server: Lock request time out period exceeded. HRESULT=80040E31, SQLSrvr: SQLSTATE=HYT00, state=12, Severity=10, native=1222, line=1' 00:05.8845-0,Context,3,process=rphost,p:processName=ut,t:clientID=66,t:applicationName=1CV8,t:computerName=MS-11, t:connectID=49,SessionID=794,Usr= Иванов Петя,Context=' {Документ.Событие.Форма.ФормаДокумента} Документ.Событие : 734 : мойЗаписатьТелефонКонтрагента(Контрагент, мойТелефон); ОбщийМодуль.мойОбщий : 1073 : Список = мойПоискАбонентаПоТелефону(Телефон, Истина); ОбщийМодуль. мойОбщий: 992 : Результат = Запрос.Выполнить();' Рис. 4.5.4. Пример информации об ошибках блокировок в технологическом журнале Квалифицированный программист «1С» обычно в состоянии достаточно быстро написать парсер, считающий, например, количество появлений строк «Lock request time out» в нескольких текстовых файлах. Другие ошибки блокировок, с которыми приходится встречаться на практике, представлены в таблице 3.9.1. 146 Настольная книга 1С:Эксперта по технологическим вопросам Простейший мониторинг, заключающийся в разборе текстовых файлов и подсчете таких ошибок, позволяет точно ответить на вопрос: есть ли «симптомы болезни» (ошибки блокировок) и сколько их: ■■ ■■ ■■ ■■ если их меньше 10 в день, можно на них пока не обращать внимания; если в какой-то день больше 10, стоит начать заниматься этой проблемой; если их больше 50 в день, проблемой надо заниматься в полную силу; если их больше 200 в день, ваши пользователи вам и так все уже рассказали. 4.6. Общий подход к анализу технологического журнала «1С» По данным технологического журнала, полученным с помощью настроек, описанных в предыдущей главе, можно вести не только простейший мониторинг. Из тех же самых логов можно получить гораздо более детальную картину о работе системы, если разобрать их же, применив следующую методику: сгруппировать события EXCP по одинаковому тексту. Под одинаковым текстом тут также понимаются ключевые фразы, однозначно идентифицирующие характер ошибки. Пример таких ключевых подстрок для ошибок блокировок приведен в таблице выше; ■■ взвесить группы, то есть составить рейтинг ошибок по частоте; ■■ разобраться с каждой группой ошибок в цикле сверху вниз; ■■ по каждой ошибке попытаться понять, имеет ли она отношение к работе пользователей или это системная информация, которая по сути ошибкой не является; ■■ если это реальная ошибка, возникшая при работе пользователей, то с соответствующим приоритетом разобраться с ней и устранить. Можно провести дополнительный анализ, сгруппировав ошибки блокировок (и другие ошибки) по контекстам, в которых они возникают. Это более сложная задача, но тоже вполне решаемая, и она с некоторыми известными ограничениями позволяет осуществлять первичный анализ причин, вызывающих эти ошибки. ■■ 4.7. Замеры производительности Замер производительности отладчиком 1С8 Замер производительности отладчиком 1С8 позволяет оценить скорость работы кода конфигурации. Показывает количество использования конкретных строк кода и время их выполнения – чистое и в процентном отношении к общему времени работы. Пример результата замера приведен на рис. 4.7.1. Включается так: Конфигуратор – Отладка – Замер производительности. После этого надо выполнить исследуемое действие, например, провести документ. Выключается так же. Инструкции 147 Файл с результатами замера можно сохранить. Справка по нюансам использования находится во встроенной справке конфигуратора (F1) – 1С:Предприятие – Конфигурирование – Замер производительности. В клиент-серверном варианте, чтобы в замер попал серверный код, необходимо, чтобы сервер был запущен в режиме отладки с ключом -debug. Рис. 4.7.1. Пример результата замера производительности отладчиком 1С8 Простейший код замера времени Замеры времени выполнения чего-либо можно проводить и вручную, используя секундомер, но такой способ имеет известные погрешности и очевидные неудобства. Правильнее всего, конечно, пользоваться подсистемой «Оценка производительности» (как это делать, рассказано ниже). Ее встраивание не занимает много времени, но затем экономия времени и удобство с лихвой оправдывают затраты. Но бывает, что возможности изменения конфигурации нет. Тогда более удобно и точно, чем секундомером, замеры можно проводить, используя различного рода самописные обработки (например, как показано на рис. 4.7.2), выводящие строковое представление функции ТекущаяДата() перед началом какого-то куска кода и после его окончания. 148 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.7.2. Простейший код замера времени Оценка производительности БСП (инструкция по установке, описание работы) В ходе жизни информационных систем могут возникать ситуации, когда пользователи начинают жаловаться на «резкое снижение» скорости работы. Жалобы пользователей – это, однако, субъективный показатель. Его, безусловно, стоит принимать во внимание, но только для того, чтобы начать собирать объективные показатели. Таким объективным показателем может быть время выполнения какой-то ключевой операции, например, время проведения документа определенного типа. Чтобы иметь объективную картину, надо, чтобы при каждом нажатии кнопки ОК в критичном документе выполнялся замер времени и записывался в базу. Тогда у вас, во-первых, будет понимание того, сколько на самом деле, а не со слов пользователя, проводятся документы, а во-вторых, вы сможете видеть динамику процесса и сами сможете отследить тревожную ситуацию и начать принимать меры (например, время увеличилось вдвое – с 5 минут до 10, но основные пользователи в отпусках, а девочкам, их замещающим, кажется, что это нормально и они не жалуются). В такой ситуации, когда нужно измерить и хранить время выполнения не одной операции, а, например, время проведения каждого документа в работающей базе, есть смысл воспользоваться функционалом подсистемы «Оценка производительности» из состава Библиотеки стандартных подсистем «1С». В ряде типовых конфигураций эта подсистема уже встроена65, и определены основные ключевые операции, так что зачастую достаточно просто включить замер производительности.52 Ниже приводится инструкция для библиотеки стандартных подсистем 2.1.1.22, перепроверенная и уточненная для ред. 2.2.5.30. В старых версиях (1.2.2.3) существенное отличие только в том, что Ключевые операции – это не справочник, а перечисление. 1. Запустить конфигуратор. 2. Убедиться, что конфигурация не содержит встроенной подсистемы «Оценка производительности» (в частности, регистра сведений Замеры времени, обра- 65 Обращайте внимание на то, какой она версии, т. к. она может быть далеко не последней версии. Разумеется, при этом она будет справляться с возложенными на нее задачами в рамках своей конфигурации, но не всегда в рамках проводимых вами работ. Решение о том, нужно ли вам ее обновлять, нужно принимать взвешенно. Обновление подсистемы «Оценка производительности» БСП – задача решаемая, но более сложная, чем установка с нуля, обязательны функциональное тестирование и готовность оперативно исправлять возникающие коллизии. Инструкции 149 ботки Оценка производительности, справочника или перечисления Ключевые операции). Если содержит, проверить предопределенные элементы справочника Ключевые операции на наличие нужных операций. Если их недостаточно, перейти к п. 10; если все необходимые есть – к п. 13. 3. Сравнить и объединить с cf на http://users.v8.1c.ru/actual.jsp. БСП. Текущая версия публикуется 4. В окне сравнения-объединения снять все флажки, как показано на рис. 4.7.3: Рис. 4.7.3. Порядок заполнения окна сравнения-объединения 5. 6. 7. 8. Из меню Действия выбрать Отметить по подсистемам файла. Снять, как показано на рис. 4.7.4, все флажки в перечне подсистем: □□ флажок поставить на Стандартные подсистемы – Оценка производительности, □□ оставить установленным флажок Включать объекты подчиненных подсистем, □□ оставить установленным флажок Включать объекты родительских подсистем. Нажать кнопку Установить. В окне сравнения-объединения Общие – Подсистемы – Стандартные подсистемы – Оценка производительности установить флажок, как показано на рис. 4.7.5. 150 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.7.4. Порядок заполнения окна отбора по подсистемам Рис. 4.7.5. Порядок заполнения окна сравнения-объединения после установки отбора по подсистемам Инструкции 9. 151 Выполнить объединение. 10. В справочник Ключевые операции добавить предопределенные элементы (например, КлючеваяОперация_1). 11. Не имеет значения – это кнопка ОК, кнопка Создать, кнопка Открыть или еще что-то. Надо с помощью кода сначала стартовать замер, а потом начать выполнение действия. Например, когда документ проводится при нажатии кнопки ОК и нам необходимо выполнить замер времени проведения: □□ если ОК стандартная кнопка: ○○ для обычных форм открыть форму на редактирование, в контекстном меню кнопки выбирать пункт Удалить, создать новую кнопку с таким же именем и разместить ее на форме, при необходимости установить свойство КнопкаПоУмолчанию в Истина; ○○ для управляемых форм открыть форму на редактирование, в свойствах формы (свойство Состав команд) отключить отображение команды ОК, в редакторе форм создать новую команду с именем ОК, расположить ее на форме, при необходимости установить свойство КнопкаПоУмолчанию в Истина. Обработчик кнопки (команды) может выглядеть следующим образом (на рис. 4.7.6 приведен код из типовой конфигурации «Бухгалтерия предприятия», ред. 3.0, релиз 3.0.19.15, элемент справочника Ключевые операции надо использовать свой): Рис. 4.7.6. Код обработки команды «Провести и закрыть» формы документа «Поступление товаров и услуг» типовой конфигурации «Бухгалтерия предприятия», ред. 3.0, релиз 3.0.19.15 152 Настольная книга 1С:Эксперта по технологическим вопросам □□ если ОК нестандартная кнопка, включить старт замера в начало обработчика нажатия кнопки: КлючеваяОперация = ПредопределенноеЗначение("Справочник.КлючевыеОперации.КлючеваяОперация_1"); ОценкаПроизводительностиКлиентСервер.НачатьЗамерВремени(КлючеваяОперация); Обратите внимание, что все счетчики лучше встраивать на клиенте (не в серверный код). Не нужно завершать замер вручную. Замер будет завершаться автоматически по обработчику ожидания. Но если вдруг потребуется вызывать замер с сервера, то замер надо заканчивать принудительно: &НаСервере Функция СоздатьДокументЗаказПоставщику(Ссылка) КлючеваяОперация = ПредопределенноеЗначение("Справочник.КлючевыеОперации.КлючеваяОперация_1"); ...<код создания документа>... ВремяНачала = ОценкаПроизводительностиКлиентСервер.НачатьЗамерВремени(КлючеваяОперация); ДокументЗаказ.Записать(РежимЗаписиДокумента.Проведение66); ОценкаПроизводительностиКлиентСервер.ЗакончитьЗамерВремени(КлючеваяОперация, ВремяНачала); .... КонецФункции 12. При объединении с версиями БСП, начиная с определенного момента, требуется в модуле обычного приложения и в модуле управляемого приложения объявлять переменную:53 Перем ПараметрыПриложения Экспорт;6754 13. Константу Выполнять Замеры Производительности установить в Истину любым удобным способом (обработкой, создав новую форму констант, и пр.). 14. При необходимости отрегулировать константу Оценка производительности период записи – это периодичность записи результатов замеров на сервере, в текущих релизах при установке значения 1 и меньше (в т. ч. 0 по умолчанию) выполняется раз в 60 секунд. 15. Для анализа значений APDEX нужно использовать обработку Оценка производительности (Операции – Обработки…). Чтобы ее использовать, нужно задать период, шаг периода и целевое время, в списке оставить только свою ключевую операцию и «общую производительность системы» и нажать Обновить показатели производительности. 66 67 На всякий случай обращаем внимание, что, в отличие от рис. 4.7.6, где в параметрах у Записать() – структура, т. к. это код для управляемой формы, в обычной форме и при вызове с сервера в параметрах у Записать() – РежимЗаписиДокумента.Проведение. Хороший повод отметить, что задачу написания идеальных инструкций на все времена мы перед собой не ставим. Код, даже списанный из книжки, перед применением на продуктиве надо проверять и отлаживать, а 1С:Эксперт должен уметь программировать и не должен падать в обморок при появлении сообщений об ошибке, особенно таких очевидных, как Переменная не определена (ПараметрыПриложения). Встраивание БСП вер. 2.1.1.22 не требовало объявления указанной переменной, поэтому в первом издании книги про это ничего написано не было. Работоспособность нынешнего кода проверена на БСП вер. 2.2.5.30. Выйдет БСП 2.3.1, возможно, появятся новые нюансы. Инструкции 153 В простых случаях время на выполнение всех пунктов изложенной выше инструкции не превышает 20 минут. Если подсистему пришлось встраивать, то потребуется обновить конфигурацию базы, причем не динамически, а с выходом всех пользователей. Дополнительно рекомендуется ознакомиться со статьей http://kb.1c.ru/articleView. jsp?id=61, а также посмотреть, как данный функционал реализован в последних релизах типовых конфигураций, например, в уже упомянутой конфигурации «Бухгалтерия предприятия», ред. 3.0. Использование изложенного подхода предполагает, что замеры выполняются только при нажатии кнопки ОК (или Провести и закрыть) в форме элемента. Это не охватывает всех случаев, потому что, например, проведение документа может выполняться и с помощью других кнопок, заменить обработчики которых гораздо сложнее. Но можно считать, что для массовых документов выборка, получаемая таким образом, является достаточной, хоть и не будет охватывать всех случаев. А для немассовых документов следует попросить отдельных пользователей пользоваться для проведения документов только кнопкой ОК. Результатом внесенных изменений, если все сделано правильно, должно стать появление в регистре сведений Замеры времени информации о том, какие ключевые операции были выполнены и за какое время. Появляются они там не моментально, но в течение минуты после выполнения ключевой операции появиться должны обязательно. Полученные данные можно использовать для самостоятельной обработки, либо, как указывалось выше, воспользоваться входящей в подсистему обработкой Оценка производительности, агрегирующей результаты по методике APDEX. 4.8. Требования к сети. Как проверить сеть Общие вопросы При решении задач проектирования центров обработки данных под ландшафт «1С» часто задают вопрос о параметрах пропускной способности сети, необходимых для комфортной работы пользователей. Ответ стереотипный: таких требований нет. Есть объективное требование – техническая возможность работы, но соблюдение этого условия обеспечивается в том числе при полном отсутствии комфорта для пользователей. В то же время «комфортная работа пользователей» – это субъективный критерий, и, кроме того, он существенным образом зависит от особенностей прикладного решения (конфигурации «1С»), то есть никаких формальных требований по нему выставлено быть не может. Если, однако, вспомнить раздел 2.3 «Как устроена система», мы увидим, что сетевое взаимодействие является важной частью работы компонентов системы. И теоретически, и на практике сеть действительно может быть узким местом в работе. Например, лет восемь назад достаточно распространенной причиной жалоб пользователей на работу 1С 7.7 (файловой) была плохо обжатая витая пара. 154 Настольная книга 1С:Эксперта по технологическим вопросам В упомянутом разделе приводилась аналогия работы системы с поездкой в гипермаркет. Если к этой аналогии вернуться, то становится понятно, что даже при наличии асфальтированной дороги между домом и магазином существует много причин, по которым время поездки вырастет, и иногда вырастет очень сильно: ямы, ухабы, «лежачие полицейские»; ■■ светофоры, ж/д переезды, перекрытия движения; ■■ ограничения скорости; ■■ проверки документов инспекторами; ■■ необходимость заехать еще куда-то по дороге (хотя бы и на заправку) и т. п. Короче говоря, требование к идеальной дороге и движению по ней довольно простое: дорога должна наличествовать, на ней не должно быть ям и ухабов, система организации движения не должна мешать по этой дороге ехать, маршрут движения должен быть максимально простым. ■■ Собственно, ровно те же требования можно предъявить и к идеальной сети: сеть должна быть, и она не должна мешать системе работать ни ошибками, ни ограничениями скорости, ни особенностями собственной организации. Как ни странно, этой цели лучше всего соответствует сеть со статическими IPадресами, расположенными в единой локальной подсети, а из физического оборудования – самый простой гигабитный хаб или неуправляемый свитч и гигабитные сетевые адаптеры. В реальности, однако, такие сети и такое оборудование в крупных организациях встречаются довольно редко, в том числе из-за необходимости ручного администрирования. А использование средств, позволяющих администрирование в той или иной степени автоматизировать, может создать довольно серьезные затруднения при работе. Рассмотрим теперь, какие проблемы можно получить или самостоятельно себе создать, а также как их можно попробовать обнаружить. Ошибки сети Самый простой способ проверить, доступен ли вообще сервер и нет ли ошибок, – команда ping <IP-адрес сервера, с которым проверяется связь> (Пуск – Все программы – Стандартные – Командная строка или Пуск – выполнить – cmd, и в появившемся окне набирать команду). Для наших целей больше подходит команда с параметром -t, показанным на рис. 4.8.1. При указании этого параметра проверка идет, пока ее не прервать сочетанием клавиш Ctrl + C. Для отображения статистики и продолжения проверки надо нажать Ctrl + Break. Второй рисунок показывает, как выводить информацию в файл, а не на экран. Инструкции 155 Рис. 4.8.1. ping -t Канал может резко терять стабильность на больших пакетах. Если обычный ping не выявит потерь, есть смысл проверить: ping <имя сервера> -n 100 -l 50000 Если при просмотре вы заметили, что есть потерянные пакеты или время скачет, достигая достаточно больших значений, это означает, что в сети есть ошибки. Будут они мешать вам работать или нет – это дело случая, но за правило надо взять, что если ошибки есть, то мешать работать они будут. Если необходимо установить связь между сбоями системы и работой сети, можно использовать другую утилиту: hrping (freeware, можно скачать на сайте ее разработчика cFos Software: http://www.cfos.de/hrping-v504.zip). Эта утилита обладает рядом дополнительных полезных возможностей. Например, ее запуск с ключом «-Т» выводит время (см. рис. 4.8.2). Для наших целей достаточно следующей строки запуска (требуются права администратора – Пуск – Все программы – Стандартные – Командная строка – контекстное меню – Запуск от имени администратора, и в появившемся окне набирать команду): hrping.exe -t -s 100 -T -l 1024 -F pinglog.txt 192.168.0.1 156 Настольная книга 1С:Эксперта по технологическим вопросам IP-адрес нужно указать, разумеется, требуемый, реальный. Вывод, как понятно из командной строки, производится в файл pinglog.txt. Пример показан на рис. 4.8.2. Если были пропавшие пакеты (это понятно из суммарной статистики), время их пропадания можно установить, проведя поиск подстроки «Timeout waiting for» по этому файлу. Сопоставив время пропадания пакетов и время ошибок, зафиксированных в технологическом журнале «1С», можно сделать вывод о наличии либо отсутствии связи по времени одного с другим. Рис. 4.8.2. Пример лога hrping Недостаточная пропускная способность Приведенные в таблице 4.8.1 значения не являются официальными требованиями к пропускной способности сети. В ней приведены пороговые значения пропускной способности, ниже которых наблюдается замедление работы, выходящее за погрешность измерения (то есть речь не совсем о комфортной работе, а о снижении скорости работы, которое может быть измерено). При пропускной способности выше указанной скорость работы находится примерно на одном уровне. Таблица 4.8.1. Пороговые значения пропускной способности сети Соединение Локальная сеть: работа толстого клиента в файловой версии, связь между серверами в клиент-серверной версии, работа совокупности клиентов Пропускная способность 1 Гбит/с Примечание Ситуации, когда действительно требуется пропускная способность выше 1 Гбит/с, являются крайне редкими, но их и нетрудно обнаружить, анализируя загрузку сетевого интерфейса, см. раздел 4.1. Пропускной способности в 100 Мбит/с может не хватать для работы без замедлений. Возможностей Wi-Fi (теоретический потолок самого быстрого стандарта на текущий момент – 300 Мбит/с, реальный – 100 Мбит/с) также может не хватать для работы без замедлений Инструкции Соединение Пропускная способность 157 Примечание RDP с терминальным сервером 14 Кбит/с Разрешение экрана 1440х900 и наcтройки цвета 32 бита (True Color) Другие терминальные клиенты В ряде Требования могут отличаться в большую сторону, для случаев – до некоторых клиентов – на порядок 128 Кбит/с Толстый клиент, тонкий клиент 16–32 Кбит/с Зависит от выполняемой операции. Замер выполнялся через TCP/IP (клиент-серверная для демобазы «1С:Управление торговлей 8», ред. 11 версия при работе одного клиента) Тонкий клиент через HTTP 8–16 Кбит/с Зависит от выполняемой операции. Замер выполнялся (клиент-серверная версия при для демобазы «1С:Управление торговлей 8», ред. 11 работе одного клиента) При использовании некоторых каналов может проявляться такая составляющая, как задержка сигнала, например, при обмене через спутник. В этом случае имеет смысл самостоятельно провести тестирование канала, используя доступный сервис «1С» (демобаза «1С:Управление торговлей 8» с веб-интерфейсом): http://demo-ma.1c.ru/trade. То же для низкоскоростного соединения: http://demo-ma.1c.ru/trade?O=Low. Маршрутизация Вообще говоря, лучше, если все серверы, относящиеся к ландшафту «1С», находятся в одном сегменте сети. Это снимает целый класс потенциальных проблем. Проверить, есть ли в сети маршрутизация, можно с помощью команды tracert, запустив ее, например, с терминального сервера на сервер (серверы) приложений «1С», а с сервера (или с серверов, если их несколько) приложений «1С» на сервер СУБД. Если трассировка покажет путь из одной строчки («хопа», «прыжка»), как показано на рис. 4.8.3, – все нормально. Если же их более одного, это значит, что между вашими серверами существуют промежуточные маршрутизаторы. Рис. 4.8.3. Команда tracert показала, что до сервера 192.168.0.1 один «хоп» Если эти маршрутизаторы представляют собой физические серверы, такая архитектура совершенно точно требует исправления. Дело в том, что при прохождении пакета из одной подсети в другую через роутер на нем обязательно происходит задержка пакета на его обработку. Чаще всего 158 Настольная книга 1С:Эксперта по технологическим вопросам и в основном потери времени идут на логирование, но могут быть задержки и на других программных надстройках роутера. Длинные пакеты задерживаются на большее время, чем короткие. В результате штатными средствами (ping) эта задержка не определяется, т. к. там по умолчанию очень короткие пакеты, которые, если нет проблем, проходят быстро. А длинные пакеты (работа с СУБД и обмен между серверами) задерживаются, и это – нормальная работа. Эти задержки на обработку пакетов замедляют работу системы в целом. Их можно минимизировать, но совсем от них избавиться нельзя, и такая работа требует наличия специфичных знаний у специалистов по сетевому оборудованию. Обычная практика в таких случаях – исключать маршрутизацию. Однако и в том случае, если речь идет о VLAN, полностью снимать вопрос о непричастности маршрутизации к проблемам не стоит. Почему – рассказано ниже. Надстройки активного оборудования Активное сетевое оборудование может вести себя подобно сотруднику ДПС на посту: задерживать, логировать и фильтровать подозрительные пакеты. Это зависит от того, какие надстройки задействованы (кстати, не обязательно они задействованы силами системных администраторов заказчика, иногда они включены по умолчанию). Внедренцам «1С», как правило, очень трудно объяснить администраторам в больших центрах обработки данных, что именно должно быть открыто для того, чтобы работа системы на платформе «1С:Предприятие» не казалась подозрительной софту активного оборудования и не встречала противодействия с его стороны. Поэтому обычный ответ, к сожалению, таков: «Сначала открыть все, а вот что можно закрыть – надо проверять». Если есть подозрение, что дело все-таки в активном оборудовании, а все серверы ландшафта «1С» являются физическими, есть смысл попробовать скоммутировать их не через активное оборудование, а через неуправляемый свитч, и сравнить данные замеров производительности, полученные для обоих случаев. Надстройки серверов ландшафта «1С» На серверах терминалов, приложений «1С» и СУБД может быть задействовано встроенное в ОС или дополнительно установленное программное обеспечение, повышающее безопасность: файрволл, антивирус и пр. Довольно часто работа этого программного обеспечения оказывает существенное негативное влияние на работу системы на платформе «1С:Предприятие», т. е. это программное обеспечение является обычным подозреваемым при расследовании проблем производительности. Стандартное решение – отключить вызывающие подозрение настройки и программы и сравнить данные замеров производительности, полученные с ними и без них. Сетевые службы Если сетевые службы (DNS, DHCP и другие) работают с ошибками и об этих ошибках известно из других источников, не обязательно связанных с ландшафтом «1С», то устранение этих ошибок должно стать приоритетной задачей, без решения которой все работы по поиску проблем производительности «1С» могут не иметь смысла. Инструкции 159 4.9. Сбор статистики дампов (общий принцип) Автоматизированный сбор дампов Для начала надо сказать, что автоматический сбор статистики дампов реализован в текущей версии ЦКК. Как это делать вручную, рассказано далее, но надо понимать, что, потратив не очень много времени на настройку ЦКК, можно затем полностью избавить себя от рутинной работы. Для наших целей мы считаем, что дамп – это содержимое рабочей памяти одного процесса. Нас интересуют дампы, создаваемые автоматически при аварийном завершении работы приложения или процесса. Также нас интересуют дампы, снимаемые вручную, когда приложение (процесс) зависло и дамп не был создан автоматически. Информация, содержащаяся в дампах, позволяет расследовать критичные ошибки. Чтобы провести такое расследование, дамп надо отправлять в «1С». Но есть и другое, более простое применение дампов, также важное на практике. Собственно количество дампов за период может служить объективной характеристикой качества работы системы, потому что оно будет отражать количество аварийных завершений работы. Статистика дампов, разобранная по офсетам, как будет показано ниже, может показать количество однородных причин их создания, и по крайней мере станет понятно, имеют место падения процессов и приложений по одной причине или по разным. Рассмотрим сначала встроенные в «1С» средства управления формированием дампов. По умолчанию при аварийном завершении процесса (приложения) формируется минимальный дамп, который попадает в папку: 55 %USERPROFILE%\Local Settings\Application Data\1C\1Cv82\dumps68 А для ОС Windows Vista и выше в папку: %LOCALAPPDATA%\1C\1Cv82\dumps Папка относится к тому пользователю, от имени которого работает приложение. Например, дампы серверных процессов в Windows 7, скорее всего, будут находиться в папке C:\Users\Usr1cv82\AppData\Local\1C\1Cv82\dumps. Состав информации, попадающей в дамп, регулируется настройками секции <dump> файла logcfg.xml69, см. раздел 4.5. В ней приведен следующий пример:56 <dump create="true" location="C:\dumps" type="0"/> Атрибут location назначает имя каталога, в который будут помещаться файлы дампов. 68 69 Для 8.3 каталог по умолчанию содержит в пути не «1Cv82», а «1Cv8». Для ОС Linux настройка формирования дампов выполняется средствами ОС. Поэтому элемент <dump> игнорируется. См. статью «Создание дампов аварийного завершения программы в ОС Linux» на ИТС, а также в гл. 6 «Руководства администратора». 160 Настольная книга 1С:Эксперта по технологическим вопросам Атрибут create указывает, создавать или не создавать файл дампа: 0 ("false") – не создавать; ■■ 1 ("true") – создавать. Атрибут type назначает тип дампа. Это произвольная комбинация битов-флажков, представленная в десятичной или шестнадцатеричной системе (сложение значений флажков). Представление в шестнадцатеричной системе должно начинаться с символа 'x', например, x0002. ■■ Доступные значения приведены на диске ИТС и в «Руководстве администратора», см. приложение 3 «Описание и расположение служебных файлов». Для большинства случаев достаточно в качестве значения атрибута type использовать значение 0 (минимальный дамп) или 3 (содержимое всей памяти процесса + дополнительный сегмент данных), например, type="3". Атрибут prntscrn указывает, создавать или нет файл копии экрана при аварийном завершении клиентской части системы «1С:Предприятие». Имя файла совпадает с именем дампа, но имеет расширение png. Файлы копий экрана создаются в том же каталоге, что и дампы (см. атрибут location). 0 ("false") – не создавать; 1 ("true") – создавать. Чтобы вести статистику критичных ошибок с помощью дампов, нужно: ■■ ■■ 1. Собрать все дампы с сервера. 2. Объединить идентичные дампы в группы. Дамп будет идентичным, если у него совпадает имя процесса, номер версии и офсет, то есть первые три группы значений в имени файла. Например, для дампа rphost_8.2.16.368_3201 be4b_20121211163453_22484: 3. 4. □□ имя процесса: rphost, □□ версия: 8.2.16.368, □□ офсет: 3201be4b. Для новых групп, то есть для тех видов дампов, которые появились впервые, нужно добавить новую строчку в таблицу (см. таблицу 4.9.1). После этого для всех видов дампов проставить количество дампов этого вида в колонке соответствующей недели. Как говорилось в начале, всю эту деятельность можно автоматизировать при помощи ЦКК. Таблица 4.9.1. Пример ведения статистики дампов Процесс Версия Офсет 08.04 – 14.04 15.04 – 21.04 ragent 8.2.16.368 4d47e384 6 0 rmngr 8.2.16.368 4d3ea44a 4 2 rmngr 8.2.16.368 4d40e8c5 15 0 rmngr 8.2.16.368 4d44a565 2 0 Инструкции Процесс Версия Офсет 08.04 – 14.04 15.04 – 21.04 rphost 8.2.16.368 0065006c 0 1 rphost 8.2.16.368 1b8627ae 0 1 rphost 8.2.16.368 30940232 0 1 27 5 Итого 161 Сбор дампов вручную Если вы ведете работу во взаимодействии с фирмой «1С», вам может потребоваться предоставлять дампы с зависших процессов и в иных случаях, когда автоматическое формирование их средствами «1С» не сработало. В этом случае надо пользоваться утилитой procdump. Скачать ее можно с сайта Microsoft Technet, из его части Sysinternals. Как ею пользоваться, приведено в примерах ниже. Например, чтобы автоматически формировался дамп при краше процесса rphost, нужно запустить bat-файл, содержащий следующую команду: procdump.exe -ma -t -e 1 -f "" -l -o rphost dump_rphost_main > dump_rphost_main_log.txt Если в диспетчере задач (Task Manager) несколько процессов с именем rphost или rmngr, то нужно для каждого такого процесса создать свой bat-файл, заменить имена процессов на PID и запустить в отдельной директории (чтобы логи не перекрывали друг друга). Узнать PID можно в диспетчере задач на вкладке Процессы, выбрав пункт меню Вид – Выбрать столбцы... и установив флажок в поле ИД процесса (PID). Чтобы снять дамп вручную, нужно запустить bat-файл, содержащий, например, следующую команду: procdump.exe -ma rmngr dump_rmngr_hand Или используя PID: procdump.exe -ma 4252 dump_rphost_hand Если будет получено сообщение об ошибке, состоящее из знаков вопросов (см. ниже), то bat-файл надо попробовать запускать либо под администратором (Пуск – Все программы – Стандартные – Командная строка – контекстное меню – Запуск от имени администратора, и в появившемся окне набирать имя bat-файла), либо под пользователем, от имени которого работает процесс. Error opening rmngr.exe (1400): ?????? ???????? ???????. 162 Настольная книга 1С:Эксперта по технологическим вопросам 4.10. Работа с ЦКК. Общие принципы, стандартные возможности, первичная настройка Общие вопросы Центр контроля качества поможет методически грамотно организовать сбор и доставку информации о параметрах функционирования системы. ЦКК последней на текущий момент редакции 2.0.8.10 позволяет осуществлять постоянный мониторинг: количества аварийных завершений рабочих процессов кластера «1С:Предприятия» за час, день, неделю или месяц; ■■ доступности информационной базы для пользователей, процента времени, в течение которого базы были доступны для пользователей; ■■ ошибок при выполнении регламентных заданий; ■■ потребления памяти рабочими процессами; ■■ работоспособности собственно центра контроля качества; ■■ общего количества сеансов в зависимости от времени; ■■ времени выполнения ключевых операций в контролируемых информационных базах и APDEX времени выполнения; ■■ количества новых и измененных объектов в контролируемых информационных базах за час, день, неделю или месяц; ■■ количества сформированных отчетов в контролируемых информационных базах за час, день, неделю или месяц; ■■ количества сеансов, находящихся внутри серверного вызова; ■■ числа новых зарегистрированных проблем, а также числа проблем, решенных за час, день, неделю или месяц. Принцип работы ЦКК заключается в том, что контроль полностью автоматизирован. При возникновении ситуаций, требующих вмешательства, генерация сообщений осуществляется автоматически, и так же автоматически осуществляется рассылка этих сообщений ответственным. ■■ Мониторинг работы системы ведется постоянно, сбору подлежит вся необходимая информации, которая может помочь при устранении критических ситуаций в контролируемой системе. Ядро системы изолировано от ее прикладных составляющих (контрольных процедур). Имеется возможность легко добавлять новые контрольные процедуры или заменять существующие без внесения изменений в ядро системы, то есть ЦКК можно использовать как платформу для автоматизации других контрольных процедур, которые сейчас там не реализованы. Инструкции 163 Что надо сделать для начала работы 1. Развернуть базу. 2. Настроить, кому и как отправляются оповещения (пройти мастер настройки). 3. Настроить периметр контроля (т. е. указать сведения про базы, кластер, рабочие процессы и внешние ЦКК). 4. Настроить появившиеся после заполнения периметра штатные контрольные процедуры, по возможности – запустить, но можно это сделать и позднее. 5. При необходимости развернуть еще одну базу ЦКК и добавить свои контрольные процедуры (как это сделать, описано в следующей главе). Далее эта же последовательность описана более подробно. ЦКК рекомендуется разворачивать непосредственно в локальной сети контролируемой системы. Но это надо делать на отдельном рабочем сервере, на котором запущен отдельный кластер «1С:Предприятия», иначе (при размещении ЦКК на том же сервере в том же кластере, что и рабочие базы) его возможности по контролю могут быть серьезно ограничены. ЦКК нет смысла разворачивать в файловом варианте, кроме как просто в ознакомительных целях. Мы не рекомендуем использовать демобазу ЦКК в качестве исходной для создания своей рабочей базы ЦКК. Правильным будет пользоваться базой, заполняемой с нуля, как показано на рис. 4.10.1. Рис. 4.10.1. Создавать рабочую базу ЦКК нужно не из демошаблона При первом входе в базу нужно пройти мастер настройки (появляется автоматически), прохождение которого показано на рис. 4.10.2–4.10.8. Нюансы описаны в подписях к рисункам. 164 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.10.2. Ввести имя Рис. 4.10.3. Указать способы оповещения – электронная почта, SMS или и то и другое вместе Рис. 4.10.4. Указать, надо ли посылать сообщения о собственной работоспособности и принимать такие сообщения от других ЦКК. Период отправки отчетов указывается в минутах. В отличие от других контрольных процедур, эта процедура генерирует письма, когда все нормально, а не когда что-то случилось Инструкции 165 Рис. 4.10.5. Настройки электронной почты Параметры, указанные на рисунке, приведены для реальной работы с mail.ru (только надо поменять имя email2@mail.ru на свое). Рис. 4.10.6. Параметры отправки SMS. Доступны провайдеры «Билайн» и МТС 166 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.10.7. В базе есть предопределенный элемент справочника «Роли пользователей»: «ОтветственныйЗаПериметрКонтроля». Нужно указать его контакты. Что такое периметр контроля, будет показано далее Рис. 4.10.8. Перед завершением мастера будет проведена проверка введенных настроек способов связи. Если они будут пройдены, вы получите сообщение об успешном завершении, если нет – сообщение, где что не удалось выполнить При необходимости настройки в любой момент можно сохранить (может потребоваться вернуться и снять флажки на шаге «Параметры оповещения»). Донастроить их можно позднее, вызвав Запуск мастера настройки основных параметров на закладке Настройки. Инструкции 167 Рис. 4.10.9. Закладка «Настройка» После прохождения мастера на закладке Рабочий стол появится периметр контроля: список информационных баз из одной базы, список кластера серверов из одного сервера, список рабочих процессов из одного процесса и список внешних ЦКК из одного ЦКК (см. рис. 4.10.10). Нужно зайти во все элементы периметра (справочник Объекты контроля, подчиненный справочнику Виды объектов контроля) и заполнить их. При необходимости добавить свои компоненты (например, вторую информационную базу). Рис. 4.10.10. Периметр контроля При заполнении реквизитов элементов периметра, если реквизит интуитивно непонятен, нужно пользоваться встроенной справкой на вкладке Рекомендации формы элемента (см. рис. 4.10.11). Там все объяснено очень подробно, и здесь дублировать содержащиеся там сведения нет необходимости. 168 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.10.11. Источник информации по заполнению реквизитов – закладка «Рекомендации» По мере прохождения периметра для его элементов будут автоматически создаваться контрольные процедуры: в текущей версии по три для каждой информационной базы и по одной для остальных видов объектов контроля (см. рис. 4.10.12). Рис. 4.10.12. Для всех элементов автоматически созданы предопределенные контрольные процедуры Инструкции 169 Необходимо зайти в каждую из созданных контрольных процедур и, опять же руководствуясь рекомендациями на соответствующей закладке, ввести нужные настройки, при наличии соответствующего решения о запуске контроля нажать Начать выполнение (см. рис. 4.10.13). По мере принятия решений о запуске, а также в зависимости от состояния контролируемого параметра (есть проблемы или нет) индикатор «Состояние системы» на рис. выше будет делиться на сектора, имеющие цвет в соответствии с приведенной на индикаторе легендой. Рис. 4.10.13. Необходимо настроить и запустить контрольные процедуры Согласно встроенной документации: общий подход к повышению качества: Все контрольные процедуры для каждой информационной базы должны быть настроены и запущены. ЦКК допускает дезактивацию контрольных процедур, однако такое решение следует принимать осознанно и индивидуально в каждом конкретном случае. ■■ Все запущенные контрольные процедуры выполняются автоматически в соответствии с заданным расписанием. В случае невозможности выполнения контрольной процедуры ЦКК формирует соответствующие задачи для пользователей ролей, ответственных за настройку контрольной процедуры. После появления фактических значений измеренных параметров за их динамикой можно будет следить на закладке Мониторинг. ■■ 4.11. Работа с ЦКК. Настройка собственных контрольных процедур В конфигурации Центра контроля качества, как указывалось в предыдущей главе, ядро системы изолировано от контрольных процедур. Можно создавать свои контрольные процедуры, копируя бизнес-процесс «Шаблон процесса контроля» (у него уже настроена карта маршрута, и в модуле есть необходимые служебные процедуры) и редактируя в его модуле процедуру ВыполнитьАнализ(). Это правильный способ, но на практике, при отсутствии точной инструкции, он может оказаться сложным или недоступным, потому что он потребует детально 170 Настольная книга 1С:Эксперта по технологическим вопросам разобраться в структуре конфигурации ЦКК: кроме бизнес-процесса, надо будет создать еще несколько прикладных объектов метаданных, правильно увязав их с ядром. Есть другой способ, не вполне изящный, зато существенно более простой. Можно создать две базы ЦКК: одна будет контролировать то, что заложено по умолчанию, а во второй перенастроить существующие бизнес-процессы (под которые вся структура метаданных уже создана) так, чтобы они выполняли контроль того, что нужно нам. В качестве примера перенастроим контрольную процедуру контроля памяти под контроль наличия файла logcfg.xml в нужном каталоге. Откроем модуль бизнес-процесса КонтрольПамяти (см. рис. 4.11.1). Рис. 4.11.1. Бизнес-процессы конфигурации ЦКК Переименуем в нем имеющуюся процедуру ВыполнитьАнализ() в ВыполнитьАнализ_() и создадим свою процедуру с тем же именем, написав в ней код, представленный на рис. 4.11.2. Инструкции 171 Рис. 4.11.2. Код контроля наличия файла logcfg.xml в нужном каталоге и отработка ситуации, когда он не найден Собственно, на этом внесение изменений закончено. Теперь контрольная процедура «Контроль потребления памяти»70 в дополнительной базе ЦКК будет следить за файлом logcfg.xml. Если настроить оповещение и переименовать файл logcfg.xml, эта контрольная процедура начнет генерировать поручения на решение проблем и рассылать оповещения, как показано на рис. 4.11.3 и 4.11.4. 57 Рис. 4.11.3. Сформировано поручение 70 Ее переименование потребует дополнительных усилий, которые здесь рассматривать не будем. 172 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.11.4. Прислано оповещение 4.12. Работа в профайлере. Как получить план запроса Получение плана запроса в профайлере Server подробно разобрано в разделе 3.14 главы «Теория». Поэтому здесь ограничимся рисунком с настройкой трассировки, необходимой для выполнения этого действия. Рис. 4.12.1. Настройка трассировки для получения планов запроса 4.13. Работа в профайлере. Как получить сумму duration 1. Подключиться профайлером к серверу, из меню Файл выбрать Создать трассировку. Можно использовать стандартный шаблон (см. рис. 4.13.1). 2. Если вы не одни на сервере, есть смысл добавить столбец DatabaseName (чтобы его увидеть, надо поставить флажок Все столбцы) и установить по нему фильтр (кнопкой Фильтры столбцов), см. рис. 4.13.2 и 4.13.3. Инструкции Рис. 4.13.1. Создание трассировки со стандартным шаблоном Рис. 4.13.2. Добавление столбца DatabaseName Рис. 4.13.3. Добавление фильтра по имени базы 173 174 Настольная книга 1С:Эксперта по технологическим вопросам 3. Стартовать трассировку. 4. Выполнить ключевую операцию, измерить время ее выполнения. 5. Приостановить трассировку кнопкой Пауза. 6. 7. Выполнить сохранение в таблицу базы: Файл – Сохранить как – Таблица трасси- ровки. В диалоговом окне (см. рис. 4.13.4) указать, в какую таблицу какой базы сохранять результат. Нельзя указывать имя базы «1С». Если вы работаете на тестовом оборудовании и работа носит разовый характер, можно пользоваться базой master, но лучше создать свою отдельную базу (не «1С») для этих целей. Рис. 4.13.4. Диалоговое окно выбора таблицы 8. Открыть SQL Management Studio, создать запрос к базе (в нашем случае master). Запрос должен выглядеть примерно так: SELECT sum (tt.Duration/1000) from [master].[dbo].[222] as tt 9. Выполнить этот запрос. Результатом будет сумма по полю Duration, переведенная в миллисекунды (см. рис. 4.13.5). Рис. 4.13.5. Запрос и его результат Инструкции 175 Пояснение: SQL Profiler тоже показывает время в миллисекундах, но на самом деле хранит его в микросекундах, и при сохранении в таблицу попадает число микросекунд. Чтобы видеть время и в SQL Profiler, и в SQL Management Studio в одном масштабе, в запросе стоит деление на 1000. 10. Сравнить общее время выполнения ключевой операции (п. 4) и время выполнения всех запросов в базе, рассчитанное в п. 9. Сделать вывод о том, находится проблема в СУБД или нет. 4.14. Работа в профайлере. Как получить граф взаимоблокировки Для получения графа взаимоблокировки достаточно настройки, представленной на рис. 4.14.1: Рис. 4.14.1. Настройка трассировки для получения графа взаимоблокировки Если взаимоблокировка поймана, ее граф будет нарисован в профайлере, а всплывающая подсказка выведет информацию о запросах, как показано на рис. 4.14.2. Информацию о взаимоблокировке можно сохранить в XML-файл, если выбрать строку с взаимоблокировкой в верхнем окне профайлера и в контекстном меню выбрать пункт Извлечь данные события... После ответа на стандартный вопрос (куда сохранять) сохраненный файл можно будет смотреть «Блокнотом». Его вид представлен на рис. 4.14.3. Важные для разбора взаимоблокировки позиции (запросы и порядок вызовов) выделены овалами. 176 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.14.2. Отображение графа взаимоблокировки в профайлере Рис. 4.14.3. XML-файл подробностей взаимоблокировки Инструкции 177 4.15. Работа в профайлере. Как получить сведения об эскалации блокировок Что такое эскалация блокировок, см. главу «Теория», раздел 3.10. На практике для установки факта эскалации блокировок достаточно включить трассировку события Lock:Escalation (см. рис. 4.15.1). Рис. 4.15.1. Настройка SQL Profiler для поиска эскалаций блокировок Если событие произошло, оно появится в трассировке (см. рис. 4.15.2). Рис. 4.15.2. Произошла эскалация блокировок Если мы говорим о работе системы на платформе «1С:Предприятие», всегда надо иметь в виду, что после эскалации данные окажутся заблокированы на уровне таблицы. 178 Настольная книга 1С:Эксперта по технологическим вопросам 4.16. Работа с ЦУП. Общие принципы, стандартные возможности, общая последовательность работы, мастер настройки, таблица прав Общие вопросы Про ЦУП порой приходится слышать вещи, которые иначе как легендами назвать сложно. Одни всерьез полагают, что установка и правильная настройка ЦУП способны сами по себе избавить комплекс от всех проблем производительности. Другие не менее искренне считают, что работа с ЦУП – это тайное знание, доступное посвященным, которому, однако, можно научить внедренцев (разработчиков) за несколько практических занятий, и тогда они начнут писать оптимально работающий код. Чаще, чем хотелось бы, приходится слышать словосочетание «Внедрение ЦУП». Источники подобных небылиц станут вам ясны, если вы когда-нибудь пробовали научить работать в «Бухгалтерии предприятия» человека, не разбирающегося в бухучете. Или если вы сами работали внедренцем или продавцом и пытались понять, как «Бухгалтерия предприятия» работает или как ее можно продавать, но сами при этом даже не знали наизусть плана счетов, не говоря уже о методике ведения хотя бы простейшего учета. Или если вы пытались понять, как нужно вести бухгалтерский учет, ориентируясь только по тому, как работает «Бухгалтерия предприятия». С ЦУП ровно то же самое. ЦУП – это нужный и полезный инструмент для людей, разбирающихся в предмете. Но сам по себе он ничего не исправит. Чтобы понять, как устроена система, одного его недостаточно; оптимальный код он писать не научит. Иначе вся эта книга состояла бы из одной главы: «Как запустить и настроить ЦУП». Согласно документации, «Центр управления производительностью» (ЦУП) – инструмент мониторинга и анализа производительности клиент-серверных информационных систем на платформе «1С:Предприятие 8». ЦУП предназначен для оценки производительности системы, сбора подробной технической информации об имеющихся узких местах и анализа этой информации с целью дальнейшей оптимизации. «Центр управления производительностью» представляет собой независимую информационную базу «1С:Предприятия», которая может подключаться к кластеру серверов «1С:Предприятия» для исследования производительности. Для работы ЦУП не требуется внесения каких-либо изменений в код исследуемой информационной базы либо в состав компонентов сервера «1С:Предприятия» исследуемой базы. Единственная подготовка, которая должна быть произведена на стороне исследуемой базы, – настройка прав доступа. Теперь отложим документацию в сторону и сделаем несколько важных примечаний к ней. «Центр управления производительностью» – это действительно отдельная база «1С:Предприятия». Эта база умеет получать данные из разных источников (не только Инструкции 179 от кластера серверов «1С:Предприятия»), но все эти данные так или иначе связаны с работой запросов, ожиданиями на блокировках и ошибками блокировок. То есть, безусловно, ЦУП предназначен для оценки производительности системы и пр. Для этих целей он показывает, как ведут себя запросы (время выполнения и планы), есть ли ожидания на блокировках «1С» и СУБД и какие они, есть ли ошибки блокировок СУБД и что явилось их причиной. Но на этом и все. Если есть длинные запросы, избыточные ожидания на блокировках, а тем более ошибки блокировок, то система может и должна быть оптимизирована, и все данные для этого предоставляются ЦУП. На самом деле это очень много и очень ценно. И нет никаких других удобных способов получить эту информацию с такими подробностями, как ее предоставляет ЦУП. За бортом при этом остаются, однако, два момента: ■■ ■■ Нужны ли эти подробности для решения конкретной прикладной задачи. Сама проблема может находиться вне пространства работы запросов и ожиданий на блокировках. ЦУП, однако, решает те проблемы качества, которые по опыту составляют подавляющее большинство. Если бы большинство проблем создавалось, скажем, запросами в цикле, то ЦУП искал бы их. Работа с полученными данными. Умение получать данные – это хорошо, и этому действительно можно научить за короткое время. Но данные же надо не только получить, но и правильно понять, а дальше надо сделать правильные выводы и применить их для решения стоящей прикладной задачи. Вопросам понимания и извлечения выводов в большой степени посвящена эта книга, а применение их на деле – это вопрос практики, которую не вместить ни в какой самый продвинутый курс обучения. Что надо сделать для начала работы 1. Развернуть базу. 2. Настроить подключение к источникам информации (пройти мастер подключения к информационной базе). 3. Подключиться к интересующей вас базе в режиме мониторинга. 4. Добавить и включить нужные счетчики (в т. ч. аналитические, при необходимости настроив их), подождать 1 минуту. В следующей главе будет показано, какие счетчики обычно используют, и как сделать так, чтобы не добавлять их каждый раз вручную. 5. Если это рабочая база и подключение проведено в рабочее время, счетчики начнут в онлайне показывать статистику по запросам, по ожиданиям на блокировках и по ошибкам блокировок СУБД. Если это тестовая база, чтобы статистика начала отображаться, надо выполнить те действия, которые собираетесь анализировать. 6. После завершения теста (или интересной активности в рабочей базе) подождать 1 минуту, выключить счетчики. 180 Настольная книга 1С:Эксперта по технологическим вопросам 7. Для начала не надо делать длинных замеров, 3–5 минут (плюс по минуте на ожидания в начале и в конце) может быть достаточно. Увеличение длительности должно производиться осознанно. 8. Подключиться к интересующей вас базе в режиме просмотра, выбрать интересующий интервал времени, нажать Анализ или Авто в окне монитора анализа. 9. Если собиралась аналитическая информация, начнется анализ, который займет какое-то время, иногда продолжительное. Если не собиралась, будет показана та же статистика, что наблюдалась непосредственно в ходе замера. 10. Результаты анализа по готовности появятся в виде таблицы, их надо изучить и сделать выводы. 11. При необходимости провести следующие замеры и их анализ. 12. В рабочей базе далее можно пользоваться регламентным мониторингом. Далее в этой и двух следующих главах последовательность описана более подробно. Мастер подключения к базе Иногда приходится слышать про «Внедрение ЦУП». Никакого внедрения, разумеется, нет. Настройка ЦУП состоит в том, чтобы пройти мастер настройки подключения к исследуемой информационной базе. Как уже говорилось, ЦУП получает информацию из нескольких источников, и возможность получения данных из них как раз настраивается и проверяется при работе мастера. На каждом из шагов при наличии затруднений нужно нажать кнопку Инструкция в нижней части формы (см. рис. 4.16.1), получить подробное разъяснение, что еще надо сделать для прохождения текущего шага, и очень аккуратно и точно выполнить предложенные действия. Ниже будут описаны нюансы прохождения мастера, а в конце главы даны сводные таблицы требуемых прав. Пункты, описанные во встроенной справке, будут даны кратко и без картинок. 1. Запустить ЦУП, нажать Новое соединение, выбрать Мониторинг. 2. В списке информационных баз нажать Добавить. 3. Прочитать текст на закладке Начало, уйти с нее кнопкой Далее. 4. На закладке Наименование подключения указать произвольное удобное название (см. рис. 4.16.1). 5. Если возникнет остановка на шаге «СОМ-соединитель», необходимо зарегистрировать на компьютере, с которого запускается клиент ЦУП, компонент comcntr.dll из каталога установки клиента «1С», т. е., например, C:\Program Files (x86)\1cv82\8.2.18.104\bin (требуются права администратора – Пуск – Все программы – Стандартные – Командная строка – контекстное меню – Запуск от имени администратора). В появившемся окне набрать команды: cd C:\Program Files (x86)\1cv82\8.2.18.104\bin regsvr32 comcntr.dll Инструкции 181 Перед регистрацией надо завершить все процессы (клиентские приложения «1С:Предприятия», сервер «1С:Предприятия» и т. п.), которые используют comcntr.dll из каталога запуска клиентского приложения «1С:Предприятия». Рис. 4.16.1. Закладка «Наименование подключения» 6. На закладке Центральный сервер нужно указать имя или IP-адрес центрального сервера кластера и его порт (см. рис. 4.16.2). Рис. 4.16.2. Закладка «Центральный сервер» 182 Настольная книга 1С:Эксперта по технологическим вопросам Порт по умолчанию – 1540. Если вы не уверены, проверьте в консоли кластера, как показано на рис. 4.16.3, либо в свойствах службы агента «1С» (см. рис. 4.16.4). Рис. 4.16.3. Имя и порт центрального сервера «1С» в консоли кластера Рис. 4.16.4. Порт центрального сервера «1С» в свойствах службы агента «1С» 7. На закладке Кластер, как показано на рис. 4.16.5, надо указать кластер исследуемой базы (с ним трудно ошибиться, он выбирается из выпадающего списка), а также имя и пароль администратора. Вот с ними можно ошибиться. Инструкции 183 Рис. 4.16.5. Закладка «Кластер» мастера подключения к информационной базе Если в кластере исследуемой информационной базы нет ни одного администратора, то указывать имя и пароль администратора кластера на закладке Кластер не нужно. В консоли кластера есть два места, где назначаются администраторы. Для цели настройки ЦУП нужно указывать того, который на рис. 4.16.6 называется «АдминистраторК», а не «АдминистраторЦС». Рис. 4.16.6. Для целей ЦУП требуется «АдминистраторК» Если администратор кластера аутентифицируется средствами операционной системы, то в кластере исследуемой информационной базы должен быть 184 8. Настольная книга 1С:Эксперта по технологическим вопросам администратор кластера с привязкой к учетной записи, под которой «1С:Эксперт» входит в операционную систему, чтобы запускать клиента ЦУП (т. е. надо добавить эксперта в администраторы кластера). Тогда в форме на закладке Кластер не нужно указывать имя и пароль администратора кластера. Если эксперт (пользователь ЦУП) локальный (не доменный) и заведен не на той же машине, где стоит сервер «1С:Предприятия», то следует создать аналогичного пользователя на компьютере сервера исследуемой базы и добавить его в число администраторов кластера. Закладка Информационная база мастера подключения к информационной базе обычно трудностей не вызывает. На ней надо указать, к какой базе подключаемся, имя пользователя «1С» и его пароль, с помощью которых в эту базу можно заходить. Пользователь должен иметь права на администрирование и на внешнее подключение. Рис.4.16.7. Закладка «Информационная база» мастера подключения к информационной базе 9. На закладке Типы показателей можно выбрать, какие показатели вам нужны. Возможность ими пользоваться зависит от используемой СУБД, а также от наличия прав. Если вам не удается включить все показатели на этой закладке и пройти ее, очень внимательно прочитайте инструкцию, вызываемую по кнопке в нижней части формы. Если все вроде бы правильно сделано, но что-то не работает, попробуйте пройти мастер без части показателей, может быть, для решения прикладной задачи они вам и не понадобятся. Согласно встроенной справке: для пользователя, от имени которого запущен клиент ЦУП, должны быть настроены права доступа к Microsoft SQL Server следующим образом: □□ откройте SQL Server Management Studio и подключитесь к Microsoft SQL Server, на котором находится база данных исследуемой информационной базы; Инструкции 185 □□ перейдите в раздел «<Instance>\Security\Logins» и создайте новый логин для пользователя, от имени которого запускается клиент ЦУП (например, DOMAIN\expert1c. – Примеч. авт.). Рис. 4.16.8. Закладка «Типы показателей» мастера подключения к информационной базе 10. Чаще всего на практике сервер «1С» подключают к серверу СУБД под пользователем sa. Если у вас так же, вам достаточно поставить флажок в окне (см. рис. 4.16.9) и проследовать дальше. Рис. 4.16.9. Закладка «Показатели сервера 1С:Предприятия» 186 Настольная книга 1С:Эксперта по технологическим вопросам Если это не так (а выяснить это вы можете в свойствах информационной базы в консоли кластера, см. рис. 4.16.10), вам надо выполнить действия, указанные в инструкции, вызываемой кнопкой в нижней части формы. Согласно встроенной справке надо: □□ открыть SQL Server Management Studio и подключиться к серверу, на котором находится исследуемая база данных; □□ перейти в раздел <Instance>\Security\Logins и открыть свойства логина, используемого сервером «1С:Предприятия», исследуемой базы для подключения к СУБД; □□ открыть страницу «Server Roles», установить флажок напротив роли «processadmin» и нажать ОК: Рис. 4.16.10. Логин, под которым происходит подключение базы к серверу СУБД Инструкции 187 11. Закладка Показатели ОС. Согласно встроенной справке: показатели операционной системы на данный момент доступны только для Microsoft SQL Server. Поэтому, если используется этот тип СУБД, необходимо выполнение следующих требований: □□ Пользователь, от имени которого запускается клиент ЦУП, должен входить в группу «Performance Monitor Users» на компьютере, где запускается SQL Server. После добавления пользователя в группу может потребоваться выход и повторный вход в систему или перезагрузка для того, чтобы изменения вступили в силу. □□ Убедитесь (по умолчанию так и есть), что на компьютере, где запущен сервер СУБД: ○○ запущена служба «Удаленный реестр (Remote Registry)»; ○○ для пользователя, от имени которого запущен клиент ЦУП, есть право чтения раздела реестра «HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ Windows NT\CurrentVersion\Perflib»; ○○ в параметрах групповой политики (gpedit.msc) присутствует строка «Software\Microsoft\Windows NT\CurrentVersion\Perflib» в параметре «Политика Локальный компьютер \ Конфигурация Windows \ Параметры безопасности \ Локальные политики \ Параметры безопасности \ Сетевой доступ: удаленно доступные пути и вложенные пути реестра». 12. На закладке Технологический журнал (ТЖ) нужно указать каталоги работы с технологическим журналом, сделав это примерно так, как показано на рис. 4.16.11. При этом надо понимать, что: □□ в качестве первого каталога надо указывать реальный подкаталог conf существующего каталога установки сервера «1С:Предприятия», т. е. именно тот, в который в разделе 4.5 помещали logcfg.xml. Только в данном случае надо указывать не локальное имя, а сетевое; □□ второй и третий каталоги – это соответственно сетевое и локальное имя одного и того же каталога, в котором будет храниться технологический журнал сервера «1С». Этот каталог предварительно нужно создать и дать на него права на запись. Его аналог также создавали в разделе 4.5; □□ если кластер «1С» развернут на нескольких серверах, нужно указывать несколько каталогов ТЖ, добавив для каждого сервера свою строку табличной части справочника; □□ при отсутствии администраторских прав есть смысл в качестве сетевого пути указывать не путь через скрытый административный общий ресурс (как в примере, \\win2k8-sql\c$...), а сетевые пути к этим папкам – просить администраторов предоставлять общий доступ (с правами на запись) непосредственно к каталогам настроек ТЖ и самого ТЖ. При настройке данного пункта может быть получено сообщение об ошибке, на самом деле связанной с рассинхронизацией времени или другими 188 Настольная книга 1С:Эксперта по технологическим вопросам проблемами службы времени. Но по сообщению об ошибке понять это не удается, и выясняется только через прохождение данного пункта на отладчике. Если пункт пройти не удается, надо смотреть за содержимым каталогов: при появлении «градусника» на форме в каталоге настроек должен появиться, а затем исчезнуть logcfg.xml, а в каталоге ТЖ должна появиться, а затем исчезнуть папка со служебным именем. Исходя из этого, можно понять, какие действия получилось выполнить, а какие – нет. Рис. 4.16.11. Закладка «Технологический журнал» мастера подключения к информационной базе 13. Нажав Отмена, вы не потеряете внесенные изменения, если согласитесь на предложение сохранить их71. Чтобы продолжить, мастер придется проходить с начала, но однажды пройденные закладки уже будут заполнены.58 Чтобы пройти шаг «Трассировки», нужно создать на сервере СУБД каталог, дать в него права на запись и указать его в поле ввода на закладке. Если вы не будете удалять файлы трассировок (см. настройки далее), в них можно затем смотреть графы взаимоблокировок, такие же, как получали профайлером в разделе 4.14. Это бывает полезно, если ЦУП не сумеет их по каким-то причинам разобрать. 14. Чтобы иметь возможность получать трассировки, согласно встроенной справке (цитируются два раздела вместе): □□ Для пользователей, от имени которых запущены рабочие процессы кластера информационной базы ЦУП, и пользователя, от имени которого запущен клиент ЦУП, должны быть настроены права доступа к Microsoft SQL Server в соответствии с нижеприведенной инструкцией: ○○ Откройте SQL Server Management Studio и подключитесь к Microsoft SQL Server, на котором находится исследуемая информационная база. 71 Это пришлось сделать и в процессе подготовки текста. По этой причине следующие рисунки имеют в заголовке не «Создание», а «buh2». Инструкции 189 Рис. 4.16.12. Закладка «Трассировки» мастера подключения к информационной базе ○○ Перейдите в раздел «<Instance>\Security\Logins» и создайте новые логины для пользователей, от имени которых запускаются все рабочие процессы кластера информационной базы ЦУП (например, это usr1Cv82. – Примеч. авт.) и создайте новый логин для пользователя, от имени которого запускается ЦУП (например, это DOMAIN\expert1c. – Примеч. авт.). ○○ В открывшемся окне на странице «General» укажите имя настраиваемого пользователя операционной системы. ○○ Откройте свойства SQL Server, на странице «Permissions» для созданного логина установите разрешение «Alter trace». На компьютере, где запускается SQL Server, добавьте пользователей, от имени которых запускаются рабочие процессы кластера базы ЦУП, в группу «SQLServer MSSQLUser$<SERVERNAME>$<INSTANCENAME>». □□ Для пользователя, от имени которого запущен клиент ЦУП, должны быть настроены права доступа к Microsoft SQL Server и выданы разрешения работы с трассировками в соответствии с нижеприведенной инструкцией: ○○ Откройте SQL Server Management Studio и подключитесь к Microsoft SQL Server, на котором находится база данных исследуемой информационной базы. ○○ Перейдите в раздел «<Instance>\Security\Logins» и создайте новый логин для пользователя, от имени которого запускается ЦУП. ○○ В открывшемся окне, на странице «General» укажите имя настраиваемого пользователя операционной системы. ○○ Откройте свойства SQL Server, на странице «Permissions» для созданного логина установите разрешение «Alter trace». 190 Настольная книга 1С:Эксперта по технологическим вопросам 15. Если мастер сочтет нужным запросить дополнительную информацию по серверу ЦУП, он это сделает. Для сервера ЦУП, в частности, может потребоваться указать порт и администратора (у нас этот тот же АдминистраторК, о котором говорилось на шаге 7). Рис. 4.16.13. Закладка «Сервер ЦУП» мастера подключения к информационной базе 16. Закладка Сервер (СОМ-соединитель) не будет пройдена, если на сервере не установлен компонент «1С:Предприятия» СОМ-соединение. При установке 32-разрядной версии сервера он ставится автоматом, а вот при установке 64-разрядной версии сервера «1С» он по умолчанию выключен, и его надо включить, как показано на рис. 4.16.14 (попасть в это окно можно так: Пуск – Панель управления – Программы и компоненты – 1С:Предприятие 8.2 (х86-64)<версия> – Изменить – Изменить). Если компонент не был установлен, то после его установки потребуется перезапустить сервер «1С:Предприятия». Регистрация компонента произойдет автоматически. Не пытайтесь копировать 32-разрядный comcntr.dll в каталог запуска 64-разрядного сервера «1С:Предприятия». 17. Некоторые вкладки могут быть пройдены без дополнительных вопросов. Если же они возникнут, рекомендуется внимательно выполнять действия, описанные во встроенной справке. Сильно упрощает жизнь размещение ЦУП в том же кластере «1С», что и исследуемая база, и на том же сервере СУБД, если такое возможно. 18. На закладке Сервер ЦУП (Трассировки) при необходимости удаления трассировок надо указать сетевой каталог на сервере СУБД, который был указан как локальный на шаге 14. Инструкции 191 Рис. 4.16.14. Не забываем про СОМ-соединение Рис. 4.16.15. Закладка «Сервер ЦУП (Трассировки)» мастера подключения к информационной базе 19. Если мастер пройден успешно, на закладке Готово останется нажать кнопку Готово. В завершение еще несколько практических советов. 1. Не ставьте ЦУП в файловой версии, даже для режима оффлайнового просмотра результатов. Будет работать очень медленно. Лучше всего ставьте ЦУП на SQL Server, даже если для этого вам потребуется специально развернуть SQL Server. 192 Настольная книга 1С:Эксперта по технологическим вопросам 2. Как правило, если вам не удается пройти какой-то шаг настройки, это означает, что у вас недостаточно прав. Поэтому проводить настройку ЦУП надо, имея рядом администратора ОС, администратора кластера «1С», администратора СУБД и администратора информационной базы. Если все это разные люди, а администраторских прав вам не дают, в тяжелых случаях согласование прав может занять до двух месяцев. 3. Очень внимательно читайте инструкции по прохождению шагов и полностью их выполняйте. 4. Очень редко, но бывает, что сообщение об ошибке на каком-то из шагов не включает в себя истинной проблемы, потому что проблема уж больно экзотическая. В этом случае надо постараться понять, что на самом деле вернула проверка получения данных. Для этого нужно открыть отладчиком форму Настройка справочника Информационная база (см. рис. 4.16.16), найти там свой шаг и разобраться с работой алгоритма проверки и возвращаемыми данными. Рис. 4.16.16. Форма мастера настройки подключения к информационной базе в конфигураторе «1С» 5. Если баз много, то для упрощения подключения следующих баз иногда имеет смысл создать для справочника свою форму элемента и форму списка, позволяющие копировать и редактировать элементы этого справочника без прохождения Инструкции 193 мастера (см. окно конфигурации на рис. выше). При этом, однако, надо понимать, что по крайней мере для первого подключения в новом ландшафте мастер должен быть пройден полностью, иначе вы долго будете гадать, какие же пропущенные настройки привели к необъяснимым ошибкам при работе ЦУП. 6. Для решения некоторых проблем иногда нужно, чтобы сервер «1С:Предприятия» и сервер СУБД работали под одной и той же доменной учетной записью или под локальными записями с одинаковыми именами и паролями. 7. Как написано во встроенной справке, если есть два компьютера А и Б, на компьютере А есть локальный (не доменный) пользователь П, а на компьютере Б есть ресурс Р, то, чтобы предоставить пользователю П доступ к ресурсу Р, нужно: 8. □□ на компьютере Б создать локального пользователя П2 с тем же именем и паролем, что и у пользователя П; □□ на компьютере Б предоставить необходимые права пользователю П2 на ресурс Р. Это справедливо в том числе и для того, чтобы предоставить пользователю usr1Cv82 доступ к ресурсам сервера СУБД. Как написано во встроенной справке, рассинхронизация времени на серверах «1С:Предприятия» и СУБД приведет к неточности или невозможности анализа взаимоблокировок. Чтобы синхронизировать время на компьютере с мировым временем или временем домена, нужно: □□ для Windows воспользоваться «Инструкциями по службе времени Windows» (http://technet.microsoft.com/ru-ru/library/cc759314(v=WS.10).aspx); □□ для Linux настроить NTP (http://ru.wikipedia.org/wiki/NTP). Права, необходимые для работы ЦУП В таблицах 4.16.1–4.16.3 приведены права, необходимые для работы ЦУП версии 2.0. Будем считать, что ЦУП запускается с машины, на которой установлен кластер серверов «1С». Таблица 4.16.1. Настройка прав на серверы приложений «1С», необходимых для работы ЦУП версии 2.0 Показатель Цель Непосредственно работа с «1С» Регистрация Comcntr.dll Ресурс Права доменного пользователя – эксперта Система, клиентская часть «1С» Обычные права для работы с «1С» Права регистрации COM-объектов в системе Включение в группы Power Users и Distributed COM Users Права доменного пользователя, от имени которого запускаются рабочие процессы кластера «1С» 194 Настольная книга 1С:Эксперта по технологическим вопросам Показатель Цель Ресурс Все показа- Подключение тели ЦУП к кластеру «1С:Предприятия» Кластер «1С», консоль кластера Все аналитические показатели ЦУП Локальный файл logcfg.xml (по умолчанию "C:\Program Files\1cv82\<номер_версии>\bin\ conf\logcfg.xml") Локальный каталог файла logcfg.xml (по умолчанию "C:\Program Files\1cv82\<номер_версии>\bin\ conf") Сетевой каталог, представляющий локальный каталог файла logcfg.xml Локальный каталог технологического журнала Сетевой каталог, представляющий локальный каталог технологического журнала Запись и чтение технологического журнала «1С» Права доменного пользователя – эксперта Права доменного пользователя, от имени которого запускаются рабочие процессы кластера «1С» Должен быть администратором этого кластера, использующим аутентификацию операционной системы, либо при настройке требуется явно указывать имя и пароль администратора кластера без аутентификации ОС Чтение и запись Должен быть администратором этого кластера, использующим аутентификацию операционной системы, либо при настройке требуется явно указывать имя и пароль администратора кластера без аутентификации ОС Чтение и запись Чтение и запись Чтение и запись Чтение и запись по сети Чтение и запись по сети Создание, чтение и запись Чтение и запись Чтение и запись по сети Чтение и запись по сети Цель 72 Локальный каталог трассировки Сетевой каталог, представляющий локал. каталог трассировки Система Наличие привязанного логина на SQL Server c аутентификацией Windows и правом Alter trace Ресурсы SQL Server Права доменного Права локального пользователя, от имени или доменного которого запускаются пользователя, от рабочие процессы имени которого кластера «1С» запускается SQL Server Чтение и запись по сети Чтение и запись по сети Наличие привязанного логина на SQL Server c аутентификацией Windows и правом Alter trace Членство в группе SQLServer2005MSSQL User$<ServerName>$<I nstanceName>72 Создание, чтение и запись Чтение и запись Чтение и запись Включение в группы Performance Monitor Users и Distributed COM Users Enable account, Remote enable Права доменного пользователя, от имени которого работает эксперт Системный монитор производительности Windows WMI Control – Root\ CIMV2 Ресурсы SQL Server Ресурс При пользовании таблицей надо сделать поправку на версию сервера. ________________ Все показа- Получение тели ЦУП информации по блокировкам Microsoft SQL Server КоличеИспользование ственные системного показатели монитора произ"Коливодительности чество Windows таймаутов" и "Количество взаимоблокировок" АналиИспользование тический трассировок показатель Microsoft SQL "Анализ Server взаимоблокировок" Показатель Таблица 4.16.2. Настройка прав на серверы СУБД, необходимых для работы ЦУП версии 2.0 Должен быть членом фиксированной серверной роли processadmin Права логина SQL, используемого сервером «1С:Предприятия», для подключения к СУБД Инструкции 195 196 Настольная книга 1С:Эксперта по технологическим вопросам Таблица 4.16.3. Права в информационных базах, необходимые для работы ЦУП версии 2.0 Показатель Цель Исследуемая информационная база Информационная база ЦУП Права пользователя базы, под которым ЦУП подключается в базе Права пользователя, которым эксперт входит в базу ЦУП Права, не относящиеся к настройке прав для ЦУП, но необходимые для работы Непосредственно работа с «1С» Непосредственно работа с «1С» Все показатели ЦУП Подключение к исследуемой информационной базе Право работать в базе Полные права Настройка прав доступа для работы ЦУП Право на административные функции и право на внешнее соединение 4.17. Работа с ЦУП. Получение плана запроса Для начала несколько облегчим себе жизнь. В большинстве случаев нам придется собирать одни и те же показатели. Поэтому, чтобы не заполнять их список вручную, настроим собственный сценарий: 1. Из основного меню выбрать ЦУП – Сценарии. 2. Добавим свой сценарий «Мониторинг настроенный» путем копирования существующего предопределенного сценария «Мониторинг». Табличную часть заполняем, как показано на рис. 4.17.1. На нем показаны как раз все те показатели, которые обычно нужны для работы, и правильный порядок элементов структуры сценария. Строки рекомендуется добавлять копированием уже имеющихся. После сохранения сценарий станет доступен в меню Выбор сценария (см. рис. 4.17.2). Дальнейшие действия по получению плана запроса будем проводить, считая, что сценарий настроили. Чтобы его получить, нужно: 1. Подключиться к интересующей вас базе в режиме Мониторинг настроенный. Список счетчиков заполнится автоматически. 2. Настроить счетчик «Анализ запросов», как показано на рис. 4.17.3. В режим настройки можно войти двойным щелчком на названии показателя. Можно установить минимальную длительность запроса, которая будет приниматься для рассмотрения. Запросы с меньшей длительностью будут игнорироваться. Установка минимальной длительности на 0, как на рисунке, повышает точность разбора, но дополнительно повышает нагрузку на систему и сильно увеличивает длительность анализа. Установка «Получать планы запросов» также дополнительно повышает нагрузку на систему, но часто именно ради нее анализ и делается. 3. Включить флажки нужным счетчикам (см. рис. 4.17.4). Все счетчики анализа, если они не нужны, включать не надо – это просто дополнительная нагрузка, в данном случае бесполезная. Наоборот, статистику (все, что в списке идет выше анализа) включать обычно надо, чтобы просто понимать, что происходило. Инструкции Рис. 4.17.1. Добавление и заполнение своего сценария Рис. 4.17.2. Меню выбора сценария 197 198 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.17.3. Настройка счетчика «Анализ запросов» Рис. 4.17.4. Идет замер. Флажки установлены для показателей статистики и анализа запросов с целью получения их планов 4. Подождать 1 минуту с момента установки флажков. Если это рабочая база и подключение проведено в рабочее время, счетчики начнут в онлайне показывать статистику по запросам, по ожиданиям на блокировках и по ошибкам Инструкции 199 блокировок СУБД. В примере это тестовая база. В ней запускаем на выполнение те действия, которые собирались анализировать (перепроведение документов Реализация товаров и услуг). 5. После завершения интересной активности (ее видно по статистическим73 показателям) подождать 1 минуту, выключить счетчики, сняв флажки.59 6. В примере замер проводился 6 минут (включая ожидания по минуте в начале и в конце). Увеличение длительности должно производиться осознанно. Чем длиннее замер, тем дольше будет идти анализ. 7. Выйти из режима мониторинга, нажав Стоп. 8. Подключиться к интересующей вас базе в режиме просмотра, выбрать интересующий интервал времени, нажать Анализ в окне просмотра или Авто в окне монитора анализа (см. рис. 4.17.5). Рис. 4.17.5. Включение анализа 73 Термин «статистические показатели» не является общепринятым. В данной книге его используем для удобства в значении «неаналитические показатели», т. е. такие, которые не требуют анализа и которые можно наблюдать в онлайне: статистика по запросам, по ожиданиям на блокировках и по ошибкам блокировок СУБД. 200 9. Настольная книга 1С:Эксперта по технологическим вопросам Начнется анализ (см. рис. 4.17.6), который займет какое-то время. В это время, вообще говоря, можно проводить новые замеры, запустив клиента «1С» и войдя в ту же базу ЦУП второй раз. Рис. 4.17.6. Анализ в своей сессии блокирует окно, но можно зайти в ЦУП второй раз, продолжать замеры и отслеживать состояние анализа по «монитору анализа» 10. Результаты анализа по готовности появятся в виде таблицы, их надо изучить и сделать выводы. В нашем случае анализ 6-минутного замера занял чуть меньше часа. Как было видно на рисунках со статистикой, замер имеет явно выраженный пик. Посмотрев таблицу результатов (см. рис. 4.17.7 и 4.17.8), можно увидеть, что вопреки ожиданиям он не относится ни к учету авансов, ни к партионному учету, а относится просто к записи в одну из таблиц регистра бухгалтерии «Хозрасчетный». Почему это произошло, станет ясно дальше. Инструкции Рис. 4.17.7. Результат анализа. Запросы, отсортированные в порядке убывания длительности. Длительность здесь интерпретируется как вес Рис. 4.17.8. Результат анализа. Таблицы базы, отсортированные в порядке убывания длительности запросов к ним 201 202 Настольная книга 1С:Эксперта по технологическим вопросам 11. Двойным щелчком по строке с надписью «Выполнение запросов» перейти собственно в анализ (см. рис. 4.17.9). В примере можно увидеть, что таких запросов было довольно много, и некоторые из них имеют ощутимый вес. Рис. 4.17.9. Анализ запросов 12. Двойной щелчок по тексту запроса (выбранное поле на рис. выше) приводит к получению деталей об этом запросе, разделенных на несколько вкладок. Часть из них показана на рис. 4.17.10–4.17.13. Рис. 4.17.10. Детали запроса. Контекст вызова Инструкции Рис. 4.17.11. Детали запроса. Текст запроса, как его получает сервер СУБД. В нижнем окне этот же запрос переведен в термины метаданных Рис. 4.17.12. Детали запроса. План запроса. Часть 1 203 204 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.17.13. Детали запроса. План запроса. Часть 2 (правее) 13. План запроса получен. Надо проанализировать его визуально. По плану из примера видно, что поиск по индексу, возвращающий по одной строчке, выполнялся 217 раз (см. оператор Nested Loops). На Table Scan можно не обращать внимания, он осуществляется по временной таблице. Теперь стало понятно, что в приведенном примере причиной того, что запрос на запись в регистр работает дольше, чем запросы на чтение по авансам и по партионному учету, стало не необъяснимое стечение обстоятельств и не недостаточная скорость записи на диск по сравнению с чтением. Причиной длительной работы запроса является его неоптимальный план. 14. После выполнения анализа в режиме просмотра также станет доступна статистика анализа, по которой можно соотносить анализ со статистикой запросов, ожиданиями на блокировках и ошибками блокировок (см. рис. 4.17.14). Для наглядности в свойствах показателя можно поменять масштаб. Инструкции 205 Рис. 4.17.14. Режим просмотра. Стала доступна статистика анализа. Ср. рис. «Включение анализа» на шаге 8 4.18. Работа с ЦУП. Разбор взаимоблокировки Чтобы смоделировать взаимоблокировку, возьмем базу «Бухгалтерии предприятия КОРП» и в процедуру Обработка проведения документа Требование-накладная добавим следующий код: Процедура ОбработкаПроведения(Отказ, РежимПроведения) ... Движения.Хозрасчетный.Записать(); Предупреждение("Подождите1"); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Хозрасчетный.Сумма |ИЗ | РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный"; Результат = Запрос.Выполнить(); Предупреждение("Подождите2"); 206 Настольная книга 1С:Эксперта по технологическим вопросам Выполнять его будем так: запустим «1С» в двух сеансах, перепроведем два разных документа Требование-накладная, сначала дойдем в обоих сеансах до останова с помощью модального окна «Подождите1», а потом попытаемся продолжить и дойти до модального окна «Подождите2». В одном из сеансов этого не получится сделать, возникнет взаимоблокировка. Чтобы разобрать взаимоблокировку с помощью ЦУП, надо сделать следующее: 1. Запустить ЦУП, подключиться к базе в режиме мониторинга и добавить аналитический показатель «Анализ взаимоблокировок СУБД»; либо воспользоваться настроенным (см. раздел 4.17) сценарием «Мониторинг настроенный». В нем можно включить запись всех показателей (см. рис. 4.18.1). Рис. 4.18.1. Взаимоблокировка MS SQL Server и настройки для ее записи и анализа 2. Подождать 1 минуту, выполнить действие. Убедиться, что взаимоблокировка произошла (см. рис. выше). 3. После возникновения взаимоблокировки подождать еще 1 минуту (при настройках по умолчанию можно просто дождаться, пока он уйдет с экрана, это несколько дольше 1 минуты). 4. Снять флажки, выйти из режима мониторинга кнопкой Стоп. Инструкции 5. 207 Подключиться к базе в режиме просмотра, нажать Авто в мониторе анализа (см. рис. 4.18.2) или Анализ (на рисунке не видна). Иногда при работе на высоконагруженных стендах, где высока вероятность аварийного завершения процессов, есть смысл не нажимать эти кнопки до тех пор, пока состояние анализа в мониторе не станет зафиксированным («Получение исходных данных» изменится на «Исходные данные получены», и появятся зеленые галочки). Рис. 4.18.2. Взаимоблокировка MS SQL и подготовка данных для анализа в режиме просмотра 6. Далее пройдет процесс анализа, по его окончании появится таблица с проблемами (см. рис. 4.18.3 и 4.18.4). 208 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.18.3. Проблемные запросы Рис. 4.18.4. Проблемные таблицы 7. Двойным щелчком по полю с надписью «Взаимоблокировки» в расшифровку взаимоблокировки (см. рис. 4.18.5). перейти Инструкции 209 Рис. 4.18.5. Расшифровка взаимоблокировки, аналог ее графа 8. Проанализировав таблицу визуально, можно убедиться, что сработал именно наш код, и именно так как было задумано: после записи отдельных областей данных была сделана попытка в тех же транзакциях прочитать общую для них область. 9. Нужно убедиться, что речь не идет о записи одного объекта (это актуально для больших нагрузочных тестов), расшифровав запросы из обоих процессов двойным щелчком и посмотрев поле Параметры запроса на закладке Запрос (см. рис. 4.18.6). 10. Также в расшифровке запроса на закладке Блокировки нужно проверить, не было ли, например, эскалации блокировок (если она была, то в поле Гранулярность будет Таблица), а также какой вообще была гранулярность блокировки. При блокировке строк или диапазонов ключей индекса компонент Database Engine74 помещает блокировку намерений (см. раздел 3.7) на страницы, содержащие эти строки или ключи. Это мы видим по полю Режим: запросом на запись строки заблокированы в режиме X, а на уровне страниц стоит блокировка намерений IX (см. рис. 4.18.7), которая остается до конца транзакции.60 74 Речь исключительно у СУБД SQL Server. 210 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.18.6. Параметры запроса. Второй параметр различается Инструкции 211 Рис. 4.18.7. Блокировка намерений на уровне страниц, установленная запросом на запись Запросом на чтение на том же уровне (т. е. на уровне страниц) делается попытка установить блокировку в режиме S (см. рис. 4.18.8). Это уже не блокировка намерений, а «обычная» блокировка, и в общем-то понятно, почему она такая, исходя из написанного запроса. Рис. 4.18.8. Блокировка на уровне страниц, устанавливаемая запросом на чтение Если не включено удаление трассировок, то граф взаимоблокировки можно посмотреть, открыв с помощью SQL Profiler соответствующий файл в каталоге трассировки на сервере СУБД. Иногда это бывает полезно. На файлы трассировки может не хватать прав на открытие. Чтобы это обойти, их можно скопировать в том же каталоге (Ctrl + C, Ctrl + V) и открывать копию файла. Если при анализе встретилась ошибка «Ошибка при вызове метода контекста (РазделитьФайл)», это означает, что файл logcfg.xml остался в состоянии продолжения сбора данных для ЦУП. Обычно остается сбор ТЖ по одному из аналитических показателей. Для обхода ошибки можно переименовать файл logcfg.xml вручную 212 Настольная книга 1С:Эксперта по технологическим вопросам и повторить попытку анализа, а уже потом разобраться с причинами, вызвавшими эту ошибку. Следует иметь в виду еще одну вещь: взаимоблокировки и таймауты, которые показывает ЦУП, могут происходить не обязательно в рабочей базе, они могут возникать на самом деле в других базах, а не в исследуемой. Это связано с методикой их получения, которая не дает информации о том, в какой из баз на сервере СУБД произошла ошибка блокировок. Поэтому вместе с аналитическими показателями нужно записывать статистику по запросам: ошибок блокировок без запросов не бывает. 4.19. Работа с ЦУП. Регламентный мониторинг Регламентный мониторинг может собирать необходимую для анализа информацию автоматически без участия пользователя. Работает это следующим образом. Необходимо подключиться к интересующей базе в режиме Регламентный мониторинг. Показатели добавляются в список автоматически, из сценария. Если в базе нет активности, показатели не записываются (см. рис. 4.19.1). Рис. 4.19.1. Показатели регламентного мониторинга Если в базе возникает определенная активность, автоматически включается запись показателей (см. рис. 4.19.2). Если активность прекращается, запись выключается. Опуская некоторые подробности (см. эту же главу ниже), можно считать, что запись включается при переходе показателей из «зеленой» зоны в «желтую» и «красную» Инструкции 213 (см. линии на рис. выше), а выключается для статистических показателей через 300 секунд, а для аналитических – через 1 800. Рис. 4.19.2. Автоматическое включение замера Этим процессом включения/выключения записи показателей можно управлять. Предопределенный сценарий «Регламентный мониторинг» закрыт от записи, однако ничто не мешает открыть справочник сценариев (Основное меню – ЦУП – Сценарии), создать новый сценарий «Регламентный мониторинг настроенный» путем копирования имеющегося (см. рис. 4.19.3) и использовать в работе именно его. Также это можно сделать, чтобы просто ознакомиться с правилами, которыми руководствуется имеющийся регламентный мониторинг. Двойной щелчок на каждом из полей открывает редактор событий, редактор команды и т. п., в зависимости от того, что это за поле. На рис. 4.19.4 показан редактор команды для поля, выделенного на рис. 4.19.3. 214 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.19.3. Настройка своего сценария регламентного мониторинга Рис. 4.19.4. Редактор команды для показателя «Анализ взаимоблокировок MS SQL Server» Границы зон, о которых идет речь в настройках сценария, задаются в форме, которая вызывается двойным щелчком по названию показателя в окне мониторинга (см. рис. 4.19.5). Инструкции 215 Рис. 4.19.5. Как задать границы зон Анализ данных замера может быть запущен автоматически. Произойдет это или нет, зависит от того, нажата ли кнопка Авто в окне монитора анализа. 4.20. Работа в конфигураторе. Исправление запросов Список правил При написании запросов могут быть допущены методические ошибки. Ниже перечислены правила, которых следует придерживаться. Большинство из них надо соблюдать всегда, вырабатывая правильный стиль написания кода. Однако есть правила, соблюдение которых требуется только при переписывании проблемных запросов (почему – станет ясно при ознакомлении с правилами), и для таких случаев в списке указано: «При возникновении проблем на данном участке кода». 1. Выбирать в запросе только то, что нужно.61 2. Понимать, что запрос через объектную модель может не соответствовать правилу 1. Зафиксирован случай, когда при получении ДокументСсылка.Проведен из базы на самом деле запрашивались все реквизиты документа. Один из реквизитов имел тип ХранилищеЗначения и большой размер данных в хранилище, поэтому запрос ДокументСсылка.Проведен выполнялся очень долго75. 75 Примечание ко второму изданию: абзац по сравнению с первым изданием не изменен, что происходит на самом деле – см. раздел 3.15 «Особенности чтения в объектной модели». 216 Настольная книга 1С:Эксперта по технологическим вопросам Обычно, однако, это не мешает работе, но при возникновении проблем на данном участке кода надо писать запросы на языке запросов, а не пользоваться объектной моделью. 3. При работе в автоматическом режиме блокировок при использовании конструкции ДЛЯ ИЗМЕНЕНИЯ надо указывать, какие таблицы блокировать, если в запросе участвует больше одной таблицы. Пояснения – в этой же главе ниже. 4. Условия в запросе и индексы в базе должны друг другу соответствовать (при возникновении проблем на данном участке кода). Пояснения – в этой же главе ниже. 5. При работе с виртуальными таблицами нужно использовать параметры виртуальных таблиц, а не выносить условия в секцию ГДЕ. 6. Не применять избыточное агрегирование. Механизм виртуальных таблиц сам считает сумму, и так, как в примере, делать не надо: СУММА(Остатки.СуммаВзаиморасчетовОстаток) КАК СуммаВзаиморасчетовОстаток 7. При соединении таблиц все условия и параметры, относящиеся к полям этих таблиц, ставить в условия соединения или пользоваться временными таблицами, а не оставлять их до секции ГДЕ. При этом, конечно, не должна страдать логика. 8. Не использовать подзапросы в условии соединения и в секции ГДЕ. Нужно использовать временные таблицы. Пояснения – в этой же главе ниже. 9. Вообще лучше не использовать соединения с подзапросами, а использовать временные таблицы. Пояснения – в этой же главе ниже. 10. Не соединять виртуальные таблицы с реальными, а также виртуальные с виртуальными. Правильно сначала результат виртуальной таблицы записывать во временную таблицу, индексировать ее по полям соединения, а затем уже соединять. Пояснения – в этой же главе ниже. 11. Не рекомендуется использовать логическое ИЛИ в условиях соединения, то есть в секции ПО запроса. Следует проанализировать решаемую задачу и попытаться найти другой алгоритм ее решения (при возникновении проблем на данном участке кода). 12. Аналогично с условием Не равно, особенно если на Не равно сравниваются ссылки (при возникновении проблем на данном участке кода). 13. В секции ГДЕ логическое ИЛИ использовать тоже не рекомендуется. Следует разбить один запрос на несколько и объединить результаты (при возникновении проблем на данном участке кода). Пояснения – в этой же главе ниже. 14. Избегать запросов к пустым таблицам в режиме автоматического управления блокировками «1С». Пояснения – в этой же главе ниже. 15. Понимать, как запрос может быть изменен при работе механизма RLS. 16. Аккуратно пользоваться разыменованием (получением данных «через точку»): □□ лучше бы не пользоваться (при возникновении проблем на данном участке кода), а использовать явное соединение; Инструкции 217 □□ совершенно точно не пользоваться для получения данных от полей составного типа (при возникновении проблем на данном участке кода). Пояснения – в этой же главе ниже; □□ для сравнения ссылок сравнивать только ссылки, если от этого не страдает логика (при возникновении проблем на данном участке кода менять логику): ПО ФИО.ФизЛицо = ФизЛица.Ссылка // правильно ПО ФИО.ФизЛицо.Наименование = ФизЛица.Ссылка.Наименование // неправильно □□ не получать еще раз .Ссылка: ПО ФИО.ФизЛицо = ФизЛица.Ссылка // правильно ПО ФИО.ФизЛицо.Ссылка = ФизЛица.Ссылка // неправильно □□ никогда не использовать конструкцию Ссылка.Ссылка. Это всегда ошибка. Далее будут даны пояснения к некоторым из перечисленные правил. Пояснение к правилу 3 («ДЛЯ ИЗМЕНЕНИЯ») При работе в автоматическом режиме блокировок при использовании конструкции ДЛЯ ИЗМЕНЕНИЯ надо указывать, какие таблицы блокировать, если в запросе участвует больше одной таблицы. Конструкция ДЛЯ ИЗМЕНЕНИЯ используется, чтобы вместо разделяемой блокировки S установить блокировку обновления U, совместимость которой с другими блокировками хуже (см. таблицу совместимости в конце раздела 3.7). Таким способом защищаются от взаимоблокировки, которая возникает при повышении уровня блокировки в транзакциях с уровнем изоляции Repeatable Read и Serializable76.62 Если не указывать, какие таблицы блокировать, то блокировка обновления U будет установлена на все таблицы, перечисленные в запросе, даже на те, в которые дальше не будет записи. Это будет мешать другим пользователям работать с ними. Пояснение к правилу 4 (соответствие индексов и условий запроса) Условия в запросе и индексы в базе должны соответствовать друг другу (при возникновении проблем на данном участке кода). В качестве иллюстрации приводится фрагмент статьи К. Рупасова «Типичные причины неоптимальной работы запросов и методы оптимизации». Фрагмент приведен без изменений, за исключением ссылок на другие материалы. Рекомендации Убедитесь в том, что для всех условий, использованных в запросе, имеются подходящие индексы. 76 Т. е. при автоматическом режиме управления блокировкой данных в «1С». В управляемом режиме такой проблемы не существует, а использование конструкции ДЛЯ ИЗМЕНЕНИЯ ни на что не влияет. 218 Настольная книга 1С:Эксперта по технологическим вопросам Условия используются в следующих секциях запроса: ВЫБРАТЬ … ИЗ … ГДЕ <условие> СОЕДИНЕНИЕ … ПО <условие> ВЫБРАТЬ … ИЗ <ВиртуальнаяТаблица>(, <условие>) ИМЕЮЩИЕ <условие> Для каждого условия должен существовать подходящий индекс. Подходящим является индекс, удовлетворяющий следующим требованиям: 1. Индекс содержит все поля, перечисленные в условии. 2. Эти поля находятся в самом начале индекса. 3. Эти поля идут подряд, то есть между ними не «вклиниваются» поля, не участвующие в условии запроса. При создании объекта метаданных «1С:Предприятие» автоматически создает индексы, которые должны подходить для работы большинства запросов. Основные индексы, создаваемые «1С:Предприятием»: индекс по уникальному идентификатору (ссылке) для всех объектных сущностей (справочники, документы и т. д.); ■■ индекс по регистратору (ссылке на документ) для таблиц движений регистров, подчиненных регистратору; ■■ индекс по периоду и значениям всех измерений для итоговых таблиц регистров накопления; ■■ индекс по периоду, счету и значениям всех измерений для итоговых таблиц регистров бухгалтерии. В тех случаях, когда автоматически созданных индексов недостаточно, можно дополнительно проиндексировать реквизиты объекта метаданных. ■■ Следует иметь в виду, что создание индекса ускоряет процесс поиска информации, но может несколько замедлить процесс ее изменения (добавления, редактирования и удаления). Поэтому индексы следует создавать осознанно и только в том случае, если точно известен запрос, для которого такой индекс необходим. Не следует создавать индексы «на всякий случай» или заведомо избыточные индексы. Например, никогда не следует дополнительно индексировать первое измерение регистра, поскольку для поиска по значению первого измерения подходит основной индекс таблицы итогов, который автоматически создаст платформа. Пояснения Если в структуре базы данных отсутствует индекс, удовлетворяющий всем перечисленным условиям, то для получения результата СУБД будет вынуждена сканировать таблицу или один из ее индексов. Это приведет к увеличению времени выполнения запроса, а также к возможному снижению параллельности системы, поскольку возрастет количество установленных блокировок. Требования к индексу, перечисленные в рекомендациях, связаны с физической структурой индекса в СУБД. Эта структура представляет собой дерево значений проиндексированных полей. На первом уровне дерева находятся значения первого Инструкции 219 поля индекса, на втором – второго и так далее. Такая структура позволяет достичь высокой эффективности при поиске по индексу. Кроме того, она гарантирует отсутствие деградации производительности индекса с ростом количества данных. Однако индекс такой структуры, очевидно, может быть использован только строго определенным образом. Сначала необходимо провести поиск по значению первого поля индекса, затем – второго и так далее. Если, например, условие по первому полю индекса не указано, то индекс уже не сможет обеспечить быстрый поиск. Если указано условие по нескольким первым полям индекса, а затем одно или несколько полей индекса не заданы, то индекс может быть использован только частично. Примеры В конфигурации описан регистр накопления ТоварыНаСкладах (см. рис. 4.20.1): Рис. 4.20.1. Структура регистра накопления «ТоварыНаСкладах» для нашего примера Платформа «1С:Предприятие» автоматически создаст для таблицы остатков данного регистра индекс по периоду и всем измерениям в том порядке, в котором они перечислены в конфигураторе. Рассмотрим несколько примеров запросов и проанализируем, смогут ли они оптимально выполняться при такой структуре данных. Запрос 1 Запрос.Текст = "ВЫБРАТЬ | ТоварыНаСкладахОстатки.Склад, | ТоварыНаСкладахОстатки.Номенклатура, | ТоварыНаСкладахОстатки.Качество |ИЗ | РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура = &Номенклатура) КАК ТоварыНаСкладахОстатки"; В данном случае нарушено требование 2. В условии отсутствует отбор по первому полю индекса («Склад»). Такой запрос не сможет выполниться оптимально. Для его выполнения серверу СУБД придется перебирать (сканировать) все записи таблицы. Время выполнения этой операции напрямую зависит от количества записей 220 Настольная книга 1С:Эксперта по технологическим вопросам в таблице остатков регистра и может быть очень большим (и будет увеличиваться с ростом количества данных). Варианты оптимизации: проиндексировать измерение «Номенклатура»; ■■ поставить измерение «Номенклатура» первым в списке измерений. Будьте внимательны при использовании этого метода. В конфигурации могут присутствовать другие запросы, которые могут замедлиться в результате этой перестановки. Запрос 2 ■■ Запрос.Текст = "ВЫБРАТЬ | ТоварыНаСкладахОстатки.Склад, | ТоварыНаСкладахОстатки.Номенклатура, | ТоварыНаСкладахОстатки.Качество |ИЗ | РегистрНакопления.ТоварыНаСкладах.Остатки( |, | Качество = &Качество | И Склад = &Склад) КАК ТоварыНаСкладахОстатки"; В данном случае нарушено требование 3. Между измерениями «Склад» и «Качество» в структуре регистра находится измерение «Номенклатура», которое не задано в условии запроса. Этот запрос также не сможет выполняться оптимально. При его выполнении СУБД выполнит поиск по первому полю индекса, но затем вынужденно просканирует некоторую его часть. Сканирование приведет к увеличению времени выполнения запроса и к блокировке избыточных записей в таблице, то есть к снижению общей пропускной способности системы. Варианты оптимизации: добавить в запрос условие по измерению «Номенклатура», ■■ убрать из запроса условие по измерению «Качество», ■■ перенести «Номенклатуру» из измерений в реквизиты, ■■ поменять местами измерения «Номенклатура» и «Качество». Запрос 3 ■■ Запрос.Текст = "ВЫБРАТЬ | ТоварыНаСкладахОстатки.Склад, | ТоварыНаСкладахОстатки.Номенклатура, | ТоварыНаСкладахОстатки.Качество, | ТоварыНаСкладахОстатки.КоличествоОстаток |ИЗ | РегистрНакопления.ТоварыНаСкладах.Остатки( |, | Номенклатура = &Номенклатура | И Склад = &Склад) КАК ТоварыНаСкладахОстатки"; В этом случае требования соответствия индекса и запроса не нарушены. Данный запрос будет выполнен СУБД оптимальным способом. Обратите внимание на то, что порядок следования условий в запросе не обязательно должен совпадать с порядком следования полей в индексе. Это не является проблемой и будет нормально обработано СУБД. Инструкции 221 Пояснение к правилу 8 (не использовать подзапросы в условиях) В качестве иллюстрации приводится фрагмент статьи К. Рупасова «Типичные причины неоптимальной работы запросов и методы оптимизации», фрагмент приведен без изменений. Не следует использовать подзапросы в условии соединения (и не только в условии соединения, но и вообще в условиях. – Примеч. авт.). Это может привести к значительному замедлению запроса и (в отдельных случаях) к его полной неработоспособности на некоторых СУБД. Пример запроса с использованием подзапроса в условии соединения: Запрос.Текст = "ВЫБРАТЬ | ОстаткиТоваров.Номенклатура КАК Номенклатура, | Цены.Цена КАК ЦенаПрошлогоМесяца |ИЗ | РегистрНакопления.ТоварыНаСкладах.Остатки(...) КАК ОстаткиТоваров | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цена КАК Цены | ПО Цены.Номенклатура = ОстаткиТоваров.Номенклатура И | Цены.Период В ( | ВЫБРАТЬ МАКСИМУМ(ЦеныПрошлогоМесяца.Период) | ИЗ РегистрСведений.Цена КАК ЦеныПрошлогоМесяца | ГДЕ ЦеныПрошлогоМесяца.Период < НАЧАЛОПЕРИОДА(ОстаткиТоваров.Период, МЕСЯЦ) | И ЦеныПрошлогоМесяца.Номенклатура = ОстаткиТоваров.Номенклатура | ) | ГДЕ ОстаткиТоваров.Склад = &Склад"; В данном случае подзапрос в условии соединения используется для получения как бы «среза последних» на конец предыдущего периода. Причем для каждой номенклатуры период может быть разным. Подобный запрос рекомендуется переписать с использованием временных таблиц. Например, это можно сделать следующим образом: Запрос.Текст = " // Максимальные даты установки цен в прошлом периоде для данных номенклатур |ВЫБРАТЬ | ОстаткиТоваров.Номенклатура КАК Номенклатура, | МАКСИМУМ(Цены.Период) КАК Период |ПОМЕСТИТЬ ДатыПоНоменклатурам |ИЗ | РегистрНакопления.ТоварыНаСкладах.Остатки(...) КАК ОстаткиТоваров | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цена КАК Цены | ПО Цены.Номенклатура = ОстаткиТоваров.Номенклатура И | Цены.Период < НАЧАЛОПЕРИОДА(ОстаткиТоваров.Период, МЕСЯЦ) | СГРУППИРОВАТЬ ПО ОстаткиТоваров.Номенклатура | ГДЕ ОстаткиТоваров.Склад = &Склад; // Выбрать данные по цене за найденный период |ВЫБРАТЬ | ДатыПоНоменклатурам.Номенклатура КАК Номенклатура, | Цены.Цена КАК ЦенаПрошлогоМесяца |ИЗ ДатыПоНоменклатурам | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цена КАК Цены | ПО Цены.Номенклатура = ОстаткиТоваров.Номенклатура И | Цены.Период = ДатыПоНоменклатурам.Период "; 222 Настольная книга 1С:Эксперта по технологическим вопросам Пояснение к правилу 9 (не использовать соединения с подзапросами, а использовать временные таблицы) В качестве иллюстрации приводится фрагмент статьи К. Рупасова «Типичные причины неоптимальной работы запросов и методы оптимизации». Фрагмент приведен без изменений. Рекомендации При написании запросов не следует использовать соединения с подзапросами. Следует соединять друг с другом только объекты метаданных или временные таблицы. Если запрос использует соединения с подзапросами, то его следует переписать с использованием временных таблиц. Если запрос содержит соединения с подзапросами, то это может привести к следующим негативным последствиям: крайне медленное выполнение запроса при слабой загрузке серверного оборудования. Замедление запроса может быть очень значительным (до нескольких порядков); ■■ нестабильная работа запроса. При некоторых условиях запрос может работать достаточно быстро, при других – очень медленно; ■■ значительная разница по времени выполнения запроса на разных СУБД; ■■ повышенная чувствительность запроса к актуальности и полноте статистик. Сразу после полного обновления статистик запрос может работать быстро, но через некоторое время опять замедлиться. Пример потенциально опасного запроса, использующего соединение с подзапросом: ■■ ВЫБРАТЬ ...ИЗ Документ.РеализацияТоваровУслуг ЛЕВОЕ СОЕДИНЕНИЕ ( ВЫБРАТЬ ИЗ РегистрСведений.Лимиты ГДЕ ... СГРУППИРОВАТЬ ПО ... ) ПО ... В данном примере в правой части соединения используется подзапрос, а не объект метаданных. Обратите внимание на то, что не важно, в какой части соединения (правой или левой) используется подзапрос. Точно так же не важно, какого типа соединение указано (ЛЕВОЕ, ПРАВОЕ и т. д.). Во всех случаях такая конструкция является потенциально опасной и должна быть исправлена при помощи временных таблиц. Обратите внимание на то, что возможность использования временных таблиц появилась в «1С:Предприятии» начиная с версии 8.1. Если вы используете версию 8.0, то для решения проблемы производительности такого запроса следует перейти на 8.1. Для оптимизации запроса следует разбить его на несколько отдельных запросов (по числу подзапросов, используемых в соединениях). Эти запросы рекомендуется поместить в один пакетный запрос. Инструкции 223 ВНИМАНИЕ! Не забудьте проиндексировать созданную временную таблицу. В качестве индексных полей следует указать все поля, которые используются в условии соединения. Для вышеприведенного примера получится следующий пакетный запрос: // Создать менеджер временных таблиц МенеджерВТ = Новый МенеджерВременныхТаблиц; Запрос = Новый Запрос; Запрос.МенеджерВременныхТаблиц = МенеджерВТ; // Текст пакетного запроса Запрос.Текст = " // Заполняем временную таблицу. Запрос к регистру лимитов. | ВЫБРАТЬ ... | ПОМЕСТИТЬ Лимиты | ИЗ РегистрСведений.Лимиты | ГДЕ ... | СГРУППИРОВАТЬ ПО ... | ИНДЕКСИРОВАТЬ ПО ...; // Выполняем основной запрос с использованием временной таблицы. ВЫБРАТЬ ... ИЗ Документ.РеализацияТоваровУслуг ЛЕВОЕ СОЕДИНЕНИЕ Лимиты ПО ...;" Пояснения Во встроенном языке запросов «1С:Предприятия» версии 8.0 отсутствовала возможность использовать временные таблицы и писать пакетные запросы. При этом часто было необходимо выполнять сложные вычисления в рамках одного запроса (то есть одного цикла взаимодействия клиент – сервер «1С:Предприятия» – сервер СУБД). Для решения таких задач использовались подзапросы – обращения не к объектам метаданных, а к выборкам из этих объектов. Как правило, подзапросы выполнялись с группировкой и часто использовались в соединениях. Оптимизатор сервера СУБД (независимо от того, какую СУБД вы используете) не всегда может правильно оптимизировать подобный запрос. В данном случае проблемой для оптимизатора является выбор правильного способа соединения. Существует несколько алгоритмов соединения двух выборок. Выбор того или иного алгоритма зависит от того, сколько записей будет содержаться в одной и в другой выборке. В том случае, если вы соединяете две физические таблицы, СУБД может легко определить объем обеих выборок на основании имеющейся статистики. Если же одна из соединяемых выборок представляет собой подзапрос, то понять, какое количество записей она вернет, становится очень сложно. В этом случае СУБД может ошибиться с выбором плана, что приведет к катастрофическому падению производительности запроса. Переписывание запроса по приведенной выше методике имеет своей целью упростить работу оптимизатору СУБД. В переписанном запросе все выборки, участвующие в соединениях, будут представлять собой физические таблицы, и СУБД сможет легко определить размер каждой выборки. Это позволит СУБД гарантированно выбрать самый быстрый из всех возможных планов. Причем СУБД будет 224 Настольная книга 1С:Эксперта по технологическим вопросам делать правильный выбор независимо ни от каких условий. Переписанный подобным образом запрос будет работать одинаково хорошо на любых СУБД, что особенно важно при разработке тиражных решений. Кроме того, переписанный подобным образом запрос лучше читается, проще для понимания и отладки. Следует понимать, что, переписав запрос таким образом, мы, возможно, внесли в него некоторое замедление за счет дополнительных накладных расходов – создания временных таблиц. Если СУБД не ошибется с выбором плана, то она, возможно, выполнит старый запрос быстрее, чем новый. Однако это замедление всегда будет крайне незначительным. Размер замедления зависит от используемой СУБД и производительности оборудования. В типичном случае на создание одной временной таблицы может уйти несколько миллисекунд. То есть эти замедления не могут оказать заметного влияния на производительность системы, и, как правило, ими можно пренебречь. Пояснение к правилу 10 (не соединять виртуальные таблицы с реальными, а также виртуальные с виртуальными) Не следует соединять виртуальные таблицы с реальными, а также виртуальные с виртуальными. Правильно сначала результат виртуальной таблицы записывать во временную таблицу, индексировать эту временную таблицу по полям соединения, а затем уже соединять. Как и в случае соединения с подзапросами, не имеет значения, какого типа соединение указано (ЛЕВОЕ, ПРАВОЕ и т. д.). Если запрос работает с неудовлетворительной производительностью и в нем используется соединение с виртуальной таблицей языка запросов «1С:Предприятия» (например, «РегистрНакопления.РасчетыСКлиентами.Остатки»), то рекомендуется вынести обращение к виртуальной таблице в отдельный запрос с сохранением результатов во временной таблице. Как это сделать, см. выше. Ниже приводится порядок действий, удобный при работе с конструктором и позволяющий избежать ошибок по невнимательности. При работе в конструкторе запросов исправления удобно вносить следующим способом. Исходный запрос: ВЫБРАТЬ ЗаказПациента.Ответственный, РасчетыСКлиентамиОстатки.СуммаОстаток ИЗ Документ.ЗаказПациента КАК ЗаказПациента ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.РасчетыСКлиентами.Остатки(, ЗаказКлиента = &ЗаказКлиента) КАК РасчетыСКлиентамиОстатки ПО (РасчетыСКлиентамиОстатки.ЗаказКлиента = ЗаказПациента.Ссылка) Открываем запрос конструктором, на закладке Пакет запросов создаем запрос копированием существующего. Инструкции 225 В запросе «Запрос пакета 1» (т. е. в верхнем из двух) переходим на закладку Дополнительно, в поле Тип запроса выбираем Создание временной таблицы и указываем ее имя (см. рис. 4.20.2). После этого «Запрос пакета 1» станет называться по имени временной таблицы (в нашем случае ВТ_РасчетыСКлиентамиОстатки). Рис. 4.20.2. Делаем дубль запроса, а результаты самого запроса помещаем во временную таблицу Далее в конструкторе на вкладке Связи смотрим, нет ли условий, ограничивающих нашу виртуальную таблицу РасчетыСКлиентами.Остатки. Если таковые есть, переносим их копированием: при наличии возможности – в параметры, при отсутствии – в ГДЕ. Затем на вкладке Таблицы и поля убираем все таблицы, кроме виртуальной таблицы РасчетыСКлиентами.Остатки, и добавляем поля, использующиеся в условии соединения, при этом может потребоваться ограничивать тип оператором ВЫРАЗИТЬ (см. рис. 4.20.3). На вкладке Индекс по этим полям индексируем временную таблицу. Рис. 4.20.3. Добавление поля для условия соединения Переходим на запрос пакета 2. На вкладке Таблицы и поля заменяем виртуальную таблицу на временную (см. рис. 4.20.4). 226 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.20.4. Замена виртуальной таблицы на временную Проверяем, что поля и связи остались после замены таблицы, при необходимости восстанавливаем. Результат изменений выглядит так: ВЫБРАТЬ РасчетыСКлиентамиОстатки.СуммаОстаток КАК СуммаОстаток, ВЫРАЗИТЬ(РасчетыСКлиентамиОстатки.ЗаказКлиента КАК Документ.ЗаказПациента) КАК ЗаказКлиента ПОМЕСТИТЬ ВТ_РасчетыСКлиентамиОстатки ИЗ РегистрНакопления.РасчетыСКлиентами.Остатки(, ЗаказКлиента = &ЗаказКлиента) КАК РасчетыСКлиентамиОстатки ИНДЕКСИРОВАТЬ ПО ЗаказКлиента ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ЗаказПациента.Ответственный, ВТ_РасчетыСКлиентамиОстатки.СуммаОстаток ИЗ Документ.ЗаказПациента КАК ЗаказПациента ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_РасчетыСКлиентамиОстатки КАК ВТ_РасчетыСКлиентамиОстатки ПО (ВТ_РасчетыСКлиентамиОстатки.ЗаказКлиента = ЗаказПациента.Ссылка) Приведем дополнение из цитированной в предыдущих пояснениях статьи К. Рупасова. Виртуальные таблицы, используемые в языке запросов «1С:Предприятия», могут разворачиваться в подзапросы при трансляции в язык SQL. Это связано с тем, что виртуальная таблица часто (но не всегда) получает данные из нескольких физических таблиц СУБД. Если вы используете соединение с виртуальной таблицей, то на уровне SQL оно может быть в некоторых случаях реализовано как соединение с подзапросом. В этом случае оптимизатор СУБД может точно так же выбрать неоптимальный план, как при работе с подзапросом, использованным в языке «1С:Предприятия» в явном виде. Инструкции 227 Пояснение к правилу 13 (в проблемных запросах отказываться от ИЛИ) Приведем пример из статьи К. Рупасова. Не следует использовать ИЛИ в секции ГДЕ запроса. Это может привести к тому, что СУБД не сможет использовать индексы таблиц и будет выполнять сканирование, что увеличит время работы запроса и вероятность возникновения блокировок. Вместо этого следует разбить один запрос на несколько и объединить результаты. Например, запрос: ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "001" ИЛИ Артикул = "002" следует заменить на запрос: ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "001" |ОБЪЕДИНИТЬ ВСЕ |ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "002" Пояснение к правилу 14 (избегать запросов к пустым таблицам в режиме автоматического управления блокировками «1С») Такие запросы могут быть связаны с особенностями документооборота в конкретной базе. При режиме автоматического управления блокировками «1С» будет использован уровень изоляции Serializable, будет заблокирован диапазон ключа индекса (и пустая таблица при таком подходе окажется заблокированной целиком), и даже разделяемая блокировка будет сохраняться до конца транзакции, не говоря уже об исключительной. Проведем эксперимент. Создадим в базе новые объекты: с двумя табличными частями ТабличнаяЧасть1 и ТабличнаяЧасть1, ■■ РегистрНакопления1 с одним измерением и одним ресурсом, ■■ РегистрНакопления2 с одним измерением и одним ресурсом, ■■ Документ1 установим в качестве регистраторов для этих регистров. В конфигурации установим автоматический режим управления блокировками. ■■ Документ1 Код обработки проведения показан на рис. 4.20.5, данные из табличной части 1 формируют движения по регистру накопления 1, данные из табличной части 2 формируют движения по регистру накопления 2. Дальше создадим и проведем пару десятков документов, заполняя в них только табличную часть 1. Проведем обновление статистики, очистим процедурный кеш (см. раздел 3.5). Проведем по одному документу в двух сеансах, также заполнив в них только табличную часть 1, при этом первый сеанс остановим на отладчике (см. рис. выше) и попытаемся перепровести второй документ. 228 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.20.5. Модуль документа «Документ1» Это не удастся сделать, результатом станет конфликт блокировок СУБД. Разобрав ожидания на блокировках ЦУП, увидим, что конфликт произошел на регистре накопления 2, то есть на пустой таблице, в которую идет запрос на запись «пустых» движений77. 63 Чтобы избавиться от конфликта блокировок, надо сделать одно из двух следующих действий: 1. В конфигурации установить управляемый режим управления блокировками. 2. Не записывать движения по регистру накопления 2 (см. рис. 4.20.6). 77 Поначалу может быть получен результат, что конфликт произошел на таблице, относящейся к регистру накопления 1. В таком случае надо убедиться, что корректны условия, обеспечивающие параллельность записи в него, т. е. создано достаточное количество документов, актуализирована статистика и процедурный кеш, различается период (месяц) документов или значение измерения регистра. Инструкции 229 Рис. 4.20.6. Один из вариантов избавления от конфликта блокировок – закомментировать запись заведомо пустых движений в заведомо пустую таблицу регистра Пояснение к правилу 15 (не получать значение через точку от поля составного типа) В качестве иллюстрации приводится фрагмент статьи К. Рупасова «Типичные причины неоптимальной работы запросов и методы оптимизации». Фрагмент приведен без изменений. Рекомендации Если в запросе используется получение значения через точку от поля составного ссылочного типа, то при выполнении этого запроса будет выполняться соединение со всеми таблицами объектов, входящими в этот составной тип. В результате текст запроса SQL чрезвычайно усложняется, и при его выполнении оптимизатор СУБД может выбрать неоптимальный план. Это может привести к серьезным проблемам производительности и даже к неработоспособности запроса в отдельных случаях. В частности, не рекомендуется обращаться к реквизитам регистратора регистра (например, ТоварыНаСкладах.Регистратор.Дата) и т. п. При этом не важно, в какой 230 Настольная книга 1С:Эксперта по технологическим вопросам части запроса вы используете реквизит, полученный через точку от поля составного типа, – в списке возвращаемых полей, в условии и т. п. Во всех случаях такое обращение может привести к проблемам производительности. Общая рекомендация заключается в том, чтобы по возможности ограничить количество соединений в таких запросах. Для этого можно использовать следующие приемы: Избегайте избыточности при создании полей составных ссылочных типов. Указывайте ровно столько возможных типов для данного поля, сколько необходимо. Не следует без необходимости использовать типы «любая ссылка» или «ссылка на любой документ» и т. п. Вместо этого следует более тщательно проанализировать прикладную логику и назначить для поля ровно те возможные типы ссылок, которые необходимы для решения задачи; ■■ При необходимости жертвуйте компактностью хранения данных ради производительности. Если в запросе вам понадобилось значение, полученное через ссылку, то, возможно, это значение можно хранить непосредственно в данном объекте. Например, если при работе с регистром вам требуется информация о дате регистратора, вы можете завести в регистре соответствующий реквизит и назначать ему значение при проведении документов. Это приведет к дублированию информации и некоторому (незначительному) увеличению ее объема, но может существенно повысить производительность и стабильность работы запроса; ■■ При необходимости жертвуйте компактностью и универсальностью кода ради производительности. Как правило, для выполнения конкретного запроса в данных условиях не нужны все возможные типы данной ссылки. В этом случае следует ограничить количество возможных типов при помощи функции ВЫРАЗИТЬ. Если данный запрос является универсальным и используется в нескольких разных ситуациях (где типы ссылки могут быть разными), то можно формировать запрос динамически, подставляя в функцию ВЫРАЗИТЬ тот тип, который необходим при данных условиях. Это увеличит объем исходного кода и, возможно, сделает его менее универсальным, но может существенно повысить производительность и стабильность работы запроса. Пример ■■ В данном запросе используется обращение к реквизитам регистратора. Регистратор является полем составного типа, которое может принимать значения ссылки на один из 56 видов документов. Запрос.Текст = "ВЫБРАТЬ | Продажи.Регистратор.Номер, | Продажи.Регистратор.Дата, | Продажи.Контрагент, | Продажи.Количество, | Продажи.Стоимость |ИЗ | РегистрНакопления.Продажи КАК Продажи |ГДЕ ... Инструкции 231 SQL-текст этого запроса будет включать 56 левых соединений с таблицами документов. Это может привести к серьезным проблемам производительности при выполнении запроса. Однако для решения данной задачи нет необходимости соединяться со всеми 56 видами документов. Условия запроса таковы, что при его выполнении будут выбраны только движения документов РеализацияТоваровУслуг и ЗаказыПокупателя. В этом случае мы можем значительно ускорить работу запроса, ограничив количество соединений при помощи функции ВЫРАЗИТЬ(). Запрос.Текст = "ВЫБРАТЬ | ВЫБОР | КОГДА Продажи.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг | ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг).Номер | КОГДА Продажи.Регистратор ССЫЛКА Документ.ЗаказПокупателя | ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.ЗаказПокупателя).Номер | КОНЕЦ ВЫБОРА КАК Номер, | ВЫБОР | КОГДА Продажи.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг | ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг).Дата | КОГДА Продажи.Регистратор ССЫЛКА Документ.ЗаказПокупателя | ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.ЗаказПокупателя).Дата | КОНЕЦ ВЫБОРА КАК Дата, | Продажи.Контрагент, | Продажи.Количество, | Продажи.Стоимость |ИЗ | РегистрНакопления.Продажи КАК Продажи |ГДЕ | Продажи.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг | ИЛИ Продажи.Регистратор ССЫЛКА Документ.ЗаказыПокупателя"; Этот запрос является более громоздким и, возможно, менее универсальным (он не будет правильно работать для других ситуаций, когда возможны другие значения типов регистратора). Однако при его выполнении будет сформирован SQL-запрос, который будет содержать всего два соединения с таблицами документов. Такой запрос будет работать значительно быстрее и стабильнее, чем запрос в его первоначальном виде. Пояснение к правилу 16 (понимать, как запрос может быть изменен платформой при работе механизма RLS) Особенности работы механизма RLS демонстрировались в разделе 3.11. Этот механизм дописывает свои условия к запросам, и это следует принимать во внимание при исправлении проблемных запросов. Если от дописывания условий нельзя избавиться совсем, следует по крайней мере ограничить их количество, как рекомендуется в статье К. Рупасова: «Если в конфигурации описано несколько ролей с условиями RLS, то не следует назначать одному пользователю более одной такой роли. Если один пользователь будет включен, например, в две роли с RLS – бухгалтер и кадровик, то при выполнении всех его запросов к их условиям будут добавляться условия обоих RLS с использованием логического ИЛИ. Таким образом, даже если в исходном запросе нет условия ИЛИ, оно появится там после добавления условий RLS. Такой запрос также может выполняться неоптимально – медленно и с избыточными блокировками. 232 Настольная книга 1С:Эксперта по технологическим вопросам Вместо этого следует создать «смешанную» роль – «бухгалтер-кадровик» и прописать ее RLS таким образом, чтобы избежать использования ИЛИ в условии, а пользователя включить в эту одну роль. 4.21. Нагрузочные тесты Простейший Термин «нагрузочный тест» в контексте данной книги надо понимать не совсем как «испытание системы высокой нагрузкой». Далеко не всегда при тесте создается значимая нагрузка, но всегда в тестировании участвуют два и более клиентских приложения, и цель такого теста – выявить проблемы параллельности и их причины. Простейший нагрузочный тест состоит в следующем: запустить 2–3 сеанса «1С», подключенных к одной базе; ■■ в каждом из них открыть по одной форме документа, например, «Реализация товаров и услуг» (документы, понятно, должны быть разными); ■■ попытаться одновременно провести их, быстро нажав друг за другом кнопки ОК в разных окнах. В ряде случаев даже такой методики достаточно, чтобы проблемы параллельности себя проявили. ■■ Останов в отладчике Методика демонстрировалась в предыдущем разделе, в пояснении к правилу 14 (избегать запросов к пустым таблицам в режиме автоматического управления блокировками «1С»). Смысл методики в том, что иногда транзакции проходят за очень короткое время, и физически не получается достаточно быстро нажать друг за другом кнопки ОК в разных окнах. Поэтому, чтобы вторая транзакция гарантированно началась до окончания первой, первый сеанс «1С» запускают через отладчик и в нужном месте ставят точку останова. Когда первая дошла до этой точки и остановилась на ней, таким образом моделируя задержку бесконечной (нужной) длительности, запускают вторую транзакцию: ■■ ■■ чаще всего точку останова ставят в конце процедуры ОбработкаПроведения модуля документа; реже – в конце процедуры ПриЗаписи модуля набора записей регистра. Останов в модальной форме Методика демонстрировалась в разделе 4.18, когда моделировали взаимоблокировку для последующего разбора ее ЦУП. Смысл методики такой же, как и при останове на отладчике: организовать задержку бесконечной (нужной) длительности. Инструкции 233 Иногда останова на отладчике недостаточно, потому что требуется организовать задержку не в одном сеансе. Кроме того, как в примере в разделе 4.18, может требоваться некоторая последовательность прохождения этапов транзакций, которая при реальной работе достигается случайным образом, а нам она нужна гарантированно. Нагрузочное тестирование групповыми обработками Смысл методики состоит в достижении условий конфликтов блокировок случайным образом, когда точно не известен механизм и места их возникновения. Для этого в нескольких сеансах «1С» запускаются обработки «Групповая обработка справочников и документов», для каждого сеанса задаются свои условия отбора (например, по организации или по периоду), отбираются документы, после этого быстрым нажатием кнопки Выполнить в разных окнах друг за другом запускается параллельное перепроведение отобранных групп документов. Такой тест, конечно, не моделирует работу реальных пользователей (нет пауз между транзакциями), и найденные узкие места могут отличаться от тех, что будут иметь место при реальной работе. Однако последствия использования методик, явно не обеспечивающих должной параллельности работы (например, автоматическую регистрацию в последовательности), такой тест выявляет эффективно. Если в системе есть хорошие возможности для возникновения взаимоблокировок, бывает достаточно и двух параллельно работающих сеансов. Если же их нет, то нужно три-четыре сеанса минимум, иначе транзакции выстроятся по принципу застежки «молния»: ожидания на блокировках будут, а конфликтов блокировок может и не быть, и все отработает без ошибок, пусть и медленно. Если же на такие узкие места не попадаем, при наращивании количества сеансов в итоге все упирается в производительность оборудования. Работа с Тест-центром. Общие принципы и стандартные возможности. Простой тест с помощью Тест-центра Методика проведения нагрузочных тестов групповыми обработками становится неудобной, если тест приходится проводить много раз, каждый раз набирая условия отбора. Можно, конечно, не пользоваться групповой обработкой, а написать свои обработки, по одной для каждого сеанса, где уже будут заданы условия отбора. Но если число сеансов приближается к 10 и опять-таки речь не идет об однократном замере (а как правило, если уже дошло до таких экспериментов, то не идет), то сам запуск рабочих мест, выбор нужной обработки и запуск выполнения действий в большом количестве окон становятся достаточно утомительными. Если же сеансов 30 и больше, выполнение всех этих подготовительных действий вручную становится просто недопустимо долгим; результаты замеров увеличиваются в объеме, и их ручная регистрация и хранение также становятся затратными по времени. Кроме того, условия тестирования начинают требовать организовывать паузы между проведением 234 Настольная книга 1С:Эксперта по технологическим вопросам документов в рамках каждого из сеансов, появляется проблема неодновременности запуска и т. п. Всю эту рутинную работу позволяет автоматизировать Тест-центр из состава КИП. Он помогает автоматизированно решить задачи, перечисленные в предыдущем абзаце. То есть он может сам запустить нужное количество сеансов, передать каждому из сеансов нужную обработку, одновременно запустить их выполнение. Также он помогает организовывать паузы, хранение результатов, их просмотр и некоторые другие полезные сервисные функции. Тест-центр версии 1.2 организован с использованием обычных форм, 2.0 ранних редакций – управляемых, 2.0 последних редакций можно использовать в обоих случаях. Поэтому, описывая далее работу с Тест-центром, будем ориентироваться на поведение Тест-центра 2.0, точнее ред. 2.0.8.10. Сам Тест-центр состоит из двух частей: объектов метаданных, встраиваемых в конфигурацию базы, с которой далее предстоит работать, и тестовых обработок. Как было объяснено выше, эти обработки служат аналогами самописных обработок по выполнению некоторых действий и по сути ими и являются. Для того чтобы сам Тест-центр смог ими пользоваться, распределять по сеансам и т. д., эти обработки должны создаваться по определенному шаблону, т. е. в них должны быть некоторые заранее определенные объекты и код, а свой код требуется писать в строго отведенных местах. Встраивание Тест-центра в базу занимает несколько минут. Написание простейших тестовых обработок может занять тоже не более часа, а сложных – несколько месяцев. Чтобы разобраться с тем, что такое «тестовая обработка», «роль» и «сценарий» в Тест-центре, представьте, что никакого Тест-центра нет, что это вы написали сами четыре разные обработки: одна, встроенная в базу, перепроводит документы реализации и счета-фактуры (чтобы обеспечить разные сеансы, выполняющие одни и те же действия, разными данными, обычно используют генератор случайных чисел); ■■ вторая, тоже встроенная – платежки, входящие и исходящие; ■■ третья, внешняя – поступления; ■■ четвертая, тоже внешняя – тоже поступления, но с паузами в 3 секунды (все предыдущие обработки работают без пауз). Первую вы запустите в двух сеансах, вторую – в трех, третью – в четырех (все сеансы «1С» запустите с одного компьютера), четвертую – в одном, и одновременно их стартуете, нажав во всех окнах Выполнить. ■■ Фактически если вы так сделаете, вы выступите в роли Тест-центра. То есть вся эта совокупность данных – сколько пользователей с какой обработкой запустить и откуда их запустить – и есть сценарий теста. Каждая группа пользователей, выполняющих одну и ту же обработку, – это роль («Продажи», «Банк», «Закупки», «Закупки с паузами»). Обработка, не важно – встроенная или внешняя, это и есть тестовая обработка. Инструкции 235 Встраивание Тест-центра Чтобы встроить Тест-центр в исследуемую базу, нужно: 1. Если у вас нет cf последней версии, собрать его. Для этого взять cf из вашего дистрибутива или последний из ранее собранных, развернуть его в отдельной базе и накатить все обновления. Для обновления версии конфигурации следует использовать режим Обновление конфигураций. 2. Выполнить приложенную к нему инструкцию из файла 1cv8upd.htm, который находится в каталоге шаблонов конфигураций. В нем см. раздел «Объединение тестируемой конфигурации с Тест-центром версии N.N.N.N». Сейчас это выглядит примерно так: □□ сделайте резервную копию вашей информационной базы. Резервную копию можно создать: ○○ при использовании файлового варианта «1С:Предприятия 8» путем копирования файла 1CV8.1CD в отдельный каталог; ○○ при использовании клиент-серверного варианта «1С:Предприятия 8» средствами SQL Server; □□ запустите систему «1С:Предприятие» в режиме Конфигуратор; □□ откройте файл конфигурации Тест-центра для объединения. Для этого в меню Конфигурация выберите пункт Сравнить, объединить с конфигурацией из файла... (от постановки на поддержку в этом пункте обычно отказываемся. – Примеч. авт.); □□ снимите флажок с пункта Свойства основной конфигурации, разверните пункт Свойства; □□ поставьте флажок в пункте Модуль приложения основной конфигурации (модулям двух приложений: обычного и управляемого. – Примеч. авт.); □□ для строки Модуль приложения (для модулей и обычного, и управляемого приложения. – Примеч. авт.) в столбце «Режим объединения и порядок подчиненных объектов» выберите значение «Объединить с приоритетом основной конфигурации»; □□ все остальные параметры объединения оставьте со значениями по умолчанию; □□ нажмите кнопку Выполнить; □□ после объединения необходимо открыть модули управляемого и обычного приложения и убрать комментарии строк кода, обрамленные директивами //{{MRG[ <-> ] и //}}MRG[ < -> ]. В результате объединения в модуле управляемого приложения в процедуре ПриНачалеРаботыСистемы() должен появиться следующий текст: Попытка ТЦКлиент.ОбработатьПараметрЗапуска(ПараметрЗапуска); Если ТЦСервер.БСППодсистемаИспользуется(ТЦОбщий.БСПИмяПодсистемыУправленияДоступом()) Тогда ТЦСервер.БСПСоздатьГруппуДоступаТестЦентр(); КонецЕсли; Исключение ТЦОбщий.ЗаписатьВЖурнал(ИнформацияОбОшибке(), "Тест-центр"); КонецПопытки; 236 Настольная книга 1С:Эксперта по технологическим вопросам А в модуле обычного приложения в процедуре ПриНачалеРаботыСистемы() должен появиться следующий текст: Попытка ТЦКлиент.ОбработатьПараметрЗапуска(ПараметрЗапуска); Исключение ТЦОбщий.ЗаписатьВЖурнал(ИнформацияОбОшибке(), "Тест-центр"); КонецПопытки; □□ выполните сохранение конфигурации. Инструкция на этом заканчивается, но есть еще вещь, которую надо сделать, если речь идет об обычном приложении. Надо самостоятельно создать в интерфейсе подменю Тест-центр. Дело в том, что если конфигурация построена с использованием управляемых форм, интерфейс Тест-центра в ней появится без дополнительных усилий с нашей стороны, а если речь об обычном приложении, то это подменю надо создать и в него включить: □□ справочник ТЦСценарии, □□ справочник ТЦАгенты, □□ справочник ТЦВП (виртуальные пользователи), □□ справочник ТЦРоли, □□ документ ТЦТест (результаты тестов). Теперь можно приступать к созданию простейшего теста. Для начала надо скопировать имеющуюся в конфигурации обработку ТЦШаблонТестовойОбработки. Копию обработки переименовать, в примере назовем ее ТЦУниверсальная. Обязательно поменять ей синоним, автоматически он не изменится. Далее надо открыть форму обработки ТЦУниверсальная, найти процедуру ТЦВыполнить() и вписать в нее свой код. В примере на рис. 4.21.1 туда вписан код вызова созданной нами процедуры ТЦВыполнитьНаСервере(), и ниже сама эта новая проце- дура, создающая и записывающая документ ПлатежноеПоручение, не заполненный, но с отличительным комментарием, по которому можно понять, создан документ во время прогона теста или нет. На этом в конфигураторе работа закончена, его можно закрыть. Начинаем подготовку теста. Для этого: 1. Запустить базу в режиме исполнения. 2. Открыть справочник Сценарии, добавить сценарий, назвать его, например «Наш сценарий». 3. Из формы элемента сценария зайти в выбор роли, добавить Роль, назвать ее, например, «Первая роль». 4. Из формы элемента роли зайти в выбор обработки, добавить обработку. 5. В форме элемента обработки указать, что обработка внутренняя, и выбрать нашу обработку ТЦУниверсальная. 6. Записывая и закрывая формы обработки и роли и выбирая созданные элементы, вернуться в форму элемента сценария. Инструкции 237 Рис. 4.21.1. Код для примера теста 7. Из формы элемента сценария зайти в выбор пользователя, добавить пользователя (у Тест-центра это свой справочник ТЦПользователи). 8. В форме элемента пользователя выбрать пользователя из списка базы и указать его пароль. Это пользователь, от имени которого будет запускаться клиент «1С» и будут выполняться действия в базе. Для начала можно указать свой логин и пароль. 9. Записать и закрыть форму пользователя, выбрав созданный элемент, вернуться в форму элемента сценария. 10. Из формы элемента сценария зайти в выбор клиента, добавить клиента. 11. В форме элемента клиента указать тип клиента (тонкий, толстый обычное приложение, толстый управляемое приложение и пр.). 12. Из формы элемента клиента зайти в выбор компьютера, добавить элемент справочника «Компьютеры». 13. В форме элемента компьютера указать имя компьютера, с которого клиент будет запускаться (для начала – своего). 238 Настольная книга 1С:Эксперта по технологическим вопросам 14. Записывая и закрывая формы компьютера и клиента и выбирая созданные элементы, вернуться в форму элемента сценария. 15. Задать количество пользователей. Для целей примера укажем количество, равное 2. 16. Перейти на вкладку Параметры, установить флажок Пауза после запуска ВП. Все параметры, имеющиеся по умолчанию, увеличить в 10 раз, чтобы гарантированно успевать выполнять действия. 17. Сохранить и закрыть сценарий. 18. Если по каким-то причинам не удается записать элемент на любом из описанных выше шагов, то надо разобраться, почему этого не удается сделать, а для этого потребуется закрыть сценарий, не сохраняя его. Понятно, что, начав сначала, уже созданные элементы справочников повторно создавать не надо, только выбирать их. Проверим, что наша тестовая обработка выполняет то, что требуется: 1. Открыть справочник Роли. 2. Выбрать нашу роль «Первая роль». 3. Рядом с полем выбора обработки есть кнопка Настроить..., нажать ее. 4. В открывшейся форме обработки будет кнопка Выполнить (эту же форму можно вызвать через меню Операции – Обработки – ТЦУниверсальная; в управляемом интерфейсе через Все функции). Нажав кнопку Выполнить, убедиться, что действие (в нашем случае создание платежного поручения) выполняется правильно и без ошибок. При необходимости отладить обработку, снова запустив конфигуратор и подключившись отладчиком к сеансу «1С». 5. Закрыть открытые окна. Теперь все готово для запуска теста. 6. Запустить еще одного клиента «1С», в нем зайти в справочник Агенты, нажать Включить режим Агента. Этот сеанс будет агентом тестирования, до окончания теста его уже трогать не надо. В будущем надо будет запускать агентов Тест-центра на всех компьютерах, которые будут использованы для запуска виртуальных пользователей, но сейчас ограничимся только одним своим компьютером. 7. Вернуться в наш сеанс, открыть форму списка сценариев. 8. Выбрать созданный сценарий, нажать Выполнить. 9. Должно появиться окно состояния теста (с машинками), и начнут запускаться две новые клиентские сессии (поскольку в сценарии указано количество = 2). Когда клиент запустится, появится окно «ВРМ78 запущены. Нажмите ОК, для продолжения выполнения теста». 64 10. Если ВРМ не успели до конца запуститься и возникло сообщение об ошибке, закрыть форму списка сценариев и окно состояния теста, не выгружая запу- 78 ВРМ (виртуальное рабочее место, «робот») – клиентское приложение, выполняющее обработку по команде Тест-центра. Инструкции 239 щенные клиентские сессии. Заново открыть форму списка сценариев и запустить сценарий повторно. В дальнейшем интервалами ожидания запуска и подготовки можно управлять на вкладке Параметры формы элемента сценария. 11. Нажать ОК. 12. Окно состояния будет показывать прогресс теста и, если все сделано правильно, пройдет его целиком и покажет окно с результатом теста. 13. Поскольку мы в протокол ничего не писали, нам надо открыть список документов Платежные поручения и убедиться, что появились две новые платежки с нашим комментарием. 14. Если больше тестов не планируется, перейти в сеанс агента и отключить его. Сессии виртуальных пользователей после этого тоже окажутся выгруженными. Тест успешно завершен. Работа с Тест-центром. Шаблон полноформатного теста Последующие тесты можно усложнять, используя навыки, приобретенные при выполнении этого простейшего теста. Для организации любого теста нужно научиться делать еще ряд вещей: 1. Организовывать замеры времени выполнения операций и их хранение. 2. Организовывать запись в протокол. 3. Организовывать повторы действий и паузы между ними. 4. Организовывать сбор статистики об ошибках. 5. Блокировать мешающий функционал. Как это делать, объясняется ниже. Организация замеров времени выполнения операций и их хранения Тест-центр содержит средства, позволяющие хранить информацию о результатах теста. Для этого процедура должна содержать код: Компонента = КипВнешнийКомпонент.ПолучитьИнструменты(); ВремяНачала = КипВнешнийКомпонент.ЗначениеТаймера(Компонента); // выполнение действия //... ВремяОкончания = КипВнешнийКомпонент.ЗначениеТаймера(Компонента); ВремяВсего = (ВремяОкончания – ВремяНачала) / 1000; ТЦЗаписатьПоказатель("ВремяВсего", ВремяВсего); Иллюстрация этого будет приведена ниже, когда дело дойдет до примера теста. Однако на практике иногда требуется сразу оценивать результаты по методике APDEX. Тогда быстрее и проще организовать это по-другому, с помощью подсистемы «Оценка производительности» из состава БСП. Кроме того, она уже может быть встроена в конфигурацию. Как проверить, встроена ли она и как ее встроить, см. раздел 4.7. 240 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.21.2. Организация замера времени с помощью подсистемы «Оценка производительности» Отличие будет состоять в том, что, в отличие от замеров при интерактивных действиях пользователей, замер надо будет не привязывать к кнопкам, а вызывать из тестовой обработки, и не только начинать, но и завершать. Как это будет выглядеть в коде обработки, см. рис. выше. Предварительно надо создать предопределенный элемент «ЗаписьПлатежногоПоручения» в справочнике Ключевые операции. Код, относящийся к замеру времени, на рисунке имеет увеличенный отступ. Организация записи в протокол Чтобы организовать запись в протокол, добавим процедуру ЗаписатьВПротоколИнформацию(). Код этой процедуры и порядок ее вызова см. на рис. 4.21.3. Код, относящийся к записи в протокол, на рисунке имеет увеличенный отступ, больший чем у кода замера времени. Рис. 4.21.3. Организация записи в протокол Инструкции 241 Процедура ТЦОбщий.ЗаписатьВЖурнал() имеет также возможности по записи сообщений с выделенным уровнем «Ошибка» или «Предупреждение». Как этим пользоваться, см. саму процедуру. ВНИМАНИЕ! Протокол, записанный таким способом, использует журнал регистрации. Это означает, что при переносе базы, например, через dt, он перенесен не будет. Организация повторов выполнения действий и пауз между ними Будем считать, что тест не должен длиться дольше определенного времени, а между повторами действий будут одинаковые паузы. Для этого добавим нашей обработке ТЦУниверсальная два реквизита – ДлительностьРаботы и Пауза (оба с типом Число 10,0) и разместим их на форме (см. рис. 4.21.4). Для определенности будем считать, что речь идет о секундах. Теперь если в режиме исполнения зайти в настройку тестовой обработки через справочник Роли и ввести значения этим реквизитам, они сохранятся системой. Рис. 4.21.4. Созданные реквизиты и их размещение на форме Количество повторов при таком подходе можно примерно вычислить, разделив значение реквизита ДлительностьРаботы на сумму среднего времени выполнения нашего действия (записи платежки) и реквизита Пауза. Возвращаемся в процедуру ТЦВыполнить() и дописываем код, обеспечивающий этот функционал (см. рис. 4.21.5). 242 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.21.5. Код организации повторов и пауз Организация сбора статистики об ошибках Можно собирать статистику ошибок средствами Тест-центра, однако иногда на практике удобнее это делать просто включив технологический журнал сервера «1С» на событие EXCP, как описано в разделе 4.5, и вести классификацию и подсчет ошибок по нему. Блокировка мешающего функционала Во-первых, через процедуру ПередЗавершениемРаботыСистемы() или ПриЗавершенииРаботыСистемы() в модуле приложения (обычного или управляемого) надо найти вызов формы вопроса о завершении работы и заглушить его, чтобы это подтверждение никогда не запрашивалось. Установки флажка Больше не спрашивать может быть недостаточно, а подтверждать завершение работы для большого количества сеансов при выгрузке виртуальных пользователей – занятие утомительное. Во-вторых, через процедуры ПередНачаломРаботыСистемы() и ПриНачалеРаботыСистемы() надо найти и заглушить вызов информационных (например, проверки актуальности релиза конфигурации) и рекламных окон, чтобы эти окна никогда не появлялись. Установки флажков Больше не спрашивать, снятия флажков Показывать Инструкции 243 при начале работы и пр. может быть недостаточно. Даже если эти окна не запрашивают никакого подтверждения от пользователя, их вызов тратит время и ресурсы сервера. Если же запрашивают, тратят еще и силы оператора. Проверка внесенных изменений Дальше, чтобы проверить, насколько правильно нами все организовано, нужно повторить простой тест, описанный выше. Необходимо не забыть установить константу ВыполнятьЗамерыПроизводительности в Истину (для чего, например, написать обработку) и настроить длительность выполнения и паузы для обработки в роли «Первая роль». В процедуру ТЦВыполнить() внесем еще код, иллюстрирующий методику замеров и хранения показателей средствами Тест-центра, а также получение номера рабочего места ТЦНомерВРМ(). Рис. 4.21.6. Итоговый код процедуры «ТЦВыполнить()» Описанный тест по сути является шаблоном полноформатного теста, поскольку для выполнения реальной работы в нем может быть достаточно заменить создание и запись платежного поручения на действия, необходимые в вашей исследуемой базе, а большинство необходимых вещей в нем уже есть. 244 Настольная книга 1С:Эксперта по технологическим вопросам Результат записи показателей и протокол будут показаны в документе Результат форма которого откроется после завершения теста автоматически (см. рис. 4.21.7). теста, Рис. 4.21.7. Показатели и протокол теста Настроив справочник Ключевые операции, можно пользоваться обработкой Оценка производительности для оценки результатов замера по методике APDEX (см. рис. 4.21.8). Рис. 4.21.8. Результаты замеров по данным подсистемы «Оценка производительности» Работа с Тест-центром. Универсальный нагрузочный тест Можно добавить в базу регистр сведений, указывающий для каждого номера ВРМ список эталонных документов в базе. Присваивать ВРМ номера можно любым доступным способом, главное, чтобы они начинались с единицы, шли подряд и не повторялись. Например, для этих целей можно пользоваться специально созданным регистром сведений, в который в конкурентном режиме ВРМ будут записывать информацию о захваченном ими номере (при большом количестве ВРМ им нужно с помощью КипВнешнийКомпонент.Пауза() раздать случайные паузы, достаточные для того, чтобы не было конфликтов блокировок). Далее нужно поставить тестовой обработке задачу либо перепроводить эти эталонные документы, либо создавать новые копированием имеющихся, и прово- Инструкции 245 дить именно вновь созданные. Проводить созданные документы можно оперативно, в текущем числе, либо неоперативно, например датой эталонного документа. В качестве эталонных могут быть назначены документы совершенно разных типов. Они могут быть как специально подготовлены для теста, так и выбраны из числа имеющихся в рабочей базе. Заполнение такого регистра эталонных документов может проводиться вручную либо автоматизированно, по интересующему исследователя свойству, например, наличию более 1000 строк в табличной части. Такой тест при наличии подготовленных тестовых обработок, адаптированных именно под такую схему, наличии навыков встраивания Тест-центра в базу и автоматизированного заполнения регистра эталонных документов может быть подготовлен к первому успешному старту в теории за несколько часов, на практике за один-два дня. Это выгодно отличает его от стандартного подхода, при котором на подготовку тестовых обработок меньше двух-трех недель не уходит. Понятно, что описанный подход имеет некоторые ограничения: малое число ролей, или все должно сводиться к одной-двум ролям – перепроведению существующих документов либо копированию эталонных документов с последующим проведением документа-копии (тип документов значения не имеет, для любого пользователя допускаются любые комбинации); ■■ роли различаются не столько характером выполняемых действий, сколько настройками интенсивности работы; ■■ наличие базы с подходящим составом заполненных документов; ■■ в первом издании книги было указано ограничение на не очень большое максимальное количество пользователей (30). Впоследствии, однако, это ограничение было преодолено – с помощью только описанного подхода был проведен тест, в котором нагрузка создавалась 1041 виртуальным пользователем; ■■ в первом издании книги было указано ограничение на отсутствие интерактивных действий, в т. ч. открытие форм и формирование отчетов. Впоследствии и это ограничение было преодолено, для чего универсальным действием надо считать не перепроведение документа на сервере, а открытие формы на клиенте и нажатие на ней кнопки ОК (задача с отчетами тоже имеет решение). И единственное, что тут нужно, чтобы форма была явно нарисована в конфигураторе. В реальности довольно много практических задач на проведение нагрузочных тестов в эти ограничения вписываются. Из наиболее труднорешаемых проблем – наличие заполненной базы (т. е. все документы в нужном количестве должны существовать до теста и быть правильно заполненными), а также чтобы формы были явно нарисованы в конфигураторе. ■■ Здесь не приводится пример конкретной технической реализации универсального теста. Специалист, понявший идею и освоивший работу с Тест-центром, может воплотить ее в коде за очень небольшое время, что подтверждено нашей практикой. 246 Настольная книга 1С:Эксперта по технологическим вопросам Работа со Стандартным нагрузочным тестом «1С». Общие принципы и стандартные возможности Согласно встроенной документации: «Стандартный нагрузочный тест» предназначен для оценки производительности совокупности серверного оборудования и серверного программного обеспечения в «стандартных пользователях 1С». Основная область применения данного теста – выбор конфигурации серверного оборудования для целей конкретного внедрения. Для проведения тестирования необходимо запустить агентов Тест-центра на всех компьютерах, которые будут использованы для запуска виртуальных пользователей. Для запуска агента нажмите кнопку Запуск агента Тест-центра. Для настройки и запуска теста нажмите кнопку Запуск теста. Стандартный нагрузочный тест представляет собой независимую информационную базу «1С», в которой Тест-центр встроен в прикладное решение, настроен и прикрыт от внешних настроек сценарий тестирования и все, что с ним связано, автоматизированы все процессы по запуску пользователей, проведению теста и получению результатов. То есть по сути это тоже база со встроенным Тест-центром, только настроенная на специализированное тестирование. Суть этого тестирования заключается в том, что в нем принимает участие все больше и больше пользователей, пока, наконец, показатели производительности не снизятся до уровня «удовлетворительно» по методике APDEX (что это за показатели и какое им установлено целевое время, «зашито» в базе). Максимальное количество пользователей, при котором сохраняется уровень «хорошо», считается оценкой производительности системы. Таким образом можно сравнивать, например, старый сервер и новый. Если старый сервер имеет уровень в 80 «стандартных пользователей 1С», а новый – в 100, то очевидно, что большого выигрыша от перехода на новый сервер не будет; напротив, если разрыв велик – и выигрыш может быть велик. Таким же образом можно сравнивать одни настройки системного программного обеспечения, а также кластера серверов «1С» (имеется в виду приложение) и сервера СУБД с другими настройками их же и оценивать, будет от изменения настроек изменение производительности или нет, а если будет, то в какую сторону. Таким же образом можно сравнивать варианты размещения баз на разных дисках и многие другие вещи. Подводя итоги, стандартный нагрузочный тест – это инструмент для сравнения одного способа размещения (включая настройки программного обеспечения) информационной системы «1С» с другим способом размещения той же системы, позволяющий получить количественную характеристику такого сравнения. Распространенной практикой является запуск виртуальных рабочих мест на том же сервере, где расположен кластер серверов «1С». Это может быть ошибкой, так как в этом случае проверяется не способность сервера обрабатывать серверный код прикладного решения, а его способность запускать и обслуживать клиентские Инструкции 247 приложения. Если в реальности такой задачи перед ним не стоит, то проверять его надо не так. Надо запускать агентов на серверах терминалов, тогда и клиентские места будут запускаться на серверах терминалов. При этом мощность серверов терминалов также должна быть достаточной, чтобы обеспечить возможность запуска заведомо избыточного количества виртуальных пользователей. Новые возможности 8.3 по функциональному и нагрузочному тестированию Для функционального тестирования продуктов на платформе 8.2 использовался компонент Корпоративного инструментального пакета – Сценарное тестирование. Особенности его технической реализации не позволяли использовать его для проведения нагрузочных тестов. С появлением новых возможностей платформы 8.3 ситуация изменилась. Появились понятия клиента тестирования и менеджера тестирования – это сеансы «1С», запущенные с особыми параметрами. Сеанс «1С», запущенный как менеджер тестирования, осуществляет управление сеансами «1С», запущенными как клиенты тестирования. Один менеджер тестирования может управлять несколькими клиентами тестирования, каждым через отдельный порт (этот порт надо указывать при запуске клиента и в управляющем скрипте, выполняющемся на менеджере). Управляющий скрипт представляет собой код на языке «1С». Код заставляет элементы форм действовать так, как если бы с ними работал человек (пример будет приведен ниже). Существует возможность автоматизированной генерации этого кода. Менеджер и клиенты даже могут быть подключены к разным базам. Это делает возможным, пусть и с некоторыми ограничениями, использование этого механизма для проведения простых нагрузочных тестов. Ограничения следующие: ■■ ■■ ■■ поскольку код выполняется из одного менеджера тестирования, строки этого кода выполняются последовательно (управление всеми клиентами идет из одного модуля формы обработки). Действия, однако, могут быть запущены на выполнение почти параллельно, т. к. скрипт отработает так, как если бы это человек быстро нажал кнопки ОК в нескольких окнах друг за другом, при этом скрипт это сделает быстрее, чем человек; поскольку код ориентирован на появление строго определенных окон, сообщение об ошибке, полученное вместо формы списка, при нажатии кнопки ОК может «дезориентировать» скрипт. В этом, однако, тоже нет большой трагедии, т. к. хотя один клиент тестирования и остановится с ошибкой, но дальнейшие команды для него будут проигнорированы, а остальные сеансы продолжат работу; довольно сложно организовывать паузы между действиями, если нужны паузы разной длительности. Если речь о двух-трех-четырех сеансах, это еще можно организовать, но при большем количестве клиентов это становится сложным даже просто для понимания, особенно если надо редактировать чужой код; 248 Настольная книга 1С:Эксперта по технологическим вопросам скрипт для управления большим количеством клиентов тестирования трудно сделать удобным для понимания и модификации. Сложность задачи вкупе с организацией пауз представляется аналогичной написанию партитуры для дирижера оркестра: не каждому под силу; ■■ клиент тестирования должен быть запущен только как управляемое приложение. В то же время этот подход обладает существенным достоинством, перекрывающим многие его минусы. Это наглядность и простота (то есть скорость) создания скриптов, в случае когда они просты: открыть форму, ввести одно-два поля, нажать две-три кнопки. Особенно это актуально, если надо моделировать поведение именно интерфейсных объектов, а управляемые формы создаются программным способом. Эмуляция нажатия кнопок «изнутри» из конфигурации в таком случае может потребовать больших трудозатрат, а также сложностей с поддержкой при изменении кода конфигурации. Напротив, запись скрипта займет только несколько минут. Кроме того, код конфигурации меняется, а интерфейсные объекты на форме остаются те же (или появляются новые), переименовывают или удаляют их довольно редко. ■■ Продемонстрируем, как с нуля подготовить и выполнить функциональное и нагрузочное тестирование сразу для двух клиентов тестирования из одного менеджера. Если коротко, надо сделать следующее: 1. Запустить сеанс «1С», записать действия пользователя. 2. Преобразовать журнал действий в код «1С». 3. Этот код вставить в обработку, сеанс записи закрыть, при необходимости доработать код. 4. Запустить один сеанс «1С» как менеджера тестирования, другой (другие) – как клиентов. 5. С менеджера тестирования запустить обработку на выполнение, убедиться, что на клиенте (клиентах) выполняются действия, которые были записаны. Теперь это же опишем подробнее. За основу возьмем демобазу «Бухгалтерии предприятия» ред. 3.0 (3.0.23.8). 1. Запустить сеанс «1С», записать действия пользователя. Запустить конфигуратор. Из него запустить сеанс «1С» кнопкой, показанной на рис. 4.21.9. Рис. 4.21.9. Кнопка запуска сеанса «1С» в режиме записи действий пользователя В этом режиме сеанс содержит особые кнопки (см. рис. 4.21.10), слева направо – Начать запись, Прервать запись, Завершить запись. После начала записи кнопка Начать запись сменится на Приостановить запись (т. е. Play – Pause). Инструкции 249 Рис. 4.21.10. Кнопки управления записью действий пользователя Находясь в меню Рабочий стол, выполним следующие действия: □□ начнем запись; □□ откроем меню Банк и касса; □□ откроем список документов Платежные поручения; □□ откроем двойным щелчком п/п № КП00-000004; □□ изменим сумму документа, введем ее равной 900 руб.; □□ нажмем кнопку Провести и закрыть; □□ завершим запись. После нажатия кнопки Завершить запись откроется окно, содержащее журнал действий пользователя (см. рис. 4.21.11). Рис. 4.21.11. Журнал действий пользователя 2. Преобразовать журнал действий в код «1С». В том же сеансе, не закрывая его, нужно открыть обработку UILogToSctript.epf, которую можно найти на диске ИТС: Технологическая поддержка – 1С:Предприя- тие 8 – Универсальные отчеты и обработки – Преобразование журнала действий пользователя. 250 Настольная книга 1С:Эксперта по технологическим вопросам В простом случае, как у нас, достаточно установить флажки и переключатели, как показано на рис. 4.21.12, в поле Журнал действий пользователя скопировать текст из соседнего окна в том же сеансе (Ctrl + A, Ctrl + C, Ctrl + V) и нажать Преобразовать. В поле Сценарий появится код на языке «1С». Рис. 4.21.12. Преобразование журнала в код «1С» 3. Этот код вставить в обработку, сеанс записи закрыть, при необходимости доработать код. В конфигураторе создать обработку с единственной кнопкой КомандаВыполнить. Весь код, полученный преобразованием журнала, вставить в модуль ее формы ниже обработчика команды КомандаВыполнить. В сам обработчик КомандаВыполнить вставить только вызов первой из процедур (в нашем случае ТестовыйСценарий_10_08_2013()), см. рис. 4.21.13. Сеанс, в котором велась запись журнала и его преобразование, можно закрыть. Одна из созданных процедур организует поиск выбранного платежного поручения по совокупности показателей. Оставим из них только номер, остальные закомментируем, см. рис. 4.21.14. В принципе если бы речь шла об организации функционального тестирования в однопользовательском режиме, обработку можно бы было считать готовой и запускать. Нам, однако, надо показать, как работать с двумя клиентами, поэтому продолжим. Инструкции 251 Рис. 4.21.13. Вставка кода в обработку Рис. 4.21.14. Упрощение условий поиска Код обработки уже содержит подключение к тестируемому приложению (см. верхнюю половину рис. 4.21.15). Продублируем его, определив при этом новое тестируемое приложение переменной ТестовоеПриложение2, которое будет подключаться через TCP порт 1539 (порт должен быть открыт и не занят, например, порты 1540 и 1541 обычно используются кластером серверов «1С», и их сюда назначать нельзя). По умолчанию используется порт 1538. Через него будет подключаться первый клиент, через 1539 – второй. Действия, которые требуется выполнять второму тестовому приложению, создадим дублированием действий первого (см. рис. 4.21.16). 252 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.21.15. Определение второго тестируемого приложения Рис. 4.21.16. Дублирование вызовов процедур и самих процедур Инструкции 253 Выше мы для первого тестируемого приложения оставили поиск платежного поручения только по номеру (КП00-000004). Пусть второе приложение работает с другой платежкой (КП00-000003). Для этого изменим одну из ее процедур, как показано на рис. 4.21.17. Рис. 4.21.17. Для второго тестируемого приложения задан поиск платежки № КП00-000003. Обратите внимание: имя процедуры отличается от имени на аналогичном рисунке выше, имя параметра внутри процедуры – нет В следующую процедуру второго приложения также надо внести изменения, связанные с тем, что выбирается документ с другим номером (см. рис. 4.21.18). Кроме того, можно ввести другую сумму. Рис. 4.21.18. Для второго тестируемого приложения задан поиск платежки № КП00-000003. Это следует отразить и в других процедурах, связанных с ней Далее надо сохранить обработку и приготовиться к запуску клиентов. 254 4. Настольная книга 1С:Эксперта по технологическим вопросам Запустить один сеанс «1С» как менеджера тестирования, другой (другие) – как клиентов. Чтобы запустить сеанс «1С» как менеджера тестирования, надо запустить «1С» из командной строки с параметрами ENTERPRISE /IBName "<имя_базы>" /TestManager, например: C:\Program Files\1cv8\8.3.3.687\bin\1cv8c ENTERPRISE /IBName "scentest" /TestManager Или в конфигураторе в меню Сервис – Параметры – Запуск 1С:Предприятия – Дополнительные установить переключатель на позицию Запускать как менеджер тестирования, см. рис. 4.21.19 (порт для менеджера значения не имеет), нажать ОК и дальше запустить «1С» через отладчик (F5 или соответствующая кнопка меню) или без отладки (Ctrl + F5 или соответствующая кнопка меню). Менеджер тестирования поначалу лучше запускать через отладчик, для отладки управляющей обработки. Клиентов запускать через отладчик нет смысла, на них доступный для отладки код не выполняется. Рис. 4.21.19. Настройка параметров конфигуратора для запуска менеджера тестирования Инструкции 255 Далее нам надо запустить двух клиентов тестирования: одного с управлением через порт 1538, другого – 1539. Для этого надо запустить «1С» из командной строки с параметрами: ENTERPRISE /IBName "<имя_базы>" /TestClient /-TPort <номер_порта> В нашем случае это будут команды: C:\Program Files\1cv8\8.3.3.687\bin\1cv8c ENTERPRISE /IBName "scentest" /TestClient C:\Program Files\1cv8\8.3.3.687\bin\1cv8c ENTERPRISE /IBName "scentest" /TestClient /-TPort 1539 Порт по умолчанию 1538 указывать не обязательно. Или в конфигураторе в меню Сервис – Параметры – Запуск 1С:Предприятия – Дополнительные установить переключатель на позицию Запускать как менеджер тестирования (см. рис. 4.21.20) и указать порт. Сначала установить порт 1538 (см. рис. 4.21.20), нажать ОК и запустить одного клиента (Ctrl + F5 или соответствующая кнопка меню: Сервис – 1С:Предприятие). Рис. 4.21.20. Настройка параметров конфигуратора для запуска первого клиента тестирования Затем установить порт 1539 (см. рис. 4.21.21), нажать ОК и запустить другого клиента (Ctrl + F5 или соответствующая кнопка меню). Как отмечалось выше, запускать клиентов тестирования через отладчик (F5 или соответствующая кнопка меню) нет смысла. Рис. 4.21.21. Настройка параметров конфигуратора для запуска второго клиента тестирования 5. С менеджера тестирования запустить обработку на выполнение, убедиться, что на клиенте (клиентах) выполняются те действия, которые были записаны. Имеет смысл расположить все три окна (менеджер и два клиента) на экране, чтобы видеть их, открыть из менеджера созданную обработку и выполнить ее. 256 Настольная книга 1С:Эксперта по технологическим вопросам Убедиться, что окна в клиентах начали открываться и закрываться в соответствии с записанным скриптом. Если в ходе выполнения обработки возникли ошибки, их можно отлаживать. Для этого надо подключиться отладчиком к менеджеру или сразу запустить менеджер в режиме отладки. Классификация нагрузочных тестирований Подводя итоги, необходимо упомянуть еще о двух классификациях нагрузочных тестирований (выше они классифицировались по инструменту, с помощью которого тестирование организуется). По одной из них они могут быть: простейшими, ■■ реалистичными, ■■ полуреалистичными, со сжатием времени. Простейшие нагрузочные тестирования служат в основном для моделирования уже найденных проблем, которые можно организовать, запустив параллельную работу двух-четырех пользователей без пауз либо с паузами неопределенной длительности (остановом на отладчике). Методика таких тестов направлена на максимально простое воспроизведение проблемы, а не на моделирование ситуации в реальной базе. ■■ Реалистичные нагрузочные тесты обычно запускают, чтобы выявить проблемы, которые могут возникнуть в системе при работе полного числа пользователей. Паузы между документами при этом стараются организовывать похожими на реальные. Структуру документооборота – соответствующей действительности по наиболее ответственным участкам. Длительность реалистичного теста следует подбирать так, чтобы каждое повторяемое действие, даже самое редкое, выполнилось за тест хотя бы дважды, а неповторяемое – однократно. Реалистичные тесты дороги. Если речь идет о большом количестве пользователей, серьезной проблемой становится необходимость запускать большое количество клиентских сессий: для этого потребуется отдельное оборудование; ■■ возрастают расходы времени на ожидания запуска и выгрузки; ■■ сам запуск и выгрузка большого количества клиентов могут являться стрессовой нагрузкой на систему. Кроме того, запущенные сессии надо держать в работоспособном состоянии и обеспечивать их лицензиями. ■■ Полуреалистичные тесты обычно получаются, если взять методику реалистичного теста, уменьшить количество виртуальных пользователей по каждой роли и кратно этому уменьшению уменьшить и паузы между действиями (поэтому они и называются тестами со сжатием времени) либо убрать паузы вообще. При этом надо понимать, что совершенно не обязательно на первое место выйдут проблемы, присущие Инструкции 257 реальной системе. Но такие тесты дешевле реалистичных. Они быстрее выполняются, а целый класс проблем, возникающих из-за большого числа клиентов, для них неактуален. Поэтому их можно использовать, чтобы, во-первых, проверить, нет ли в системе легко выявляемых грубых ошибок, ради которых нет смысла проводить дорогой реалистичный тест, а во-вторых, окончательно отладить тестовые обработки. Однако полной заменой реалистичному тесту они служить не могут. Еще одна классификация нагрузочных тестов основывается на том, кто выполняет действия: виртуальные пользователи, ■■ живые люди. Второй случай всегда имеет место при вводе системы в эксплуатацию, опытную, а потом промышленную. Если до этого ввода в эксплуатацию нагрузочных тестов не проводилось, пользователи на себе ощутят то, что ощутили бы «роботы». Случается такое, понятно, нередко, и раз уж пошли на это, надо вести хотя бы мониторинг качества работы системы. Как это делать, см. раздел 5.6. ■■ Расследование падений платформы, ошибок блокировок и причин неудовлетворительной производительности, которые воспроизвелись при выполнении теста Надо понимать, что проведение нагрузочного теста – это способ воспроизвести ситуации, имеющие место в реальной базе или ожидаемые в проектируемой базе, но еще не способ от этих ситуаций избавиться. Поэтому при обнаружении падений платформы нужно получать дампы и отправлять их в «1С», при обнаружении ошибок блокировок расследовать их с помощью ЦУП, при обнаружении неудовлетворительной производительности действовать в соответствии с бизнес-процессом, изложенным в разделе 2.4. 4.22. Бизнес-процесс общей диагностики Бизнес-процесс работы с проблемами, изложенный во второй главе книги и подробно разобранный там в разделе 2.4, является правильным и обеспечивает правильный ход проекта и достижение его результатов. Поэтому при наличии возможности есть смысл вести работу именно в соответствии с ним. К сожалению, такой возможности может не быть, например, по какой-либо из перечисленных ниже причин: ■■ очень большая неопределенность при оценке сроков и стоимости работ: □□ заказчик не в состоянии поставить задачу иначе, чем «у нас все медленно работает, приезжайте сами и разберитесь», но хочет знать заранее, сколько это займет времени и сколько это будет стоить; □□ заказчик не дает никакой информации из соображений тайны до подписания договора и соглашения о конфиденциальности, но требует указать сроки и стоимость работ; 258 Настольная книга 1С:Эксперта по технологическим вопросам заведомо ограниченные сроки (единицы дней); ■■ заведомо маленький бюджет (например, могут быть оплачены максимум несколько человеко-дней работы, и совершенно точно не может быть речи о продаже КИП); ■■ отсутствие доступа в базу, работа только через специалистов заказчика или подрядчика. Ситуация не является безнадежной, за работу можно и нужно браться, и даже можно назначать за такую услугу фиксированную, а не почасовую оплату, если в процессе обсуждения установлено, что: ■■ высока вероятность стандартных ситуаций (соответственно, наличествует хорошее знание экспертом этих ситуаций, их диагностики и способов решения); ■■ есть согласие заказчика или подрядчика на то, что результатом работ являются рекомендации, что сделать. Далее по ним он сам будет вносить требуемые исправления; ■■ есть согласие заказчика или подрядчика на то, что после работ по диагностике, если стандартных ситуаций не выявлено, работа будет принята и может быть продолжена в «обычном» (описанном в разделе 2.4) формате, с дополнительным согласованием сроков и стоимости по результатам проведенной общей диагностики. Если обо всем удалось договориться, последовательность действий будет следующая: ■■ 1. Запросить информацию по списку вопросов для общего понимания ситуации (см. раздел 5.3). 2. Настроить сбор информации о загрузке оборудования (см. раздел 4.1), собрать данные за несколько дней, оценить, насколько справляется оборудование. 3. Настроить сбор технологического журнала, собрать данные за несколько дней, подсчитать общее количество ошибок блокировок и частоту появления повторяющихся контекстов (см. разделы 4.5 и 4.6). 4. Посмотреть в cf-файле наиболее часто повторяющиеся контексты ошибок блокировок, с работой какого механизма они связаны, и кто является автором данного механизма. 5. Принять решение, является ли ситуация стандартной, либо, имея собранную информацию, более точно формализовать задачу и оценить состав проблем, сроки и стоимость работ по решению имеющихся проблем. Также в разделе 2.4 говорилось, что методика общей диагностики может быть использована, если проверка обычных подозреваемых не дала результатов. Альтернативой выполнению работ по общей диагностике как отдельной платной услуги может быть: ■■ ■■ бесплатное проведение этих работ на входе в проект; работы по аудиту системы в течение 1–2 часов, максимум одного неполного дня, обычно до первой найденной стандартной ситуации, которая объявляется виновником всех бед. Инструкции 259 Распространенность этих подходов такова, что именно они у внедренцев и у заказчиков считаются нормой. Это довольно сильно мешает развитию рынка недорогих услуг по диагностике: бесплатно или за минимальные часы эту работу невозможно выполнить с должным качеством, а полноформатные работы, обеспечивающие гарантию результата, включают не только диагностику, но и «лечение», и потому стоят дорого. В то же время в других отраслях – платной медицине, малом строительстве и ремонте – обследования и замеры отделены от основного цикла работ. Показательный пример: в стоматологии есть сети лабораторий, специализирующихся только на диагностике. И если стоимость диагностики, обследований и замеров входит в стоимость лечения или работ, это всегда специально указывается. 4.23. Работа в конфигураторе. Редактирование параметра времени ожидания блокировки Время ожидания на блокировке, после истечения которого наступает таймаут (это относится и к таймаутам СУБД, и к таймаутам «1С»), может быть изменено в конфигураторе с помощью формы, вызываемой через меню Администрирование – Параметры информационной базы (см. рис. 4.23.1). Рис. 4.23.1. Изменение параметра, отвечающего за максимальную длительность ожидания на блокировке Увеличение этого времени позволяет уменьшить количество таймаутов в системе, но эффект от этого есть только в том случае, если их там и так единицы. Оно не устраняет причин возникновения таймаутов, а лишь маскирует сами таймауты. Если в информационной системе есть взаимоблокировки, редактирование этого параметра бесполезно. В подавляющем большинстве случаев изменять этот параметр не надо, следует использовать значение по умолчанию, равное двадцати секундам. 260 Настольная книга 1С:Эксперта по технологическим вопросам 4.24. Работа с ТЖ. Как посмотреть, какие управляемые блокировки были установлены Увидеть, какие управляемые блокировки были установлены, можно в технологическом журнале сервера «1С». Для этого файл logcfg.xml нужно настроить следующим образом (см. рис. 4.24.1): <?xml version="1.0" encoding="UTF-8"?> <config xmlns="http://v8.1c.ru/v8/tech-log"> <dump create="true" location="C:\DUMPS" type="0" prntscrn="false"/> <log location="C:\LOGS\TLOCK" history="48"> <event> <eq property="Name" value="TLOCK"/> </event> <property name="all"/> </log> </config> Рис. 4.24.1. Настройка технологического журнала для получения информации об установленных управляемых блокировках Обратите внимание, что такая настройка в обязательном порядке требует контроля наличия места на диске, куда пишется журнал. Кроме того, есть рекомендация собирать дампы и журналы в две разные директории. Информация об установленных управляемых блокировках, однако, обычно нужна не сама по себе, а для расследования конфликтов управляемых блокировок. Чтобы получить информацию также о конфликтах, надо настроить logcfg.xml так, как на рис. 4.24.2: <?xml version="1.0" encoding="UTF-8"?> <config xmlns="http://v8.1c.ru/v8/tech-log"> <dump create="true" location="C:\DUMPS" type="0" prntscrn="false"/> <log location="C:\LOGS\TLOCK" history="48"> <event> <eq property="Name" value="TLOCK"/> </event> <event> <eq property="Name" value="TTIMEOUT"/> </event> <event> <eq property="Name" value="TDEADLOCK"/> </event> <property name="all"/> </log> </config> Рис. 4.24.2. Настройка технологического журнала для получения информации об установленных управляемых блокировках и их конфликтах Инструкции 261 4.25. Работа с ТЖ. Как расследовать конфликт на управляемых блокировках Расследование бесконфликтной ситуации Чтобы собрать сведения об установленных управляемых блокировках и их конфликтах, нужно собрать технологический журнал с событиями TLOCK, TTIMEOUT и TDEADLOCK. Как это сделать, описано в разделе 4.24 «Работа с ТЖ. Как посмотреть, какие управляемые блокировки были установлены». В простых случаях для работы вам потребуется простой текстовый редактор. В более сложных, например, когда у вас много рабочих процессов и/или блокировка ресурса происходит вне пределов одного часа, вам потребуется или написать парсер, или использовать файловый менеджер, позволяющий производить поиск кириллического текста одновременно в нескольких текстовых файлах (FAR Маnager, Total Commander и т. п.). Возьмем ошибочный пример из первого издания книги, вызвавший много нареканий (рассмотрен в разделе 3.8)79.65 Имеются два фрагмента кода (толстый клиент, обычное приложение, 8.2.18.102, «Бухгалтерия предприятия», ред. 2.0, конфигурация в управляемом режиме управления блокировками). Фрагмент 1: НачатьТранзакцию(); Блокировка = Новый БлокировкаДанных; ЭлементБлокировки = Блокировка.Добавить("РегистрБухгалтерии.Хозрасчетный"); ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; Блокировка.Заблокировать(); Фрагмент 2: НачатьТранзакцию(); НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей(); НаборЗаписей.Отбор.Регистратор.Установить(ДокументСсылка); НаборЗаписей.Прочитать(); Если поставить останов сразу после любого фрагмента и попытаться выполнить соседний, конфликта блокировок не возникнет. В технологическом журнале появятся две записи (важные поля выделены полужирным шрифтом): 01:51.4861-3,TLOCK,4,process=rphost,p:processName=buh20,t:clientID=32,t:applicationName=1CV8,t:computerName =ZENYA,t:connectID=8,SessionID=9,Usr=DefUser,Regions=AccRg7916.DIMS,Locks=AccRg7916.DIMS Exclusive,WaitConnections= 01:51.4865-0,Context,3,process=rphost,p:processName=buh20,t:clientID=32,t:applicationName=1CV8, t:computerName=ZENYA,t:connectID=8,SessionID=9,Usr=DefUser,Context=' {Форма.Форма1}/{КоманднаяПанель : ОсновныеДействияФормы}/{Кнопка1Выполнить} Форма.Форма1.Форма : 9 : Блокировка.Заблокировать();' 01:59.9570-3,TLOCK,4,process=rphost,p:processName=buh20,t:clientID=22,t:applicationName=1CV8,t:computerName= ZENYA,t:connectID=4,SessionID=4,Usr=DefUser,Regions=AccRg7916.RECORDER,Locks='AccRg7916 .RECORDER Shared Rec order=181:bbd70013d4b2c44611e02bd53593ce4d',WaitConnections= 79 Еще раз извинения читателям от автора. 262 Настольная книга 1С:Эксперта по технологическим вопросам 01:59.9574-0,Context,3,process=rphost,p:processName=buh20,t:clientID=22,t:applicationName=1CV8,t:computerName =ZENYA,t:connectID=4,SessionID=4,Usr=DefUser,Context=' {Форма.Форма1}/{КоманднаяПанель : ОсновныеДействияФормы}/{Кнопка2Выполнить} Форма.Форма1.Форма : 24 : НаборЗаписей.Прочитать();' Конфликта блокировок не возникнет, поскольку DIMS и RECORDER (AccRg7916. DIMS и 'AccRg7916.RECORDER) – «измерения» и «регистратор» – это разные пространства блокировок, они не конфликтуют. Расследование превышения максимального времени ожидания на блокировках «1С» Если вместо регистра накопления взять непериодический независимый регистр сведений, у него в свойствах набора записей не будет отбора по регистратору, но будет отбор по измерению. Фрагмент 1: НачатьТранзакцию(); НаборЗаписей = РегистрыСведений.СчетчикВыгрузокПФР.СоздатьНаборЗаписей(); НаборЗаписей.Отбор.Год.Установить(2013); НаборЗаписей.Прочитать(); Фрагмент 2: НачатьТранзакцию(); Блокировка = Новый БлокировкаДанных; ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.СчетчикВыгрузокПФР"); ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; Блокировка.Заблокировать(); Если поставить останов сразу после любого фрагмента (поставим после первого) и попытаться выполнить соседний, произойдет конфликт блокировок. В технологическом журнале появятся записи: 29:03.8024-3,TLOCK,4,process=rphost,p:processName=buh20,t:clientID=13,t:applicationName =1CV8,t:computerName=ZENYA,t:connectID=2,SessionID=2,Usr=DefUser,Regions=InfoRg7031.DIMS,Locks ='InfoRg7031.DIMS Shared Fld7033=2013',WaitConnections= 29:03.8182-0,Context,3,process=rphost,p:processName=buh20,t:clientID=13,t:applicationName =1CV8,t:computerName=ZENYA,t:connectID=2,SessionID=2,Usr=DefUser,Context=' {Форма.Форма1}/{КоманднаяПанель : ОсновныеДействияФормы}/{Кнопка2Выполнить} Форма.Форма1.Форма : 22 : НаборЗаписей.Прочитать();' 29:31.9450-0,TTIMEOUT,5,process=rphost,p:processName=buh20,t:clientID=23,t:applicationName =1CV8,t:computerName=ZENYA,t:connectID=6,SessionID=7,Usr=DefUser,WaitConnections=2 29:31.9452-200471,TLOCK,4,process=rphost,p:processName=buh20,t:clientID=23,t:applicationName =1CV8,t:computerName=ZENYA,t:connectID=6,SessionID=7,Usr=DefUser,Regions=InfoRg7031.DIMS,Locks =InfoRg7031.DIMS Exclusive,WaitConnections=2 29:31.9458-0,Context,3,process=rphost,p:processName=buh20,t:clientID=23,t:applicationName=1CV8,t:computerName =ZENYA,t:connectID=6,SessionID=7,Usr=DefUser,Context=' {Форма.Форма1}/{КоманднаяПанель : ОсновныеДействияФормы}/{Кнопка1Выполнить} Форма.Форма1.Форма : 9 : Блокировка.Заблокировать();' Из этого примера видно, что если воспроизвести его самостоятельно, по нему можно разобраться, как работать с логами управляемых блокировок (а фактически журнал, Инструкции 263 настроенный на сбор событий TLOCK, TTIMEOUT и TDEADLOCK, и является логом управляемых блокировок). В частности, сразу видно следующее: 1. Разделяемая блокировка не снимается сразу после выполнения метода Прочитать (в реальности она держится до конца транзакции). 2. Обратите внимание на число 200471 в информации о событии TLOCK, связанном с TTIMEOUT. Это время ожидания в сотнях микросекунд (если дописать два нуля справа и отбить разряды, получится «20 047 100»). По нему можно посчитать, какие на самом деле происходят потери на ожидания на управляемых блокировках в системе, даже без использования ЦУП. 3. В информации о событии TTIMEOUT в явном виде указано, кто кого ждет (соединение с t:connectID=6 ждет (WaitConnections=2) соединение с t:connectID=2). 4. В простых случаях, чтобы найти виновника конфликта блокировок, достаточно найти, какую именно управляемую блокировку, не совместимую с блокировкой-жертвой, установило соединение, указанное в WaitConnections. При этом даже в простых случаях она может находиться не в этом же файле. Она может быть в логах другого часа, другого рабочего процесса и даже, если в кластере несколько серверов, – в логах другого сервера. Именно для этого нужен файловый менеджер, позволяющий производить поиск кириллического текста одновременно в нескольких текстовых файлах. Расследование неустранимого конфликта на управляемых блокировках Выполним с двух клиентских приложений следующий код: НачатьТранзакцию(); Блокировка = Новый БлокировкаДанных; НаборЗаписей = РегистрыСведений.СчетчикВыгрузокПФР.СоздатьНаборЗаписей(); НаборЗаписей.Отбор.Год.Установить(2013); НаборЗаписей.Прочитать(); Предупреждение("этап1"); ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.СчетчикВыгрузокПФР"); ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; Блокировка.Заблокировать(); Вначале дойдем в обоих приложениях до предупреждения, а затем одновременно попробуем продвинуться дальше. Возникнет неразрешимый конфликт на управляемых блокировках. В технологическом журнале до модального окна увидим следующее: 46:33.4463-3,TLOCK,4,process=rphost,p:processName=buh20,t:clientID=54,t:applicationName= 1CV8,t:computerName=ZENYA,t:connectID=7,SessionID=8,Usr=DefUser,Regions=InfoRg7031.DIMS,Locks= 'InfoRg7031.DIMS Shared Fld7033=2013',WaitConnections= 46:33.4621-0,Context,3,process=rphost,p:processName=buh20,t:clientID=54,t:applicationName=1CV8,t:computerName= ZENYA,t:connectID=7,SessionID=8,Usr=DefUser,Context=' {Форма.Форма1}/{КоманднаяПанель : ОсновныеДействияФормы}/{Кнопка1Выполнить} Форма.Форма1.Форма : 8 : НаборЗаписей.Прочитать();' 46:39.6554-3,TLOCK,4,process=rphost,p:processName=buh20,t:clientID=23,t:applicationName= 1CV8,t:computerName=ZENYA,t:connectID=6,SessionID=7,Usr=DefUser,Regions=InfoRg7031.DIMS,Locks= 'InfoRg7031.DIMS Shared Fld7033=2013',WaitConnections= 264 Настольная книга 1С:Эксперта по технологическим вопросам 46:39.6558-0,Context,3,process=rphost,p:processName=buh20,t:clientID=23,t:applicationName=1CV8,t:computerName= ZENYA,t:connectID=6,SessionID=7,Usr=DefUser,Context=' {Форма.Форма1}/{КоманднаяПанель : ОсновныеДействияФормы}/{Кнопка1Выполнить} Форма.Форма1.Форма : 8 : НаборЗаписей.Прочитать();' Но далее: 46:50.4951-0,TDEADLOCK,5,process=rphost,p:processName=buh20,t:clientID=54,t:applicationName=1CV8,t:computerName =ZENYA,t:connectID=7,SessionID=8,Usr=DefUser,DeadlockConnectionIntersections ='7 6 InfoRg7031.DIMS Exclusive Fld7033=2013,6 7 InfoRg7031.DIMS Exclusive Fld7033=2013' 46:50.4953-471,TLOCK,4,process=rphost,p:processName=buh20,t:clientID=54,t:applicationName =1CV8,t:computerName=ZENYA,t:connectID=7,SessionID=8,Usr=DefUser,Regions=InfoRg7031.DIMS,Locks =InfoRg7031.DIMS Exclusive,WaitConnections=6 46:50.5571-0,Context,3,process=rphost,p:processName=buh20,t:clientID=54,t:applicationName=1CV8,t:computerName =ZENYA,t:connectID=7,SessionID=8,Usr=DefUser,Context=' {Форма.Форма1} Форма.Форма1.Форма : 15 : Блокировка.Заблокировать();' 46:50.7139-34458,TLOCK,4,process=rphost,p:processName=buh20,t:clientID=23,t:applicationName =1CV8,t:computerName=ZENYA,t:connectID=6,SessionID=7,Usr=DefUser,Regions=InfoRg7031.DIMS,Locks =InfoRg7031.DIMS Exclusive,WaitConnections=7 46:50.7146-0,Context,3,process=rphost,p:processName=buh20,t:clientID=23,t:applicationName =1CV8,t:computerName=ZENYA,t:connectID=6,SessionID=7,Usr=DefUser,Context=' {Форма.Форма1} Форма.Форма1.Форма : 15 : Блокировка.Заблокировать();' В информации о событии TDEADLOCK в явном виде указано, кто кого ждет (DeadlockConnectionIntersections='7 6). Это же видно в следующих за ним записях с информацией о событиях TLOCK: t:connectID=7 InfoRg7031.DIMS Exclusive WaitConnections=6 и t:connectID=6 InfoRg7031.DIMS Exclusive WaitConnections=7. В простых случаях, чтобы найти виновника конфликта блокировок, достаточно найти, какую именно управляемую блокировку, не совместимую с блокировкой-жертвой, установило соединение, указанное в WaitConnections. При этом, как говорилось выше, нужно иметь под рукой средства автоматизации поиска. Ранее на это же пространство InfoRg7031.DIMS были наложены разделяемые блокировки: t:connectID=6 'InfoRg7031.DIMS Shared и t:connectID=7 'InfoRg7031.DIMS Shared Из этого становится понятно, что речь идет о повышении уровня блокировки. Способ обхода – ставить исключительную блокировку до установки разделяемой блокировки, которая ставится неявно в НаборЗаписей.Прочитать(). Дальше в этом же месте есть опасность получить продолжение в виде следующего неустранимого конфликта блокировок, который может возникнуть из-за варианта захвата ресурсов Инструкции 265 в разном порядке, когда вначале блокируется измерение, а потом целиком регистр. Чтобы этого избежать, в данном случае блокировать надо сразу максимальную область из имеющихся. 4.26. Измерение динамики производительности по журналу регистрации Случаются ситуации, когда встроить в конфигурацию код замеров времени выполнения ключевых операций в силу каких-то организационных или иных причин невозможно. Также бывает, что заказчики обратились уже после имевшей место деградации производительности. В следующий раз она воспроизведется только в следующий отчетный период, счетчики встроены не были, а понять картину надо уже сейчас. Во многих практических случаях картину можно попробовать собрать по журналу регистрации. Табл. 4.26.1. Фрагмент журнала регистрации Дата, время 08.12.2014 15:10:04 08.12.2014 15:10:08 08.12.2014 15:10:31 Пользователь Компьютер Событие Комментарий Данные. Проведение SRV-PRL-EXP-01 Толстый 56 клиент Данные. Проведение SRV-PRL-EXP-01 Толстый 56 клиент Данные. Проведение SRV-PRL-EXP-01 Толстый 56 клиент Статус транзакции Транзакция Зафиксирована Метаданные Данные Документ. Расходный кассовый ордер 08.12.2014 15:10:01 (54282) Расходный кассовый ордер 00000000074 от 20.08.2013 0:00:00 Зафиксирована Документ. Расходный кассовый ордер 08.12.2014 15:10:07 (55090) Расходный кассовый ордер 00000000069 от 31.07.2013 0:00:00 Зафиксирована Документ. Расходный кассовый ордер 08.12.2014 15:10:17 (55898) Расходный кассовый ордер 00000000074 от 20.08.2013 0:00:00 В табл. 4.26.1 приведен фрагмент журнала регистрации с отбором только по событию «Данные. Проведение». Видно, что в столбце «Транзакция» отображается идентификатор транзакции и время ее начала, а в столбце «Дата, время» – время события (в данном случае время фиксации транзакции). Если из одного вычесть другое, мы получим статистику о длительности транзакционной части проведения документов. Хотя, конечно, транзакционная часть – это не вся длительность проведения, но в общем-то можно разобраться, чего именно мы здесь не видим. Внетранзакционной частью, скорее всего, можно пренебречь, если с высокой степенью достоверности установлено, что: ■■ длительность транзакции по журналу регистрации примерно равна длительности операции по секундомеру; 266 Настольная книга 1С:Эксперта по технологическим вопросам вне транзакции нет других неявных транзакций, не попадающих в журнал регистрации, но фиксируемых профайлером. Кроме того, в подавляющем большинстве случаев проблемы параллельности возникают именно в транзакциях, то есть может быть важна динамика именно длительности транзакций. ■■ 4.27. Про открытие модальных окон в транзакции Модальным называется окно, которое блокирует работу пользователя с родительским приложением до тех пор, пока пользователь это окно не закроет. Открытие модальных окон в транзакции – это почти всегда грубая ошибка. Исключением является, пожалуй, лишь случай, когда окно открывается намеренно для целей гарантированного воспроизведения ошибок (конфликтов блокировок). Если требуется использовать модальные окна для привлечения внимания пользователя к важному событию или критической ситуации, это все равно не повод открывать их в транзакции. Модальные формы открываются методами: ■■ <Форма>.ОткрытьМодально(), ■■ <Таблица или дерево значений>. ВыбратьСтроку(). Процедурами и функциями глобального контекста: ■■ Вопрос(), ■■ Предупреждение(), ■■ ОткрытьФормуМодально() и т. п. Разберем еще один пример ошибочного кода, который иллюстрирует, как работает механизм транзакций и как можно на ровном месте создать серьезные проблемы. В режиме обычного приложения создадим обработку, с помощью которой выполним следующий код: НачатьТранзакцию(); Форма = Документы.РасходныйКассовыйОрдер.ПолучитьФормуСписка().ОткрытьМодально(); В открывшейся форме списка последовательно откроем несколько документов РасходныйКассовыйОрдер, изменим им даты, перепроводя каждый из документов, пока не обратим внимания, что даты у документов в списке меняются только после нажатия кнопки Обновить (в конце концов мы могли бы менять и не отображаемые в форме списка реквизиты). Затем закроем модальную форму списка, а открыв ее еще раз, увидим, что даты вернулись в исходное состояние. Откроем журнал регистрации (см. табл. 4.27.1). Инструкции 267 Табл. 4.27.1. Фрагмент журнала регистрации Дата, время Пользователь Компьютер 28.11.2014 12:29:44 Событие Комментарий Данные. Изменение SRV-PRL-EXP-01 Толстый клиент Данные. Проведение SRV-PRL-EXP-01 Толстый 2 клиент 28.11.2014 12:29:50 SRV-PRL-EXP-01 Данные. Проведение SRV-PRL-EXP-01 Толстый клиент Данные Документ. Расходный кассовый ордер Отменена ордер 00000000071 от 20.08.2013 0:00:00 Документ. Расходный кассовый ордер Отменена ордер 00000000071 от 20.08.2013 0:00:00 Документ. Расходный кассовый ордер 28.11.2014 12:29:39 (10473) Расходный кассовый 2 28.11.2014 12:29:50 Транзакция Отменена 28.11.2014 12:29:39 (10473) Расходный кассовый Данные. Изменение Толстый клиент Метаданные 28.11.2014 12:29:39 (10473) Расходный кассовый 2 28.11.2014 12:29:44 Статус транзакции 2 Отменена ордер 00000000075 от 30.08.2013 0:00:00 Документ. Расходный кассовый ордер 28.11.2014 12:29:39 (10473) Расходный кассовый ордер 00000000075 от 30.08.2013 0:00:00 Видим, что все происходило в одной транзакции (колонка Транзакция), несмотря на то, что номера кассовых ордеров разные и время фиксации события разное. Последствия оказались весьма серьезные: все внесенные изменения откатились, хотя пользователь не рассчитывает на подобное поведение системы; ■■ ресурсы продолжают оставаться блокированными неопределенное время, несколько часов, пока не будет закрыта исходная модальная форма списка; ■■ каждый следующий документ добавляет новые заблокированные ресурсы к уже заблокированным. Код может быть вызван из внешней обработки, т. е. в случае с рабочей базой написать и вызвать такое может кто угодно и откуда угодно. Как можно попробовать поймать такой код, см. раздел 4.28 «Ловушка для получения стека вызовов». ■■ Конечно, скорее всего, в родительской обработке предполагался следующий код: НачатьТранзакцию(); Форма = Документы.РасходныйКассовыйОрдер.ПолучитьФормуСписка().ОткрытьМодально(); ЗафиксироватьТранзакцию(); И внесенные изменения сохранятся (см. табл. 4.27.2). 268 Настольная книга 1С:Эксперта по технологическим вопросам Табл. 4.27.2. Фрагмент 2 журнала регистрации Дата, время 28.11.2014 12:43:59 Пользователь Компьютер Событие Комментарий Данные. Изменение SRV-PRL-EXP-01 Данные. Проведение SRV-PRL-EXP-01 Данные. Изменение SRV-PRL-EXP-01 Данные. Проведение SRV-PRL-EXP-01 Толстый 5 клиент Зафиксирована 28.11.2014 12:42:48 (16755) Толстый 5 клиент 28.11.2014 12:44:07 Зафиксирована 28.11.2014 12:42:48 (16755) Толстый 5 клиент 28.11.2014 12:44:07 Зафиксирована 28.11.2014 12:42:48 (16755) Толстый 5 клиент 28.11.2014 12:43:59 Статус транзакции Транзакция Зафиксирована 28.11.2014 12:42:48 (16755) Метаданные Данные Документ. Расходный кассовый ордер Расходный кассовый ордер 00000000002 от 22.08.2014 0:00:00 Документ. Расходный кассовый ордер Расходный кассовый ордер 00000000002 от 22.08.2014 0:00:00 Документ. Расходный кассовый ордер Расходный кассовый ордер 00000000003 от 25.08.2014 0:00:00 Документ. Расходный кассовый ордер Расходный кассовый ордер 00000000003 от 25.08.2014 0:00:00 Однако если при проведении любого из документов возникнет исключительная ситуация, которая будет признана невосстановимой (т. е. после нее нельзя продолжать транзакцию), как говорилось в разделе 3.6, при следующем обращении к данным вся транзакция будет отменена с сообщением «В данной транзакции уже происходили ошибки!». То есть все введенные и измененные в ней документы вернутся в исходное состояние. И, кроме того, это не отменяет факта блокировки ресурсов на неопределенное время. 4.28. Ловушка для получения стека вызовов, когда отладка недоступна Связать между собой вызовы методов НачатьТранзакцию() и Форма.ОткрытьМодально() непосредственно путем анализа кода конфигурации получается далеко не всегда: это может быть как очень трудоемко, так и вовсе невозможно, если, например, код вызывается из внешней обработки. Ловить такие связки, однако, нужно, т. к. их последствия могут быть очень серьезными (см. раздел 4.27). Чтобы поймать ее для случая из раздела 4.27, когда в транзакции модально открывалась форма списка, из которой шла интерактивная работа с документами, обратим внимание на то, что вообще-то открытие формы документа не должно выполняться в транзакции. То есть наличие активной транзакции Инструкции 269 в процедуре ПриОткрытии() формы документа может являться маркером неправильного поведения. Процедура ПриОткрытии() Если ТранзакцияАктивна() тогда // каким-то образом вытащить стек вызовов в доступное место КонецЕсли; ... Удобным способом получить стек вызовов является вывод в технологический журнал сервера «1С:Предприятия». Однако, поскольку процедура ПриОткрытии() выполняется на клиенте, далеко не любое событие (в т. ч. исключение) окажется именно в серверном журнале, а не в клиентском. Подходящим является событие SDBL. Ниже приводится пример решения задачи. Настроим logcfg.xml: <?xml version="1.0"?> <config xml="http://v8.1c.ru/v8/tech-log"> <log history="24" location="D:\LOGS1c"> <event> <eq property="Name" value="SDBL"/> <like property="Sdbl" value="%АктивнаяТранзакцииВПриОткрытии%"/> </event> <property name="all"/> </log> </config> На месте АктивнаяТранзакцииВПриОткрытии может быть любая уникальная последовательность символов, которую можно использовать в качестве фильтра. Если все настроено правильно, в технологическом журнале не будет других событий. В процедуре ПриОткрытии() формы документов, отметившихся в журнале регистрации, включаем код: Процедура ПриОткрытии() ... Если ТранзакцияАктивна() тогда ЗапросЛовушкаОшибкиДляАктивнойТранзакции = Новый Запрос; ЗапросЛовушкаОшибкиДляАктивнойТранзакции.Текст = "ВЫБРАТЬ | ""АктивнаяТранзакцииВПриОткрытии"" КАК Поле1"; Результат = ЗапросЛовушкаОшибкиДляАктивнойТранзакции.Выполнить(); КонецЕсли; Если выполнение действий требуется пресекать, можно вызывать исключение. Чтобы вывести значения переменных или другую информацию о происходящем, например ЭтоНовый(), нужно использовать параметры запроса: Процедура ПриОткрытии() Если ТранзакцияАктивна() тогда ЗапросЛовушкаОшибкиДляАктивнойТранзакции = Новый Запрос; ЗапросЛовушкаОшибкиДляАктивнойТранзакции.Текст = "ВЫБРАТЬ | ""АктивнаяТранзакцииВПриОткрытии"" КАК Поле1, | &Параметр1 КАК Поле2"; ЗапросЛовушкаОшибкиДляАктивнойТранзакции. | УстановитьПараметр("Параметр1", ЭтоНовый()); Результат = ЗапросЛовушкаОшибкиДляАктивнойТранзакции.Выполнить(); 270 Настольная книга 1С:Эксперта по технологическим вопросам ВызватьИсключение "АктивнаяТранзакцииВПриОткрытии"; // это по желанию. Можно вызывать, чтобы не давать выполняться. КонецЕсли; Если ловушка срабатывает, в серверном технологическом журнале виден стек вызовов, а также текст запроса с фактическими значениями параметров (в нашем случае ЭтоНовый() = FALSE): 47:21.9647-3,SDBL,4,process=rphost,p:processName=bp20,t:clientID=110198,t:applicationName =1CV8,t:computerName=SRV-PRL-EXP-01,t:connectID=93632,SessionID=45,Usr=DefUser,Trans=1,Sdbl='SELECT "АктивнаяТранзакцииВПриОткрытии", FALSE ',Rows=1 47:21.9651-0,Context,3,process=rphost,p:processName=bp20,t:clientID=110198,t:applicationName =1CV8,t:computerName=SRV-PRL-EXP-01,t:connectID=93632,SessionID=45,Usr=DefUser,Context=' {Документ.РасходныйКассовыйОрдер.Форма.ФормаСписка} Форма.Форма1.Форма : 5 : Форма = Документы.РасходныйКассовыйОрдер.ПолучитьФормуСписка().ОткрытьМодально(); Документ.РасходныйКассовыйОрдер.Форма.ФормаДокумента.Форма : 612 : Результат = ЗапросЛовушкаОшибкиДляАктивнойТранзакции.Выполнить();' Описанный выше способ получения стеков вызовов и значений переменных годится и в других ситуациях, когда проблема воспроизводится эпизодически и/или отладка недоступна. Например, его можно применять для поиска ошибок: ■■ ■■ ■■ в фоновых заданиях; в коде, который хранится где-то еще (скажем, в справочнике) и выполняется через Выполнить(); при расследовании проблем на продуктивных системах с выключенной отладкой, но с имеющейся возможностью вносить изменения в конфигурацию. 4.29. Как собрать отказоустойчивый кластер 8.3 из двух серверов 1. Остановить кластеры «1С» на обоих серверах. 2. Удалить каталоги srvinfo80 на обоих серверах.66 Например, путь, по которому они могут лежать, может выглядеть так81:67 C:\Program Files\1cv82\srvinfo\ C:\Program Files (x86)\1cv8\srvinfo 3. 4. 5. 80 81 Запустить на каждом сервере кластеры «1С». Запустить консоль администрирования кластера только на первом сервере (в нашем случае ZENYA), см. рис. 4.29.1. С этой консоли подключиться ко второму серверу (в нашем случае Z3060015) через 1С:Enterprise 8.3 Central Servers – Создать – Центральный сервер 1С:Предприятия 8.3 (см. рис. 4.29.2). Чревато потерей журнала регистрации и списка зарегистрированных баз. Определяется параметром -d в настройках службы агента сервера. Эту настройку иногда меняют, чтобы не хранить журналы регистрации на системном диске. Инструкции 271 Рис. 4.29.1. Окно консоли администрирования, запущенное на первом сервере Рис. 4.29.2. Если второй сервер запущен с параметрами по умолчанию, то и подключаться к нему надо с параметрами по умолчанию Удалить на нем локальный кластер «1С» (через Удалить в контекстном меню на узле Локальный кластер второго сервера), см. рис. 4.29.3. Рис. 4.29.3. Что именно удалять 272 6. Настольная книга 1С:Эксперта по технологическим вопросам С этой же консоли подключиться к первому серверу консолью и добавить второй сервер в кластер (Рабочие серверы – Создать – Рабочий сервер), см. рис. 4.29.4. Заполнить имена, нажать ОК. Рис. 4.29.4. Окно ввода нового рабочего сервера 7. Войти в свойства созданного второго сервера (в нашем случае Z3060015), сделать второй сервер тоже центральным (флажок Центральный сервер будет уже доступным), см. рис. 4.29.5. 8. Изменить в свойствах локального кластера уровень отказоустойчивости с 0 на 1 (см. рис. 4.29.6). 9. Добавить информационную базу и подключиться к информационной базе в режиме 1С:Предприятие. 10. Подключиться к информационной базе в режиме Конфигуратор. 11. Обратите внимание: в инструкции нет ни слова про то, что надо переназначать порты, т. е. на обоих серверах все настроено на порты по умолчанию (1540, 1541, 1560:1591). Инструкции 273 Рис. 4.29.5. Окно свойств рабочего сервера похоже на предыдущее, но доступные поля – другие Рис. 4.29.6. Окно свойств локального кластера 274 Настольная книга 1С:Эксперта по технологическим вопросам 4.30. Как оставить сервис лицензирования только на одном сервере кластера 8.3 1. Открыть консоль администрирования кластера с любого из серверов, развернуть ветку Рабочие серверы до конца (см. рис. 4.30.1). Рис. 4.30.1. Необходимо установить требования назначения функциональности у обоих рабочих серверов 2. У сервера, который будет источником лицензирования, добавить: Требо- вания назначения функциональности – Создать – Требование назначения функциональности, с объектом требования Сервис лицензирования и типом требования Назначать (см. рис. 4.30.2). Рис. 4.30.2. Требование назначений функциональности для сервера – источника лицензий Инструкции 3. 275 У сервера, который НЕ будет источником лицензирования, добавить: Требования назначения функциональности – Создать – Требование назначения функциональности, с объектом требования Сервис лицензирования и типом требования Не назначать (см. рис. 4.30.3). Рис. 4.30.3. Требование назначений функциональности для сервера, не являющегося источником лицензий Обращаем внимание, что в таком случае работоспособность кластера, даже если он собран как отказоустойчивый, определяется работоспособностью сервера, на котором оставлен сервис лицензирования. В некоторых случаях имеет смысл отводить под сервер с сервисом лицензирования недорогой компьютер, не используемый под другие задачи (в т. ч. под рабочие процессы кластера), а также, при использовании программных лицензий, не имеющий динамически меняющихся параметров оборудования. Чтобы запретить запускать на нем рабочие процессы, можно установить равными 0 параметры Количество ИБ на процесс или Количество соединений на процесс в свойствах данного рабочего сервера. 4.31. Как собрать отказоустойчивый кластер 8.2 из двух серверов Если коротко, инструкция выглядит так: ■■ имеем два сервера: SERVER1 и SERVER2: □□ на обе машины устанавливаем сервер «1С»; □□ создаем на каждом сервере по кластеру «1С» (стандартный кластер, рабочий сервер пока 1 – тот, который держит кластер); □□ добавляем рабочие процессы и пр. (настройки идентичны на обоих серверах); □□ на SERVER1 добавляем информационную базу; □□ в список резервирования SERVER1 добавляем SERVER2 (должен быть вторым в списке); 276 Настольная книга 1С:Эксперта по технологическим вопросам □□ в список резервирования SERVER2 добавляем SERVER1 (должен быть первым в списке); □□ ждем, пока синхронизируется список ИБ и сеансов (около 1 минуты); ■■ отказоустойчивость настроена. Пример Есть сервер V81CORA, на котором установлен сервер «1С:Предприятия» и зарегистрированы две информационные базы: test и test1. Есть сервер Z3060015, который необходимо использовать для создания отказоустойчивого кластера «1С» из двух серверов: V81CORA и Z3060015. Это наиболее простой случай создания и использования отказоустойчивого кластера «1С». Решение 1. Имеем один сервер V81CORA с единственным рабочим процессом. Все установки – по умолчанию (1540, 1541). На нем зарегистрированы две базы (см. рис. 4.31.1). Рис. 4.31.1. Начальное состояние кластера на V81CORA 2. На втором сервере (Z3060015) установить и запустить сервер «1С:Предприятия» с единственным рабочим процессом. На нем нет зарегистрированных информационных баз. Все установки – по умолчанию (1540, 1541). Инструкции 277 Рис. 4.31.2. Начальное состояние кластера на Z3060015 Свойства рабочего процесса Z3060015 1 показаны на рис. 4.31.3. Обратите внимание: в поле Использование стоит Использовать, а не Использовать как резервный. Такая же настройка должна быть и у рабочего процесса на V81CORA. Рис. 4.31.3. Свойства рабочего процесса Z3060015 1 278 Настольная книга 1С:Эксперта по технологическим вопросам 3. Открыть в консоли администрирования оба сервера V81CORA и Z3060015, чтобы было удобнее работать (см. рис. 4.31.4, левая часть). 4. В ветку Резервирование кластеров сервера V81CORA, на котором зарегистрированы базы, добавить резервный кластер с именем второго сервера (порт по умолчанию 1541), см. рис. 4.31.4, правая часть. Рис. 4.31.4. Кластер V81CORA до добавления резервирования (слева) и после (справа) 5. В ветку Резервирование кластеров второго сервера Z3060015 добавить резервный кластер с именем первого сервера V81CORA (порт по умолчанию 1541) и, ЭТО ВАЖНО, переместить его на первое место (доступно по контекстному меню – Переместить вверх) так, чтобы порядок в группах Резервирование кластеров был одинаковый (см. рис. 4.31.5, левая часть). 6. Подождать некоторое время, потом нажать Действия – Обновить. Если в дереве информационных баз второго сервера Z3060015 появились информационные базы первого сервера V81CORA (см. рис. 4.31.5, правая часть), синхронизация прошла успешно, и отказоустойчивый кластер готов к работе. Инструкции 279 Рис. 4.31.5. Кластер Z3060015 после добавления резервирования (слева) и полностью готовая отказоустойчивая схема (справа) Настройка отказоустойчивой схемы 8.2 с масштабированием и балансировкой нагрузки Отказоустойчивая схема, собранная выше, обеспечивает отказоустойчивость, но содержит один рабочий сервер в кластере V81CORA, поэтому возможностей по масштабированию и балансировки нагрузки не дает, для этого нужно продолжить настройку. Для настройки схемы с масштабированием и балансировкой нагрузки надо использовать уже собранный в предыдущем примере отказоустойчивый кластер. 1. Добавить в кластер V81CORA новый рабочий сервер Z3060015 (см. рис. 4.31.6). IP-порт – стандартный (1540), а вот диапазоны IP-портов рабочих процессов – сдвинутые, не пересекающиеся с основными (основные – 1560:1591, сдвинутые, например 1660:1691). 280 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.31.6. Параметры добавляемого в кластер V81CORA рабочего сервера Z3060015 2. Аналогичным образом добавить в кластер Z3060015 новый рабочий сервер V81CORA (см. рис. 4.31.7). Инструкции Рис. 4.31.7. Параметры добавляемого в кластер Z3060015 рабочего сервера V81CORA 281 282 3. Настольная книга 1С:Эксперта по технологическим вопросам Добавить к созданным рабочим серверам по одному рабочему процессу (см. рис. 4.31.8). После этого настройка становится завершенной. Рис. 4.31.8. Параметры добавляемых в кластеры рабочих процессов Инструкции 283 4.32. Работа с ЦКК. Как сделать код доступным для отладки Многие вещи в ЦКК выполняются с помощью фоновых и регламентных заданий. Соответственно, может возникать необходимость отлаживать код в явном виде. Приведенный далее пример сделан для ЦКК 2.0.13.1082.68 Например, нужно поставить точку останова в процедуре ИмпортироватьТехЖурнал() общего модуля ИмпортТехЖурнала или процедурах, вызываемых из нее, чтобы понять, с какими фактическими значениями переменных приходится иметь дело при разборе технологического журнала. Ищем вызов процедуры ИмпортироватьТехЖурнал глобальным поиском. Она вызывается из модулей бизнес-процессов АнализВызововКластера1С и КонтрольЧислаИсключений. Для наших целей нам нужен модуль бизнес-процесса КонтрольЧислаИсключений. Открыв его, видим, что процедура вызывается следующим образом: ФоновыеЗадания.Выполнить("ИмпортТехжурнала.ИмпортироватьТехЖурнал", ПараметрыИмпорта, КлючФоновогоЗадания); Комментируем этот вызов, разбираемся, какие параметры передаются, и вместо него пишем свой (см. рис. 4.32.1). Рис. 4.32.1. Замена способа исполнения кода для целей отладки Далее, чтобы вызвать исполнение именно этого кода явно, нужно открыть форму «Задачи мониторинга системных ошибок» с рабочего стола (см. рис. 4.32.2). 82 В ЦКК 2.0.14.15 модули и формы, рассмотренные в данной главе, не изменились. Но даже если к моменту выхода книги материал данного раздела устареет, считаем необходимым включить этот и три следующих раздела в книгу, чтобы продемонстрировать, что при настройке ЦКК на его нынешнем этапе развития нужно уметь программировать в конфигураторе, уметь пользоваться отладчиком, и не надо стесняться делать это. ЦКК может многое, и тот факт, что адаптация его возможностей к конкретным инсталляциям требует применения головы и рук, не является поводом его не использовать. 284 Настольная книга 1С:Эксперта по технологическим вопросам На самом деле это форма ФормаЭлементаКонтрольЧислаИсключений справочника КонтрольныеПроцедуры. Рис. 4.32.2. Форма «Задача мониторинга системных ошибок» на рабочем столе Поставить точки останова в процедуре ИмпортироватьТехЖурнал() общего модуля ИмпортТехжурнала и в модуле бизнес-процесса КонтрольЧислаИсключений перед вызовом ИмпортТехжурнала.ИмпортироватьТехЖурнал(). В появившейся форме (см. рис. 4.32.3) поменять расписание на достаточно редко выполняющееся и при нажатии на кнопку Выполнить сейчас убедиться в том, что остановы срабатывают. Чтобы кнопка стала активной, мониторинг должен быть запущен (см. на том же рис. положение кнопок Старт, Пауза и Стоп). Далее можно приступать к анализу и отладке кода. После окончания работ не забываем вернуть способ выполнения обратно на фоновое задание, а расписание – на рекомендованную частоту (1 раз в 600 с). Рис. 4.32.3. Кнопка «Выполнить сейчас» и гиперссылка на изменение расписания в форме «Задачи мониторинга системных ошибок» Инструкции 285 Этот же подход может пригодиться в том случае, если вам требуется в оффлайне разбирать технологический журнал, присылаемый с действующей информационной системы заказчика однократно при разовых работах. 4.33. Работа с ЦКК. Развертывание для целей контроля ошибок блокировок В нашей практике именно контроль ошибок блокировок и анализ их контекстов дает основу для поиска проблем производительности и параллельности, а количество ошибок блокировок служит важным показателем общего «здоровья» системы. Далее описывается, как решать эту задачу с использованием ЦКК. Создайте пустую клиент-серверную базу. Откройте ее конфигуратором, загрузите в нее конфигурацию83, обновите конфигурацию базы.69 ЗАМЕЧАНИЕ Не следует развертывать демобазу ЦКК на продуктивных серверах, если вы не собираетесь ее перенастраивать (если развернете, заблокируйте в ней фоновые и регламентные задания). Настроенные в базе фоновые и регламентные задания предназначены для условий демобазы и не будут корректно работать в вашей информационной системе, они просто замусорят вам технологический журнал сообщениями об ошибках. В то же время для рабочей базы ЦКК блокировку фоновых и регламентных заданий включать нельзя, она без них не заработает. Перезапустите конфигуратор. Стартуйте базу в режиме исполнения. Если вы попытаетесь по привычке сразу же запустить отладчик, без перезапуска конфигуратора, и у вас появится сообщение о нехватке прав доступа, просто закройте конфигуратор, и запуск продолжится. Если вам требуется собирать только ошибки блокировок, откажитесь от прохождения мастера настроек. В меню Задачи войдите в редактирование поля Кластер серверов 1С 1 и заполните его примерно так, как показано на рис. 4.35.1. Замечания: ■■ ■■ ■■ 83 не указывайте «localhost» в поле с именем компьютера; на закладке Ответственные за настройку контрольных процедур (на рисунке скрыта) во все процедуры ставьте ответственным Ответственного за периметр контроля; пусть вас не смущает, что вы не видите все дерево целиком, – новые узлы будут появляться по мере заполнения вами более близких к корню узлов. Мы берем cf от 2.0.13.10, подготовленный в соответствии с инструкциями из разделов выше. Все реалии работ касаются именно этого релиза. 286 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.35.1. Настройка узла «Кластер серверов 1С 1» На диске D: создайте четыре каталога, см. рис. 4.35.2 (для данного раздела понадобится указывать три из них, а использовать – два). Рис. 4.35.2. Каталоги, нужные для работы ЦКК Затем заполните настройки по умолчанию для узла Рабочие серверы (см. рис. 4.35.3). В качестве путей для некоторых из них укажите созданные заготовки. Для простоты пути к сетевым каталогам укажите через скрытый административный общий ресурс. Слеши на концах в данном случае ошибкой не являются. Затем войдите в редактирование узла Рабочий сервер 1 (см. рис. 4.35.4). Если на предыдущем шаге все было заполнено правильно, поля с каталогами заполнятся автоматически, а контроль после нажатия кнопки Проверить доступ сообщит об успешности операций. Затем войдите в редактирование узла Мониторинг системных ошибок. Имена каталогов, заполненные по умолчанию, есть смысл поменять на более удобные (см. рис. 4.35.5). Количество часов хранения пока оставьте по умолчанию – изменить сможете после оценки количества ошибок сообразно с имеющимся местом на диске. Запустите мониторинг кнопкой Старт (с зеленым треугольником). После этого убедитесь, что в каталоге настроек (см. рис. 4.35.4) создался logcfg.xml с правильным содержимым (см. рис. 4.35.6), а в каталоге, указанном в Location, появилась соответствующая подпапка. Инструкции Рис. 4.35.3. Настройки узла «Рабочие серверы» Рис. 4.35.4. Настройка узла «Рабочий сервер 1» 287 288 Настольная книга 1С:Эксперта по технологическим вопросам Рис. 4.35.5. Настройка мониторинга системных ошибок Рис. 4.35.6. logcfg.xml с правильным для данного случая содержимым Инструкции 289 Чтобы можно было пользоваться фильтром по базам, в список информационных баз добавьте известные нужные вам базы. В добавлении баз есть сложный момент: надо указать Сетевой каталог регистрации. Как его указать, подробно описано во встроенной справке, но для нынешней цели он не актуален, можно указать предлагаемый по умолчанию. Проверьте работу. Создайте искусственно известные конфликты блокировок. После того как пройдет интервал времени, заданный в расписании, убедитесь в том, что ЦКК увидел смоделированные конфликты (см. рис. 4.35.7). Рис. 4.35.7. ЦКК увидел смоделированные конфликты 290 Настольная книга 1С:Эксперта по технологическим вопросам ГЛАВА 5 Методики и дополнительная информация 5.1. Обзор платных и бесплатных инструментов Сразу надо сказать, что бесплатными инструменты являются лишь постольку, поскольку за них не нужно платить дополнительных денег, но они входят в состав коммерческих продуктов, за которые уже заплачено. Что можно увидеть с помощью бесплатных инструментов: общее состояние системы в объективном виде: перегруз/недогруз оборудования, наличие ошибок блокировок (даже если пользователи еще не жалуются), время выполнения ключевых операций; ■■ динамику процесса – хуже/так же/лучше. Существующие бесплатные инструменты: ■■ 1. 2. 3. Все, о чем говорилось в разделе 4.7 «Замеры производительности»: □□ замер производительности отладчиком 1С8. Позволяет оценить скорость работы кода конфигурации. Измеряет количество использований конкретных участков кода и время выполнения этих участков; □□ различного рода самописные обработки; □□ функционал подсистемы «Оценка производительности» из состава Библиотеки стандартных подсистем «1С». Ряд типовых конфигураций уже содержит данный функционал, при необходимости его можно встроить самостоятельно. Как это сделать, описывается в соответствующем разделе этой книги. Windows performance monitor. Позволяет измерять загрузку оборудования. Настройка и использование описаны в разделе 4.1. Технологический журнал. Позволяет получать технологическую информацию о работе приложений, как сервера, так и клиентов. Например, позволяет 292 Настольная книга 1С:Эксперта по технологическим вопросам посчитать количество ошибок блокировок. Настройка и использование описаны в разделах 4.5 и 4.6. 4. Специфический род бесплатных инструментов (профайлер SQL-сервера и аналогичные инструменты других СУБД). Эти инструменты больше доступны и привычны администраторам баз данных, чем программистам и внедренцам «1С». Необходимым для нас приемам работы в профайлере посвящено несколько глав в этой книге. Платный инструмент – это «1С:Корпоративный инструментальный пакет 8» (http://v8.1c.ru/expert/etp.htm). В его состав входят: Тест-центр, ■■ Центр управления производительностью, ■■ Сценарное тестирование, ■■ Центр контроля качества, ■■ Стандартный нагрузочный тест. Существует легенда, что если купить этот пакет и установить его у себя, то проблемы производительности исчезнут сами собой. Это нельзя назвать неправдой, потому что оно примерно так и случится... если вместе с покупкой пакета вы пригласите специалистов, умеющих им пользоваться. ■■ 5.2. Требования с диска ИТС, применяемые при проверке на 1С:Совместимо!, влияющие на производительность Для получения статуса 1С:Совместимо! конфигурация проходит проверку на соответствие кода формальным требованиям. Полный список требований приведен на ИТС. Те из них, что влияют на производительность, приведены в таблице 5.2.1. Таблица 5.2.1. Требования, влияющие на производительность Требование Описание Проверка на пустой результат выполнения запросов Использование ключевых слов в запросах «Объединить» и «Объединить все» в запросах Проверку того, что результат выполнения запроса не содержит строк, следует выполнять с помощью метода Пустой(), поскольку на получение выборки из результата запроса (выгрузка его в таблицу значений) будет затрачиваться дополнительное время В общем случае при объединении в запросе результатов нескольких запросов следует использовать конструкцию «ОБЪЕДИНИТЬ ВСЕ», а не «ОБЪЕДИНИТЬ», поскольку во втором варианте при объединении запросов полностью одинаковые строки заменяются одной, на что затрачивается дополнительное время, даже в случаях, когда одинаковых строк в запросах заведомо быть не может. Исключением являются ситуации, когда выполнение замены нескольких одинаковых строк одной является необходимым условием выполнения запроса ...В разделе инициализации модуля формы запрещается открывать другие формы или диалоги (например, операторами Вопрос(), Предупреждение() и т. д.). Программное управление формой Методики и дополнительная информация Требование Обращение к данным информационной базы в обработчиках часто вызываемых событий 293 Описание Следует минимизировать обращение к данным информационной базы в обработчиках событий, приведенных ниже, поскольку это может существенно замедлить интерактивную работу. События формы: ○○ ОбновлениеОтображения(). События табличного поля: ○○ ПриВыводеСтроки(), ○○ ПриАктивацииСтроки(). В качестве средств минимизации в зависимости от ситуации могут быть: ○○ использование переменных модуля формы для кеширования данных, ○○ перенос обработки данных в обработчики других событий, ○○ для таблиц значений получение необходимых данных на этапе заполнения, ○○ любые другие методы Получение метаданных объектов Получение метаданных объекта конфигурации следует выполнять с помощью метода Метаданные() этого объекта, а не путем обращения к свойству глобального контекста «Метаданные», так как второй способ существенно более медленный. Правильно: СправочникОбъект.Метаданные() Неправильно: Метаданные.Справочники[ИмяСправочника] Использование объекта «РегистрСведений МенеджерЗаписи» Чтение записи (набора записей) из регистра сведений без последующей модификации необходимо выполнять запросом. Во всех остальных случаях объект «РегистрСведенийМенеджерЗаписи» следует применять только тогда, когда выполнение операций с регистром сведений требует использования отбора одновременно по всем измерениям. При этом менеджер записи использует для выполнения записи два набора записей, устанавливая им соответствующие значения отборов. Поэтому обработчики событий набора записей вызываются и тогда, когда для записи данных используется менеджер записи. В остальных случаях следует использовать объект «РегистрСведенийНаборЗаписей». С точки зрения производительности использование менеджера записей в некоторых случаях будет столь же эффективным, как и использование набора записей, а в некоторых – менее, так как будут выполняться лишние действия. Правильно: Набор = РегистрыСведений.ЗначенияПравПользователя.СоздатьНаборЗаписей(); Набор.Отбор.НаборПрав.Установить(ЗначениеНабораПрав); Для Каждого СтрокаТаблицы ИЗ ТаблицаЗначенийПрав Цикл Запись = Набор.Добавить(); Запись.НаборПрав = ЗначениеНабораПрав; Запись.Право = СтрокаТаблицы.Право; Запись.Значение = СтрокаТаблицы.Значение; КонецЦикла; Набор.Записать(); Неправильно: Для Каждого СтрокаТаблицы ИЗ ТаблицаЗначенийПрав Цикл ЭлементРегистраСведений = РегистрыСведений.ЗначенияПравПользователяСоздатьМенеджерЗаписи(); ЭлементРегистраСведений.НаборПрав = ЗначениеНабораПрав; ЭлементРегистраСведений.Право = СтрокаТаблицы.Право; ЭлементРегистраСведений.Значение = СтрокаТаблицы.Значение; ЭлементРегистраСведений.Записать(); КонецЦикла; 294 Настольная книга 1С:Эксперта по технологическим вопросам Требование Описание Копирование строк между таблицами значений произвольной структуры При копировании строк между различными таблицами значений (табличными частями и т. п.) со схожим составом колонок следует использовать метод глобального контекста ЗаполнитьЗначенияСвойств(). Алгоритмы, использующие данный метод, значительно эффективнее, например, многократного перебора колонок таблицы значений, выполняемого для получения их состава. Правильно: Для каждого СтрокаТаблицыИсточника Из ТаблицаИсточник Цикл СтрокаТаблицыПриемника = ТаблицаПриемник.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтрокаТаблицыИсточника); КонецЦикла; Неправильно: Для каждого СтрокаТаблицыИсточника Из ТаблицаИсточник Цикл СтрокаТаблицыПриемника = ТаблицаПриемник.Добавить(); Для каждого Колонка Из ТаблицаПриемник.Колонки Цикл КолонкаТаблицыИсточника = ТаблицаИсточник.Колонки.Найти(Колонка.Имя); Если КолонкаТаблицыИсточника <> Неопределено Тогда СтрокаТаблицыПриемника[Колонка.Имя] = СтрокаТаблицыИсточника[Колонка.Имя]; КонецЕсли; КонецЦикла; КонецЦикла; Получение представлений для ссылочных значений в табличном документе При формировании табличного документа запрещено в качестве параметров ячеек с типом заполнения «Параметр» указывать ссылочные значения, поскольку в этом случае в момент вывода данных в табличный документ будет выполнено многократное обращение к базе данных для получения представлений этих значений. Поэтому в качестве параметров следует указывать сами представления. Исключением могут быть случаи, когда для получения представлений придется выполнять аналогичное многократное обращение к базе данных. При этом следует иметь в виду, что при получении представлений для полей непосредственно в самом запросе (через поле «Представление» или функцией Представление(<Имя поля>)) выполняется неявное соединение с таблицей объекта, для которого получаются представления. Для полей составного типа – несколько соединений, для каждого из типов, входящих в состав. Это может приводить к увеличению времени выполнения запроса (и как следствие общего времени формирования итогового документа), а при большом количестве типов – к невозможности его выполнения в клиент-серверной версии из-за ограничения Microsoft SQL Server, по которому в запросе не может участвовать больше 256 таблиц. Такие случаи также могут быть исключением для данного правила. В них представления для ссылочных значений допускается получать в момент их вывода в табличный документ. Поскольку однозначно рекомендовать, какой из способов получения представлений следует выбрать, нельзя, такой выбор должен делаться разработчиком самостоятельно, на основании данных, полученных экспериментально Методики и дополнительная информация 295 5.3. Уточнения, важные для общего понимания картины ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ 84 Есть ли жалобы, достаточно четко сформулированные, чтобы использовать их как формализованные требования. Не идет ли речь о файловой базе. Полный список и характеристики серверного оборудования, задействованного в ландшафте «1С». Используется ли виртуализация оборудования; если да, то что, чем и как именно она осуществляется. Какая ОС и какая СУБД используются. Соответствие программного обеспечения списку http://v8.1c.ru/requirements/. Номер релиза платформы, соответствие текущему. Выполняются ли регламентные операции СУБД, с какой периодичностью. Размеры рабочих баз. Количество пользователей, работающих одновременно (максимальное/обычное). Количество информационных баз в кластере: □□ всего, □□ из них тестовых/архивных. Ведется ли учет фоновых и регламентных заданий: □□ установлена ли блокировка фоновых заданий в тестовых/архивных базах, □□ нет ли ненужных заданий в рабочих базах. Разрядность сервера «1С». Количество рабочих процессов, соответствие текущему тренду84.70 Если решение полностью типовое или создано на основе типового, релиз типового решения, соответствие текущему релизу для этого решения. Какой режим управления блокировками данных используется: автоматический, смешанный или управляемый. Не идет ли речь о сочетании автоматического или смешанного режима блокировок и СУБД Oracle Database. Текущие рекомендации для 8.2 следующие: для 64-разрядного сервера – 1 рабочий процесс, для 32-разрядного сервера – 1 рабочий процесс на 2 Гб оперативной памяти или на 100–150 пользователей. – по 1 рабочему процессу на каждые 2 Гб оперативной памяти, необходимые для работы сервера приложений (но не от общего объема ОЗУ, т. е. ошибкой будет запускать 32 рабочих процесса только потому, что у вас на сервере 64 Гб оперативной памяти). – иногда считают – по 1 рабочему процессу на 80–100 пользователей при невысокой интенсивности их работы. В 8.3 механизм определения количества рабочих процессов переработан; количество процессов определяется автоматически на основе количества информационных баз и количества пользователей для одного процесса, задаваемых в свойствах рабочего сервера «1С». 296 ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ Настольная книга 1С:Эксперта по технологическим вопросам Используется ли RLS; по каким признакам; сколько ролей одного пользователя имеют ограничения RLS. Есть ли зафиксированные обращения, связанные с разной скоростью работы под разными правами. Используется ли разделитель данных, в каком режиме. Используются ли заведомо тяжелые механизмы: □□ онлайновый партионный учет, □□ онлайновый учет авансов, □□ документы с числом строк табличной части свыше 1000, □□ единственная номенклатура, □□ конфигурация на основе регистра расчета с периодом действия. Находятся ли все серверы и рабочие станции «1С» в одной подсети или в разных. Как организована маршрутизация. Если работа ведется с сервера терминалов, какой клиент используется для подключения к нему. Присутствуют ли, и если да, то в каких частях информационной системы участки сети с пропускной способностью 100 Мбит/с или менее, в т. ч. Wi-Fi. Используется ли шифрование. Используется ли антивирусное программное обеспечение, и какое. Большую часть данных по спискам из разделов 5.4 и 5.5 специально получать не нужно, если изложенные в них приемы и решения не приводят к возникновению проблем. В то же время всегда следует обращать внимание на них, если они себя проявляют. Получить и проанализировать данные мониторинга (см. раздел 5.6). 5.4. Проектные и технические решения, приводящие к проблемам ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ Удалять профили пользователей с терминального сервера после завершения их сеансов. Совместно использовать программные и аппаратные ключи защиты. Размещать аппаратные ключи на сервере «1С» или СУБД. Проводить какие-либо регламентные работы при начале или при окончании работы пользователя. Проводить регламентные работы, которые может делать один пользователь, всеми пользователями. Проводить регламентные работы в момент интенсивной работы. Проводить загрузку сообщений обмена и другие загрузки в длинной транзакции. Проводить выгрузку сообщений обмена в длинной транзакции. Методики и дополнительная информация 297 5.5. Приемы конфигурирования, приводящие к проблемам ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ Использовать константы не по назначению (для хранения заведомо изменяющихся данных). Использовать автоматическую регистрацию в последовательностях и перемещение границы при проведении документов. Пользоваться операторными скобками Попытка… Исключение внутри транзакции в системах на стадии промышленной эксплуатации. Использовать вложенные транзакции, явно и неявно, например, вызывая из процедур проведения документа проведение других документов, запись элементов справочников и т. п. Использовать запросы, в том числе через объектную модель, в цикле. Неявно использовать запросы в цикле, например, в формах списка в обработчике события ПриВыводеСтроки получать какие-то дополнительные данные из базы (распространенный случай – статусы документов из регистров в формах списков документов). В транзакции (в т. ч. проведения документа) получать данные не из регистров, а из других документов. Открывать модальные формы (например, Вопрос(…), Предупреждение(…)) внутри транзакций, в т. ч. неявных, например, при проведении документов. Вызывать ЭтотОбъект.Записать() внутри транзакции записи объекта, например, из процедуры ОбработкаПроведения. Вызывать обращение через COM-соединение к другой базе внутри транзакции. В формах, в которых динамический список формируется через произвольный запрос, чрезмерно усложнять запрос. Вызывать запрос, формирующий отчет, из модуля формы, а не из модуля объекта. 5.6. Ежедневный мониторинг В перечень проектных решений, приводящих к проблемам (раздел 5.4), следовало бы включить еще одну весьма распространенную методику: ведение мониторинга проблем исключительно по жалобам (обращениям) пользователей. На протяжении ряда глав этой книги проводилась мысль о недопустимости подобного подхода, и рассказывалось об инструментах, с помощью которых можно получать объективные данные о состоянии системы. Причем для этого не требуется никаких особых платных инструментов мониторинга, а настройка бесплатных займет минимальное время (1,5–2 часа максимум). 298 Настольная книга 1С:Эксперта по технологическим вопросам Подводя итоги, для получения объективных данных о состоянии системы требуется: 1. Включить мониторинг загрузки оборудования (см. раздел 4.1). 2. Включить технологический журнал севера «1С» и начать считать по нему хотя бы ошибки блокировок (см. разделы 4.5 и 4.6). 3. Встроить подсистему «Оценка производительности» из состава Библиотеки стандартных подсистем «1С» и реализовать замеры времени по ключевым операциям (см. раздел 4.7). Если используется типовое решение, возможно, она уже встроена и часть замеров реализована. 4. Организовать сбор и подсчет дампов, начать считать падения серверных процессов (см. раздел 4.9). 5. Снимать и анализировать эти показатели ежедневно (если все хорошо, то можно не так часто, но все равно минимум раз в неделю это надо делать). В разделе 2.4 говорилось, что методики общей диагностики и мониторинга должны быть использованы, если не дала результатов проверка обычных подозреваемых по проблемам. То есть если сразу не удалось назначить специализированное «лечение», нужно отойти на позиции общего понимания ситуации, для чего надо наладить сбор объективных данных. Если вы дочитали книгу до этого места, а мониторинг у вас еще не ведется, пожалуйста, посвятите остаток сегодняшнего дня его настройке. Это будет лучшей благодарностью автору книги за несколько месяцев работы над ней. ГЛАВА 6 Дополнительные заметки 6.1. Экономический смысл автоматизации учета и оптимизации производительности А зачем, правда, автоматизировать учет, а потом заниматься оптимизацией внедренного решения? Стандартный ответ: автоматизировать учет нужно, чтобы облегчить труд бухгалтера. А оптимизацию производительности внедренного решения нужно проводить, когда бизнес-процесс не успевает выполниться за отведенное время. На практике, однако, оказывается, что бухгалтер, вполне себя хорошо чувствовавший при системе бумажного учета, проявляет упорное нежелание пользоваться новой системой. И корни данного явления имеют под собой не только субъективные, но и вполне экономические причины. А подход к вопросам производительности, основанный на принципе «пока гром не грянет, мужик не перекрестится», не только чреват рисками для бизнеса, но и прямо лишает владельца компании возможности получать больше работы за те же деньги, причем происходит это постоянно и сейчас, а не в туманной перспективе. Сначала избавимся от иллюзии насчет того, что перед системой автоматизации учета ставится задача облегчить жизнь сотрудникам, занятым собственно учетом. У Маркса в начале XXXIII главы 1-го тома «Капитала» читаем: «Джон Стюарт Милль говорит в своих «Основаниях политической экономии»: «Сомнительно, чтобы все сделанные до сих пор механические изобретения облегчили труд хотя бы одного человеческого существа» (прим. Маркса – Миллю следовало бы сказать: «хотя бы одного человеческого существа, не живущего чужим трудом», потому что машины, несомненно, сильно увеличили число знатных бездельников). Но перед капиталистически применяемыми машинами вовсе и не ставится такой цели. 300 Настольная книга 1С:Эксперта по технологическим вопросам Подобно всем другим методам развития производительной силы труда, они должны удешевлять товары, сокращать ту часть рабочего дня, которую рабочий употребляет на самого себя, и таким образом удлинять другую часть его рабочего дня, которую он даром отдает капиталисту. Машины – средство производства прибавочной стоимости». Замените «машины» на «средства автоматизации учета», и вы получите нормальную, не иллюзорную формулу для задачи систем автоматизации учета: они должны удешевлять товары, сокращать ту часть рабочего дня, которую рабочий употребляет на самого себя, и таким образом удлинять другую часть его рабочего дня, которую он даром отдает капиталисту. Можно, однако, справедливо возразить, что сотрудник, осуществляющий учет, за некоторыми исключениями, почти никогда не является производственным рабочим, и вроде бы речь не о нем. Чтобы прояснить, в чем тут дело, приведу длинный блок цитат из Маркса. Во втором томе «Капитала» в главе VI, посвященной издержкам обращения, читаем: «Превращения формы капитала из товара в деньги и из денег в товар являются в то же время торговыми сделками капиталиста, актами купли и продажи. Время, в течение которого совершаются эти превращения формы капитала, субъективно, с точки зрения капиталиста, является временем продажи и купли, т. е. тем временем, в течение которого он функционирует на рынке как продавец и покупатель... Оно составляет часть его делового времени. <...> Поэтому, если товаровладельцы не капиталисты, а самостоятельные непосредственные производители, то время, затрачиваемое ими на куплю и продажу, есть вычет из их рабочего времени. <...> Купля и продажа становятся главной функцией капиталиста, заставляющего других работать на себя <...> Примем, что агент по купле и продаже является человеком, продающим свой труд. Он расходует свою рабочую силу и свое рабочее время на эти операции Т – Д и Д – Т. <...> Как бы ни оплачивался его труд, он как наемный рабочий часть своего времени работает даром. Может быть, он получает ежедневно стоимость, вновь создаваемую им за восемь часов, а работает в продолжение десяти часов. <...> ...если этих агентов применяет капиталист, то неоплаченные два часа уменьшают издержки обращения его капитала, составляющие вычет из его дохода. Для него – это положительный выигрыш, так как отрицательные границы возрастания стоимости его капитала суживаются. <...> ...капиталистический товаропроизводитель выступает в качестве агента обращения<...> Если размер предприятия принуждает его или позволяет ему покупать (нанимать) особых агентов обращения как наемных рабочих, то сущность дела от этого не меняется. <...> Наряду с затратой времени на осуществление купли и продажи рабочее время расходуется также и на ведение бухгалтерского учета, которое, кроме того, Дополнительные заметки 301 требует затрат и овеществленного труда (перья, чернила, бумага, письменный стол и т. д.), т. е. требует издержек на контору. Следовательно, при выполнении этой функции расходуется, с одной стороны, рабочая сила, с другой стороны – средства труда. Дело здесь обстоит совершенно так же, как со временем, затрачиваемым на куплю и продажу». Отсюда вытекает вообще экономический смысл внедрения систем автоматизации учета как повышение степени эксплуатации работников учетных служб (а отнюдь не облегчение им жизни «волшебной кнопкой»). Иллюзия развеяна, и без нее наглядно становится виден экономический смысл повышения производительности систем автоматизации учета, применительно как к бухгалтерам, так и к менеджерам по продажам. Сотрудник является человеком, продающим свой труд. Как бы ни оплачивался его труд, он как наемный рабочий часть своего времени работает даром. Повышение производительности систем автоматизации учета увеличивает количество операций в единицу времени. За счет этого оно повышает длительность неоплачиваемого рабочего времени и позволяет освободившееся рабочее время использовать с пользой для дела, например, для повышения сложности и оперативности учета, притом, возможно, без роста заработной платы. 6.2. О режиме доступности 24х7 Если команда, продающая проект, делает заявление о режиме доступности 24х7 для базы «1С», спросите ее, как она собирается это обеспечивать. Ответ «Включить, и дальше оно само» правильным не является. Как уже говорилось в разделе 3.4, если есть необходимость, то существует возможность построить систему с полным дублированием всех компонентов, которая будет работать в режиме 24х7. Такие системы существуют и находятся в промышленной эксплуатации. Например, 1cFresh. Но созданием такой системы надо специально заниматься, сама собой она не возникнет, создать ее сложно, и стоит это дорого. Поэтому правильным надо считать подход, при котором по умолчанию принимается, что, как и для любых сложных информационных систем, на текущем этапе развития платформы «1С:Предприятие» для информационных систем, построенных на ней, требуется регулярное проведение регламентных работ. И чем масштабнее система, тем строже надо соблюдать требования по их выполнению. Если же нужен режим 24х7, его надо обеспечивать отдельно. 302 Настольная книга 1С:Эксперта по технологическим вопросам 6.3. О методике расчета оборудования Для расчета оборудования, необходимого для развертывания проектируемой информационной системы на платформе «1С:Предприятие», необходимо собрать о ней следующие данные: решаемая задача; ■■ количество баз; ■■ количество операций в пиковый день (если операция – это не одна проводка, а документ – уточнить размер табличной части); ■■ количество операций в обычный день; ■■ предпочтительная конфигурация «1С» (планируемая); ■■ альтернативные конфигурации «1С» (допустимые); ■■ необходимость круглосуточного доступа; ■■ используется распределенная база или обмены с базами с той же конфигурацией; ■■ есть ли свои специалисты по Linux; ■■ есть ли свои специалисты по IBM DB2, Oracle Database или PostgreSQL; ■■ это новая база или развитие старой; ■■ количество пользователей (максимальное/наиболее вероятное); ■■ сколько из них будут работать через терминальный сервер в толстом клиенте/в тонком клиенте; ■■ необходимость выделения оборудования виртуализацией имеющегося; ■■ пожелания к отказоустойчивости (отказоустойчивый кластер «1С», отказоустойчивый кластер СУБД и т. п.). Если планируется внедрение типовых решений, то, используя собранные данные, оборудование, необходимое для сервера приложений «1С» и сервера СУБД, можно приблизительно подобрать, используя данные сайта http://v8.1c.ru/overview/ techparams/, пересчитав данные пропорционально количеству операций в единицу времени. ■■ Если планируется внедрение собственных, не типовых решений, то для предварительной оценки требований к оборудованию для сервера приложений «1С» и сервера СУБД можно ориентироваться на те же расчеты, потому что если в системе будут проблемы параллельности, то нагрузка на оборудование сервера приложений «1С» и сервера СУБД будет не выше расчетной, а, напротив, гораздо ниже. Если решение совсем не соответствует типовому, можно провести замер нагрузки на оборудование для одного рабочего места, выполняющего какой-то обычный для него сценарий работы. Далее надо умножить требования для одного пользователя на планируемое количество пользователей. При этом рабочее место обязательно должно запускаться с одной машины, сервер приложений – с другой, сервер СУБД – с третьей, чтобы считать требования для каждого из серверов отдельно. Дополнительные заметки 303 При расчете системы часто забывают про сервер терминалов. Между тем, при работе уже 20–40 пользователей в режиме толстого клиента нагрузка на терминальный сервер догоняет нагрузку на сервер приложений, а далее существенно перегоняет ее. Последствия такой «забывчивости» могут быть достаточно печальными. Чего совершенно точно не следует делать, так это, купив один сервер, путем виртуализации выделять из него сервер терминалов, сервер приложений и сервер СУБД. Лучше, если это будут 3 разных сервера, а если уж купили один, пусть на нем одном все и работает, без виртуализации. Требования к созданию центров обработки данных под ландшафт «1С» могут включать блок, относящийся к отказоустойчивости системы (кластер «1С», кластер СУБД, кластер ОС). На самом деле если у вас нет своих людей (речь именно о ваших сотрудниках, а не о проектной команде внедренцев), умеющих правильно ее настроить и правильно использовать, то целесообразность выделения средств на это оказывается весьма сомнительной. Комплекс мероприятий, обеспечивающих отказоустойчивость и надежность системы, в том числе должен включать в себя регулярные тренинги по сбоям. Приведем пример из смежной области: многие способны по инструкции настроить резервное копирование базы так, чтобы каждые 30 минут создавались копии журналов транзакций (вариант – попросить настроить внедренцев); но вот восстанавливать базу из такого бэкапа почему-то не берутся, а предпочитают делать это из dt-файла или полного бэкапа, сделанного ночью. В свете этого примера особенно интересными становятся затраты на приобретение дорогостоящей системы хранения данных. Подводя итоги, ваш центр обработки данных – это не только железки, которые в нем стоят, но и сотрудники, которые его обслуживают. Нет смысла пытаться использовать (и закупать) то, чем не сможете пользоваться без посторонней помощи. 6.4. О работах в различных СУБД Часто просят сказать, что будет, если вместо одной СУБД использовать другую. Ответ прост: возьмите именно вашу базу, попробуйте развернуть ее под другой СУБД и провести хотя бы маленькое нагрузочное тестирование. Такая задача при наличии относительно свободного стенда может быть решена одним человеком. Все СУБД, с которыми может работать «1С», имеют бесплатные редакции. При этом вы сможете оценить как эффект от перехода на другую СУБД именно для вашей базы (это существенно), так и собственные возможности по ее настройке и дальнейшему сопровождению (это тоже существенно, см. резюме по предыдущей главе). 304 Настольная книга 1С:Эксперта по технологическим вопросам Заключение. О гарантиях работоспособности системы через несколько лет Иногда приходится отвечать на вопросы: как будет вести себя система на платформе «1С:Предприятие» через 5 лет с учетом 30 % роста документов ежегодно, будут ли и как долго выполняться «тяжелые» регламентные операции в их базе, насколько будет работоспособна база? Ответ тут довольно простой: давайте посчитаем. Результаты сведем в таблицу 7.1. Таблица 7.1. Прогноз роста базы с учетом роста интенсивности ввода документов Год Интенсивность ввода документов 2013 100 % 2014 130 % 2015 169 % 2016 219,7 % 2017 285,61 % Сумма 904,31 % То есть за 5 лет база вырастет в 9 раз по объему, а интенсивность работы вырастет в 3 раза. Теперь посмотрите параметры наиболее крупных внедрений той же конфигурации с сайта v8.1c.ru (например, тут: http://v8.1c.ru/overview/techparams/), соотнесите их с прогнозируемыми параметрами своей системы и, скорее всего, вы увидите, что не переходите в зону непрогнозируемых рисков – что-то похожее такого размера уже работает. Метод хорош тем, что он дает результат быстро и бесплатно. Этот метод, однако, не учитывает специфику вашего документооборота, только используемую конфигурацию «1С». Можно попробовать получить этот ответ, проведя нагрузочные тестирования. 306 Настольная книга 1С:Эксперта по технологическим вопросам Это уже не бесплатно. Но по результатам тестирований вы увидите узкие места и можете приступить к их оптимизации. Оптимизировать работу системы возможно, даже если это типовые БП и ЗУП. Однако может потребоваться достаточно трудоемкая и нестандартная оптимизация. Все это вопрос времени, а, следовательно, денег. Вне рамок ЦКТП (http://v8.1c.ru/expert/cts/cts.htm) такие проекты не стоит делать. А в их рамках с помощью «1С» (при поддержке разработчиков) – вполне можно. Но это если ничего не будет меняться. А меняться будет. Давайте для БП8 проделаем обратный отсчет на 6–7 лет и сведем основные вехи в таблицу 7.2. Таблица 7.2. Развитие платформы «1С:Предприятие» и типового решения «Бухгалтерия предприятия» Дата 27.12.2006 21.12.2007 25.09.2009 01.04.2010 28.04.2012 29.05.2013 Событие Выход платформы 8.1 Выход БП 8 редакции 1.6 (поддержка законодательства до 31.12.2010 г.) Выход платформы 8.2 (офиц. релиз) Выход БП 8 редакции 2.0 Выход БП 8 редакции 3.0 Выход платформы 8.3 (офиц. релиз) Смотрите сами: как все изменилось, причем в лучшую сторону. Каковы реальные риски, оцениваемые 5 лет назад для «Бухгалтерии предприятия» редакции 1.6 на 8.1? Их нет, потому что и БП 1.6, и платформа 8.1 уже в прошлом. Еще надо учесть, что в 2011 году все, кому актуальна поддержка законодательства, перешли на «Бухгалтерию предприятия» редакции 2.0, и объем базы у многих опять сократился – потребовался перенос остатков. С помощью нагрузочных тестирований можно и нужно защищаться от опасностей текущего периода: переходить или нет на новый релиз платформы; как работает ваша уникальная конфигурация, которую вы внедряете через 2 месяца; как отразятся на производительности ваши доработки, которые вы внедряете через 2 недели. Для таких случаев систему организации нагрузочных тестов надо собрать один раз и потом регулярно использовать в рамках системы управления изменениями проекта. Затраты на ее организацию с нуля распределятся на большое количество тестов, которые на этом проекте с ее помощью будут проведены. Но надо ли собирать систему с нуля ради единственного теста, дающего прогноз на 5 лет вперед, это все-таки всегда открытый вопрос, как с точки зрения экономического эффекта, так и с точки зрения обоснованности рисков текущего периода в пятилетней перспективе. Как же все-таки дать гарантию? Если система уже работает, прочитайте эту книгу, особенно раздел 5.6, включите мониторинг времени выполнения ключевых операций, мониторинг загрузки оборудования, мониторинг ошибок блокировок. Заключение. О гарантиях работоспособности системы через несколько лет 307 Если в системе появятся проблемы производительности, вы их увидите минимум за полгода до того, как они станут критичными для бизнеса. Тогда у вас, во-первых, появятся гораздо более точные данные об узких местах, чем те, которые можно получить с помощью моделирования. Во-вторых, у вас будет достаточно времени, а у заказчика достаточно мотивации, чтобы начать заниматься поиском их решений. В-третьих, эти данные будут построены на реалиях сегодняшнего дня, а не на прогнозах. Если проблемы уже есть, вы их сразу сегодня и увидите. Проблемы производительности в одночасье не появляются, их можно и нужно ловить на ранней стадии. То, что вы ведете ежедневный мониторинг, – это самая лучшая гарантия работоспособности вашей системы на обозримую перспективу, и эту гарантию вы можете получать в каждый момент жизни системы. 308 Настольная книга 1С:Эксперта по технологическим вопросам Кому что читать Сотрудникам заказчика: ИТ-директору: главу 1, разделы 2.1–2.4, 3.1–3.5, 3.9, 4.10 (общие вопросы), 4.16 (общие вопросы), 4.21 (тест-центр – общие принципы), 4.21 (стандартный нагрузочный тест), 4.22, 5.1, 5.3, 5.4, 5.6, 6.1–6.4, «Заключение. О гарантиях работоспособности системы через несколько лет»; ■■ системному администратору: главу 1, разделы 2.1–2.3, 3.1–3.5, 3.17–3.19, 3.9, 4.1–4.9, 4.22, 4.23, 4.26, 4.29– 4.31, 5.1, 5.3, 5.4, 5.6, 6.1–6.4, «Заключение. О гарантиях работоспособности системы через несколько лет»; ■■ методисту: главу 1, разделы 2.1–2.3, 3.1–3.4, 3.9, 3.11, 5.1, 5.3, 5.4, 5.6, «Заключение. О гарантиях работоспособности системы через несколько лет»; ■■ администратору СУБД: главу 1, разделы 2.1–2.4, 3.1–3.14, 3.16–3.19, 4.4, 4.12–4.15, 4.22, 4.23, 5.1, 5.3, 5.4, 5.6, 6.2–6.4, «Заключение. О гарантиях работоспособности системы через несколько лет». Сотрудникам фирмы-внедренца (или сотрудникам заказчика, если у заказчика своя команда разработки и поддержки): ■■ внедренцу: главу 1, разделы 2.1–2.3, 3.1–3.5, 3.9, 3.11–3.13, 3.15–3.19, 4.1–4.9, 4.10 (общие вопросы), 4.12–4.15, 4.16 (общие вопросы), 4.20, 4.21 (простейшие тесты), 4.21 (тест-центр – общие принципы), 4.21 (стандартный нагрузочный тест), 4.22, 4.23, 4.26, 4.27, 4.29– 4.33, 5.1–5.6, 6.1–6.4, «Заключение. О гарантиях работоспособности системы через несколько лет»; ■■ программисту: главу 1, разделы 2.1–2.3, 3.1–3.3, 3.6–3.13, 3.15, 4.7, 4.20, 4.21 (простейшие тесты), 4.27, 4.32, 5.1–5.5, «Заключение. О гарантиях работоспособности системы через несколько лет»; ■■ руководителю проекта: главу 1, разделы 2.1–2.4, 3.1–3.5, 3.9, 4.10 (общие вопросы), 4.16 (общие вопросы), 4.21 (тест-центр – общие принципы), 4.21 (стандартный нагрузочный тест), 4.22, 5.1, 5.3, 5.4, 5.6, 6.1–6.4, «Заключение. О гарантиях работоспособности системы через несколько лет». 1С:Экспертам по технологическим вопросам требуется владение всем материалом книги. ■■ 310 Настольная книга 1С:Эксперта по технологическим вопросам Список сокращений APDEX – Application Performance Index, индекс производительности программ. CPU – Central processor unit, центральный процессор. DHCP – Dynamic Host Configuration Protocol – протокол динамической настройки узла. DNS – Domain Name System – система доменных имен. ID – Identifier, идентификатор. MSDN – Microsoft Developer Network, подразделение компании «Майкрософт», ответственное за взаимодействие фирмы с разработчиками. PID – Process IDentifier, идентификатор процесса. RLS – Record Level Security, разделение доступа к данным на уровне записей. RPO – Recovery point objective, допустимая точка восстановления. RTO – Recovery time objective, допустимое время восстановления. VLAN – Virtual Local Area Network, виртуальная локальная сеть. БД – база данных. БП – Бухгалтерия предприятия. БСП – Библиотека стандартных подсистем. ВРМ – виртуальное рабочее место. ДПС – дорожно-патрульная служба. ЗУП – Зарплата и управление персоналом. ИТС – Информационно-технологическое сопровождение «1С». КИП – Корпоративный инструментальный пакет. КО – ключевая операция. КОРП – корпоративная редакция конфигурации. НДС – налог на добавленную стоимость. ОЗУ – оперативное запоминающее устройство. 312 Настольная книга 1С:Эксперта по технологическим вопросам ОП – оценка производительности (подсистема). ОРНР (ОРНР1, ОРНР2 и т. д.) – общий реквизит, являющийся разделителем в режиме «независимо». ОРР – общий реквизит, являющийся разделителем (для случая, когда режим разделения не имеет значения). ОРРХ – значение хеш-функции набора значений разделителей. ОРСР – общий реквизит, являющийся разделителем в режиме «независимо и совместно». ОС – операционная система. ПО – в качестве сокращения в данной книге не используется, используется только как элемент языка запросов, наряду с ГДЕ, ИЛИ и пр. СУБД – система управления базами данных. ТЖ – технологический журнал. ТЦ – Тест-центр. УПП – Управление производственным предприятием. ЦКК – Центр контроля качества. ЦКТП – Центр корпоративной технологической поддержки. ЦУП – Центр управления производительностью. © ООО «1С-Паблишинг», 2015 © Оформление. ООО «1С-Паблишинг», 2015 Все права защищены. Материалы предназначены для личного индивидуального использования приобретателем. Запрещено тиражирование, распространение материалов, предоставление доступа по сети к материалам без письменного разрешения правообладателей. Разрешено копирование фрагментов программного кода для использования в разрабатываемых прикладных решениях. Фирма «1С» 123056, Москва, а/я 64, Селезневская ул., 21. Тел.: (495) 737-92-57, факс: (495) 681-44-07. 1c@1c.ru, http://www.1c.ru/ Издательство ООО «1С-Паблишинг» 127434, Москва, Дмитровское ш., д. 9. Тел.: (495) 681-02-21, факс: (495) 681-44-07. publishing@1c.ru, http://books.1c.ru Об опечатках просьба сообщать по адресу publishing@1c.ru.