Блокировки 1С или что тормозит работу 1С? Почему медленно работает и зависает 1С?

Влияние блокировок на производительность 1С:Предприятие 8

Команда gilev уже много лет занимается вопросами производительности и успешно решает в том числе вопросы устранения ожиданий на блокировках и взаимоблокировок.

Lock request time out period exceeded

Ниже мы расскажем наш опыт по решению данных проблем.

Обнаружение проблем блокировок в 1С

Вопросы производительности в многопользовательском режиме вовсе не обязательно связаны с плохим кодом или плохим железом. Для начала нам надо ответить на вопрос — какие проблемы производительности существуют и что их вызывает?

Отследить вручную деятельность сотен пользователей вручную нельзя, нужен инструмент автоматизирующий сбор такой информации.

Существует много инструментов, но практически у всех них есть один очень существенный недостаток — цена.

Но есть выход — мы в качестве инструмента анализа выбираем БЕСПЛАТНЫЙ ИНСТРУМЕНТ онлайн мониторинга производительности 1С.

Мы будем исследовать проблему на MS SQL Server, поэтому нам потребуются следующие сервисы из этого набора:

1. Мониторинг и анализ долгих запросов (подробнее о настройке читайте здесь http://www.gilev.ru/querytj/ ) — нужен для того чтобы оценить о наличии долгих операций к субд.

Анализ долгих запросов

Собственно факт их наличия позволяет говорить о том что проблемы с производительностью есть, и проблемы заключаются в строчках кода конфигураций 1С, который сервис проранжирует по важности. Проблемы в начале списка надо решать в первую очередь. Такие решения проблемных строк принесут наибольший эффект, т.е. будет больше всего пользы и толка для пользователей системы.

2. Анализ ожиданий на блокировках (подробнее читайте здесь http://www.gilev.ru/latch/ )  позволит нам оценить — а собственно вызвано ли время длительных (долгих) запросов ожиданием блокировок или есть другие причины (неоптимальный код, перегружено железо и т.п.) Сервис покажет причину возникновения ожидания запросом, а именно ресурс который был заблокирован и кто его заблокиовал. Т.е. мы поймем наличие проблем с блокировками и их причины.

Анализ ожиданий на блокировках

 

график интенсивности блокировок

 3. Анализ взаимных блокировок в 1С и MS SQL server ( подробнее о настройке читайте здесь http://www.gilev.ru/deadlock/ ) — позволит нам оценить более сложные ситуации с ожиданием ресурсов, когда несколько участников часть ресурсов уже успели «захватить» блокировкой и теперь вынуждены ждать вынуждены ждать друг друга из-за того, что они не могут освободить занятые ресурсы до завершения захвата других ресурсов, заблокированных соседями.

 

Вообщем в такой непростой ситуации вручную не разобраться, нужен такой сервис.

4. Контроль загруженности оборудования  ( подробнее о настройке читайте здесь http://www.gilev.ru/hardware/ ) помогает нам ответить на вопросы — сколько пользователей в системе, есть ли у них блокировки, как много блокировок, справляется ли железо с нагрузкой?

картина загруженности железа

 

Сервисы настраиваются очень легко, но даже если у вас все равно остались вопросы, есть специализированный форум где можно решить любой вопрос по настройке и использованию сервисов!

С помощью выше перечисленных инструментов мы обладаем объективной информации о производительности системы. Это позволяет нам правильно оценить ситуацию и предложить адекватные меры.

Фактически мы получаем информацию обо всех проблемах производительности и можем точно ответить на вопросы вроде «сколько проблем в системе», «где конкретно они возникают», «каждая из проблем с какой точно частотой возникает», «какие проблемы значимы, а какие второстепенны».  Т.е. мы видим все предпосылки, которые сформировали  причину  возникновения проблемы.

Сервисы позволяют существенно улучшить понимание условий возникновения проблем, не заставляя вручную копаться в таких вещах как структура хранения данных информационной базе на уровне СУБД, механизме наложения блокировок, уровней изоляций транзакций и т.д.

структура базы в разрезе проблемы нулевых строк итогов

В результате мы получим картину производительности которая измеряется

- время запроса (разумеется, отранжировав проблемные запросы по весу (время запроса на количество вызовов этого запроса);

- время ожидания блокировок;

- количество взаимных блокировок.

Итак, мы запустили сервис Анализ ожиданий на блокировках

Если Вы под демо учеткой work, выберите к примеру 15 апреля 2013 года для анализа.

период анализа

 

В верхней таблице сервис показывает список «жертв» блокировок с учетом суммарного веса «тяжести ожиданий».

В нижней таблице для каждый жертвы рассматриваются один или более участников «борьбы за высококонкуретный ресурс», где и возникло ожидание на блокировке.

Рабочая площадь сервиса 1с

В нижней таблице откройте детализацию по факту одного из событий «таймаута». Как например на картинке.

виновник блокировки

Подсветив строку с «виновником», мы увидим что узким местом стала таблица _Reference64, причем возникла проблема на кластерном индексе с областью «неизвестно». Возможно в будущем мы переименуем в «таблица», так как на самом деле такое поведение характерно для повышения/укрупнения области блокирования.

Жертва блокировки

Строка с «жертвой» показывает какой код оказался заложником ситуации и не смог заблокировать все навсего строку «по ключу» (минимальная область блокирования данных в этой таблице).

Решать эту проблему можно «правильно» и «по легкому».

По легкому — это воспользоваться знанием, что один из участников блокировки читает данные, при чем достаточно аккуратно. Значит прежде чем звать программистов и перелапачивать код можно применить «версионирование» в MS SQL Server. Как, вы первый раз слышите об этом, тогда читайте здесь http://www.gilev.ru/snapshot1c/ . Кроме того можно «запретить» большую часть эскалации (укрупнения) области блокирования данных. Этот прием также описан нами http://www.gilev.ru/escalation/ .

По правильному пути идти сложнее — фактически надо переписывать код, минимизируя вероятность возникновения подобных ситуаций.

Один из факторов как ни странно звучит — это уменьшение длительности транзакции.

Уменьшить длительность транзакции можно:

1. переписав алгоритм

2. переписав запрос (более быстрый запрос уменьшает вероятность блокировок в сложных транзакциях на таблицах, которых иногда даже может не быть в запросе!)

2.1 добавив отсутствующий покрывающий индекс (иногда индекс не только ускоряет запрос, но и уменьшает область чтения данных, что уменьшает вероятность блокирования)

3. уменьшив объем данных, обрабатываемый в тразакции (помимо линейной скорости помним еще про эскалацию блокировок)

4. увеличив производительность оборудования в рамках каждого потока

 

Время исполнения запроса

Как уже сказал в статье «Влияние оптимизатора запросов…» двумя наиболее вероятными причинами долгого ИСПОЛНЕНИЯ ЗАПРОСА являются отсутствующие индексы и сложность запроса. Однако время отклика пользователю состоит из ИСПОЛНЕНИЯ ЗАПРОСА и ОЖИДАНИЙ ЗАПРОСА. Посмотрим на вторую составляющую. Ожиданиями условно можно обозначить очереди к конкурентным ресурсам. Часть времении исполнения запросы могут ничего не делать (отсюда отсутствие загруженности железа), а просто ожидать своей очереди, когда будет снята блокировка с ресурса, который нужен запросу.

Можно ли отказаться от блокировок?

Блокировки – чрезвычайно важный и неотъемлемый механизм функционирования сервера. Они применяются для каждого запроса на чтение или обновления данных, а также во многих других случаях (например, при создании новой сессии).

Многопользовательская система - это компромисс:

1)  разные пользователи могут работать параллельно с разными данными
2)  разные пользователи должны работать строго последовательно с одними и теми же данными

Однако оптимизировать использование блокировок можно, тем самым уменьшив общее время ожидания.

Как работают блокировки (этот пункт можно не читать)

Работой с блокировками занимается специальный модуль SQL Server’а – менеджер блокировок (Lock Manager). В его задачи входит:

  • создание и установка блокировок;
  • снятие блокировок;
  • эскалация блокировок;
  • определение совместимости блокировок;
  • устранение взаимоблокировок (deadlocks) и многое другое.

Когда пользователь делает запрос на обновление или чтение данных, менеджер транзакций СУБД передает управление менеджеру блокировок СУБД для того, чтобы выяснить были ли блокированы запрашиваемые ресурсы, и, если да, совместима ли запрашиваемая блокировка с текущей. Если блокировки несовместимы, выполнение текущей транзакции откладывается до тех пор, пока данные не будут разблокированы. Как только данные становятся доступны, менеджер блокировок накладывает запрашиваемую блокировку, и возвращает управление менеджеру транзакций.

Основная причина, снижающая быстродействие – блокировки

Ожидания на блокировках являются основной проблемой быстродействия многопользовательского режима. И это понятно, ведь они увеличивают время ожидания операций, а значит и время отклика. Можно ли сказать, что ожидание на блокировках – это не правильно и ошибка многопользовательской системы? Так сказать нельзя, поскольку сам по себе механизм блокирования ресурсов обеспечивает целостность данных. С помощью механизма блокировок конкурентные данные ЗАПИСЫВАЮТСЯ ПОСЛЕДОВАТЕЛЬНО.

Разница между необходимыми и избыточными блокировками

Когда пользователь сообщает об ошибке ожидания на блокировке, то с его точки зрения это всегда ошибка, потому что она например мешает ему работать – увеличивается время выполнения его работы.

Опыт подсказывает нехитрое правило, если больше половины времени исполнения запроса он фактически ожидает заблокированный ресурс, то надо посмотреть: может быть можно часть блокировок получиться оптимизировать, уменьшить время блокирования ресурса.

Тут как бы невзначай ввожу определение:

Ожидание на блокировке – это ситуация, которая возникает в том случае, если два пользователя пытаются одновременно захватить одни и те же данные. При этом один из этих пользователей оказывается заблокированным, то есть должен ждать до окончания транзакции первого пользователя.

А транзакция — это множество вычислений и операций с данными (наиболее яркий пример — при проведении документа) , выполняемых как единое целое. Невыполнений любой из операции транзакции приводит к отмене транзакции целиком.

 

Итак,пользователи в многопользовательских информационных базах могут часто жаловаться, что невозможно работать из-за этих блокировок, при этом в коде действительно могут быть блокировки, которые в этом месте не нужны (избыточные).
А еще и в коде конфигурации они сами по себе блокировки могут не присутствавать, про них можно прочитать например здесь http://kb.1c.ru/articleView.jsp?id=30 (статья является фрагментом книги П.С.Белоусов, А.В.Островерх «1С:Предприятие: от 8.0 к 8.1″.). Предлагаю упрощенный способ объяснения различия блокировок на простом примере так:

В вашей конфигурации в режиме 1С:Предприятие создайте две одинаковых накладных с одинаковым составом товара. Но обязательно укажите различные склады поступления.
В коде обработки проведения надо добавить строчку с выводом на экран сообщения (или другой код, способный задержать исполнение обработки проведения на 21 секунду ( таймаут блокировки происходит через 20 секунд, если параметры по умолчанию)).
Проводите два документа.
Если возникает таймаут, а по логике товары приходят на разные склады, в приложении присутствуют избыточные блокировки. Бизнес – логике (считай по здравому смыслу) здесь блокировок не должно быть.
Если же мы теперь сделаем в этих двух накладных одинаковые склады. То созданные блокировки в результате попытки одновременного проведения приведут НЕОБХОДИМОЙ блокировке и это ХОРОШО!

Т.е. пока накладная вносит изменения в остатки на складе, другая должна подождать.

Конечно даже этот простой пример оставляет много вопросов. Например, а если документы от одного поставщика и «двигается» задолженность по нему. А если двигаются не одни остатки на складе, а несколько регистров, а документы разного вида.
Но самый главный вопрос – А ПО КАКОЙ ТАКОЙ БИЗНЕС-ЛОГИКЕ НЕ ДОЛЖНО БЫТЬ БЛОКИРОВОК. Кто эту бизнес – логику и где прописывает в контексте блокировок? Но довайте обо всем по порядку.

Избыточные блокировки – лишние – которые не нужны с точки зрения обеспечения целостности данных и при этом снижающие общую производительность системы, увеличивая общее время «простоя» — ожидания на блокировках.
Необходимая блокировка возникает при захвате двумя пользователями одних и тех же ресурсов (объектов данных). Если же пользователи работают с непересекающимися ресурсами, но при этом происходит ожидание на блокировке, то блокировка считается избыточной.

Наиболее понятными критериями избыточности блокировок обозначу:

1. Взаимные блокировки;

2. Уровень (область) блокировки выше необходимой (как частный случай повышения уровня блокировки, т.н. эскалация);

3. Время блокировки больше времени «реального» использования объекта блокировки.

Критерий взаимных блокировок настолько сильно оказывает негативное влияние, что выделен в наших сервисах в самостоятельный критерий производительности. Взаимные блокировки – всегда ошибочные блокировки. В отличии ожиданий на блокировках вцелом, факт существования взаимных блокировок говорит о наличии ошибок в коде. Парадокс в том, что полностью из кода убрать «взаимные» блокировки очень сложно. Проблема взаимных блокировок настолько сложна, поэтому я вынесу эту тему в отдельную статью http://www.gilev.ru/vzaimoblokirovka/.

Получив информацию о группировках проблем в разрезе метаданных 1С:Предприятие, рекомендую обратить внимание прежде всего на объектах:

  • Константы
  • Последовательность
  • Регистры бухгалтерии
  • Регистры накоплени
  • Регистры сведений
  • Регистры расчета

 

1) До не давнего времени была общеизвестная рекомендация в константы ничего не писать. В крайнем случаи делать это из под одного пользователя, и то помнит, что пока пользователь «пишет» одну константу, не только эту, но и любую другую константу другие пользователи будут «ждать». Поэтому особо опасно использовать констатны в обработке проведения. Значения всех констант хранятся в одном ресурсе.

Таблица с константами

На рисунке показано физическое размещение констант конфигурации УПП в таблице базы данных MS SQL Server 2005.

Это означает, что при блокировке одной константы будут заблокированы все константы. СУБД накладывает блокировку на ВСЮ единственную СТРОКУ таблицы, т.е. на все константы.

Однако в последних релизах платформы хранение констант изменено. Теперь каждая константа — это отдельная таблица. Правда сильно не увлекайтесь, если вы создадите тысячи таблиц, то можете словить блокировку на базе master.

Внимание, если у вас конфигурация существует давно, то изменить формат хранения можно путем «реструкторизации» в Тестировании и Исправлении конфигуратора.

2) Отказаться от использования объекта метаданных «Последовательность». Хотя бы от движений при оперативном проведении, проводить при неоперативном (допроведении). Смотрите, как реализовано в последних версиях УПП.

3) Если в системе осуществляется оперативная запись движений по бухгалтерскому регистру в многопользовательском режиме, то рекомендуется:

  • включить для данного регистра режим разделения итогов;
  • не использовать контроль остатков регистра при оперативной работе.

