Search
Write a publication
Pull to refresh
3
0
Олег Юрченко @yurchenko_oleg

Разработчик приложений.

Send message

В MS SQL Server AlwayOn Availability долгий запрос на вторичном узле может заблокировать синхронизацию, общая нагрузка небольшая, но синхронизация не идёт. Возможно, у вас что-то подобное.

«Почему запросы на чтение должны меньше потреблять ресурсов из за того что база весит меньше?»  

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

Предъявить какие-то подробности о влиянии нагрузки процессоров, оперативной памяти и дисков на вторичном узле кластера отказоустойчивости без разделяемых ресурсов на процесс синхронизации вторичного узла?! Это каким образом будет происходить эта синхронизация, если нет ни процессоров, ни оперативной памяти и дисков, всё занято выполнением запросов на чтение данных?! Синхронизация будет стоять и ждать освобождения ресурсов. Это ваш случай. «Чтобы все реплики смогли догнать мастер и применить накопившиеся транзакции, flow control останавливает запись в мастере вовсе...». Это касается всех кластеров отказоустойчивости без разделяемых ресурсов всех производителей. MS SQL Server Availability Groups отваливается примерно так же. Нельзя нагружать вторичные узлы чрезмерной нагрузкой, это общее правило.

Рассмотрим крайний/граничный случай, когда в кластере отказоустойчивости без разделяемых ресурсов всего два сервера и кластер используется по своему прямому назначению для отказоустойчивости. В этом случае резервный сервер нагружать запросами нельзя совсем. Это чтобы при поломке любого сервера оставшийся сервер мог гарантированно выдержать нагрузку пока не подъедет замена. В этом граничном случае нагрузка на вторичный узел будет намного меньше нагрузки первичного узла, угрожать процессу синхронизации могут только какие-то внезапно приключившиеся проблемы типа выхода из строя какого-то оборудования.

У вас не этот случай, кластер отказоустойчивости без разделяемых ресурсов используется не для отказоустойчивости, а для распределения нагрузки и вторичный узел нужен для выполнения запросов на чтение данных. И эта нагрузка на чтение оказалась чрезмерной, не стало хватать ресурсов для синхронизации и пошли проблемы. Сначала проблемы возникают редко, потом чаще, а потом и вообще всё может остановиться, если не принять какие-то срочные меры. В вашем случае было достаточно почистить базу данных от ненужных старых данных. Как это повлияло? Таблицы стали сильно меньше. Реплика – это копия, если удалить данные в основной базе, то и на реплике удалятся. Запросы на чтение стали потреблять меньше ресурсов, ресурсов стало хватать, проблемы синхронизации решены. Вы просто вернулись к состоянию на сколько-то месяцев/лет назад, когда данных было меньше и проблем не было.

Похоже, что проблемы с производительностью наступили по причине большого объёма данных. Не только большое количество изменений данных мешает синхронизации реплик, но и нагрузка самих реплик запросами. Достаточно дать на реплику слишком большую нагрузку запросами, и синхронизация сломается.

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

Не надо было делать недостаточно продуманные и протестированные изменения на production. Привезли некоторые проблемы с согласованностью данных и доставили неприятности бизнесу и клиентам («но были потери в заказах»).

Есть ещё внешний контроль транзакций, когда транзакцию контролирует приложение и приложение решает судьбу транзакции. Это самый часто используемый вариант.

Контроль выполнения транзакций бывает внешний и внутренний.
Внутренний - это когда вся транзакция находится внутри хранимой процедуры (ну и может другие хранимые процедуры вызывать). Все проверки правил внутри хранимых процедур.
Так вот. Выполнение транзакции на стороне СУБД - это про внутренний контроль. Т.е. вызвана хранимая процедура и в ней работает транзакция. И все проверки внутри хранимых процедур.

Где я такое написал: "что когда транзакция выполняется на стороне бд, консистентность проверяется также приложением, а не только бд"?!

Не приписывайте мне лишнего.

Ваше: "Транзакции это прерогатива базы данных.".

Вам надо пройти тему транзакций.

Транзакции надо изучать по учебникам, а не по Клеппману. Читайте Дейта!

Долго отвечать, это не формат комментариев. У Дейта тема транзакций разбита на две главы. Это самый авторитетный учебник, там всё правильно по теории.

Вам нужен учебник. Рекомендую этот: "Дейт К.Д. Введение в системы баз данных."

ACID - свойства транзакций. Транзакции реализовывают программисты, а выполняются транзакции на СУБД. Не надо ACID делить на свойства СУБД и приложений.

Не только о внешних ключах и констрейнтах бд (но в том числе и о них). Правила могут быть какие-угодно. Если правило на данные нельзя определить на уровне базы данных, то его реализует программист, пишет нужный код под свою ответственность.  

Причём, не всегда правила на данные зависят от области деятельности. У компаний-конкурентов могут быть разные правила работы и разные требования к данным. Что разработчикам приложения закажут, то программисты и сделают. Какие транзакции в приложении нужны, такие и будут.

Правила на данные - свойства приложений. Да и сами транзакции зависят от приложения, программисты их реализовывают, когда приложение делают. Делить свойства ACID на свойства СУБД и приложений не надо. Правила на данные частично задаются ограничениями целостности, а частично реализуются программистами, и куда их отнести :)

Какие сложные сценарии? У "кабанчика" уровень сложности для студентов, причём главы про репликацию и транзакции студентам читать нежелательно, чтобы потом не переучиваться. Рецензенты должны были помочь Клеппану доработать эти главы. Могли бы ещё посоветовать написать про альтернативы секционированию. Глава про секционирование написана хорошо. Но в книге нет альтернатив. И это плохо для учебника. Из-за незнания альтернатив ученики могут применять секционирование там, где оно неуместно.

В моей статье только вступительная часть, старинный способ физического проектирования баз данных для оптимизации нагрузки на сервер и комментарии к трём главам "кабанчика". И никаких сценариев, только поясняющие примеры. Каждый пример поясняет какую-то идею или её полезность. Все примеры тут вторичны по отношению к идеям.

Для слабого сервера и такой объём большой. Тут не Uber, труба пониже - дым пожиже. И необходимость привлекательных условия для авиакомпаний и перевозчиков делает рентабельность бизнеса непривлекательной для собственников. Экономия на всём и раз в три года развлечение "продать слона".

Information

Rating
Does not participate
Location
Новосибирск, Новосибирская обл., Россия
Date of birth
Registered
Activity

Specialization

Application Developer, Database Developer
Lead
From 350,000 ₽
Designing application architecture
Database design
Software development
Database
Microsoft SQL Server
SQL
.NET
C#
Python