В последних версиях конфигурации бухгалтерии смотрите использование кода «управляемых» блокировок.

4) В регистре накопления в случаи отсутствия необходимости получить «оперативные» данные можно включить разделение итогов, что повысит параллельность записи данных и ускорит работу в целом. Внимательно следить за измерениями, чтобы «остатки» можно было получить максимальной детализацией по измерениям.

5) Избавиться от некоторых избыточных блокировок, создаваемых платформой можно только путем использования «управляемых» блокировок. В автоматическом режиме работы конфигураций платформа «берет на себя» блокирование ресурсов. Цена беззаботного использования автоматического режима — возможны блокировки на границах диапазонов индексов, блокировки пустой таблицы, эскалация блокировок.

 

Эти блокировки полностью исчезают при переходе в управляемый режим блокировки данных в транзакции. То есть, данная взаимоблокировка будет невозможна при работе в управляемом режиме.

Уже несколько раза произнес «управляемые блокировки», «управляемый режим». Надо понимать, что существует два вида блокировок:
Блокировки СУБД – устанавливаются автоматически на уровне СУБД при выполнении запросов.
Блокировки 1С:Предприятие – устанавливаются автоматически при записи (модификации) данных и всегда вручную при чтении данных.

Дотошный читатель скажет, что 1С делит еще на объектные и не объектные блокировки, но сейчас этот подход мы трогать не будем.

Зато отмечу, что использование «управляемых» блокировок накладывает больше требований квалификации и опыту 1С-специалиста.

6) Отсутствующие индексы (особенно в сложных запросах) это вообще основной фактор возникновения более выского уровня блокировок, чем необходимо. Т.е. парадокс, я с одной стороны говорил, что до оптимизации запроса говорил что сначала надо посмотреть на блокировки, а теперь говорю, чтобы оптимизировать блокировки — надо оптимизировать запрос. У меня есть оправдание, перевод конфигурации на управляемые блокировки уменьшает избыточные блокировки даже не в оптималном запросе. Это происходит по причине уменьшения уровня изоляции транзакций, что в свою очередь менеджеру блокировок СУБД дает меньше поводов наложить избыточную блокировку.

Основные причины избыточных блокировок (подитожим выше сказанное)

- ошибки проектирования
(степень параллельности определяется тем «насколько мелко нарезаны данные»: возможна параллельная работа с двумя строками таблицы, работа с одной строкой будет идти только последовательно)
(ошибки использования метаданных: запись констант, последовательностей, оперативный учет на регистрах бухгалтерии)
- избыточная блокировка по вине автоматическго режима (связка платформа — СУБД).
- неоптимальная работа запроса
(например при сканировании таблицы блокируется вся таблица – избыточная область
и увеличивается время блокировки – избыточное время, дополнительное количество блокировок увеличивает вероятность эскалации блокировки)

Как Вы видите задача оптимизации блокировок «многогранная». Нужно как можно лучше представлять «контекст», что спровоцировал проблему. На каких ресурсах, какой код. Насколько реально эта блокировка необходима, или она избыточна.

У ребенка и взрослого болит горло. Когда доктор задаст вопрос: «Что не так?», ребенок будет смотреть на доктора и кричать (верьте мне, я знаю), тогда как взрослый укажет на симптомы болезни.  Эти явное различие направляет доктора к разным методам идентификации проблемы.
С ребенком, доктор должен выполнить много тестов, собрать данные, объединить их, выполнить анализ и только затем дать рекомендации. Тогда как с взрослым, он задаст несколько вопросов и, поскольку число исходных данных невелико, время анализа и определения проблемы будет существенно меньше. Как результат, рекомендации будут выданы намного раньше.

Пользуйтесь нашими сервисами http://www.gilev.ru/online/ и у Вас появиться больше возможностей бесплатно проанализировать проблему и найти решение!