Вопросы по SQL и базам данных для собеседования. Некоторые из них касаются только Microsoft SQL Server, но большинство вопросов являются общими для всех реляционных СУБД.
Опросник доступен на github. Добавления и правки приветствуются.
В чем разница между операторами DELETE
и TRUNCATE
?
Информация
Операторы DELETE
и TRUNCATE
в SQL используются для удаления данных из таблицы.
DELETE
позволяет использовать условия с помощью WHERE
.
TRUNCATE
удаляет все данные из таблицы.
При DELETE
каждое удаление регистрируется в журнале транзакций, что увеличивает накладные расходы, но позволяет откатить операцию (если транзакция не завершена).
TRUNCATE
минимально регистрирует действия в журнале транзакций (только освобождение страниц), что делает его более эффективным. Фактически он удаляет таблицу и создает новую(зависит от СУБД).
TRUNCATE
в Sql Server cбрасывает счётчик IDENTITY
на начальное значение (если не используется SEED
). В Postgresql не сбрасывает.
DELETE
активирует триггеры, если они определены на таблице.
В чём разница между операторами union
и union all
? Какие ещё операторы существуют для работы со множествами?
Информация
UNION
Объединяет результаты двух или более запросов в один набор данных, удаляя дубликаты. Результат отсортирован.
UNION ALL
Объединяет результаты двух или более запросов в один набор данных без удаления дубликатов. Результат не отсортирован.
INTERSECT
Пересечение. Возвращает только те строки, которые присутствуют в результатах обоих запросов. Результат отсортирован.
EXCEPT
Исключение. Возвращает только те строки, которые присутствуют в результатах первого запроса, но отсутствуют во втором. Результат отсортирован.
Какие join
бывают и чем они отличаются?
Информация
Оператор join
используется для объединения данных из двух или более таблиц на основе определённого условия.
inner join
- возвращает только те строки, для которых условие соединения выполняется в обеих таблицах.left join
- возвращает все строки из левой таблицы и соответствующие строки из правой таблицы. Если соответствие не найдено, в правой таблице будут значенияNULL
.right join
- возвращает все строки из правой таблицы и соответствующие строки из левой таблицы. Если соответствие не найдено, в левой таблице будут значенияNULL
.full join
- возвращает все строки из обеих таблиц. Если соответствие не найдено, в недостающих столбцах будут значенияNULL
.cross join
- возвращает декартово произведение строк из обеих таблиц- self join - cоединение таблицы с самой собой. Используется, когда нужно сравнить строки внутри одной таблицы.
Алгоритмы реализации join
Наводящие вопросы
join
это логический оператор(декларация), какие физические операторы использует СУБД? Что видим в плане запроса?- есть два массива объектов, на любом языке программирования, как их объединить по каким то полям? Без готовых решений в языке.
Информация
В SQL Server и других СУБД для выполнения операций соединения (JOIN
) используются три основных алгоритма: Nested Loops Join, Hash Join и Merge Join. Каждый из них оптимизирован для определённых сценариев работы с данными.
Nested Loops Join (Вложенные циклы)
Как работает:
- Использует два вложенных цикла:
- Внешний цикл проходит по строкам первой (внешней) таблицы.
- Внутренний цикл для каждой строки внешней таблицы ищет совпадения во второй (внутренней) таблице.
- Часто использует индексы внутренней таблицы для быстрого поиска совпадений.
Когда применяется:
- Когда одна из таблиц маленькая, а вторая имеет индекс на ключе соединения.
- Для соединений с условиями неравенства (например,
a.id < b.id
), если нет сортировки данных.
Плюсы:
- Низкие накладные расходы на старт.
- Эффективен для маленьких таблиц или при наличии индексов.
Минусы:
- Медленно работает, если обе таблицы большие и нет индексов.
- Сложность:
O(N*M)
, где N и M — размеры таблиц.
Hash Join (Хеш-соединение)
Как работает:
- Фаза построения(Build): Создаёт хеш-таблицу для одной из таблиц (обычно меньшей), где ключ — значение столбца соединения.
- Фаза проверки(Probe): Для каждой строки второй таблицы вычисляет хеш и ищет совпадения в хеш-таблице.
- Если хеш-таблица не помещается в память, используется диск, что замедляет процесс (Grace Hash Join).
Когда применяется:
- Для больших таблиц без индексов.
- Когда нужно обработать много данных и условие соединения — равенство (
=
).
Плюсы:
- Эффективен для больших несортированных данных.
- Сложность:
O(N+M)
в лучшем случае.
Минусы:
- Требует много памяти.
- Не работает для условий неравенства (например,
>
или<
).
Merge Join (Слияние)
Как работает:
- Обе таблицы должны быть отсортированы по ключу соединения (если нет — выполняется сортировка, что затратно).
- Проходит по обеим таблицам одновременно, как в алгоритме сортировки слиянием:
- Указатели двигаются от начала к концу, сравнивая ключи.
- При совпадении ключей строки объединяются.
Когда применяется:
- Когда обе таблицы уже отсортированы (например, есть кластеризованный индекс).
- Для соединений с условиями равенства, больше/меньше (
=
,>
,<
). - Для больших таблиц, если данные отсортированы.
Плюсы:
- Очень быстр, если данные отсортированы.
- Сложность:
O(N+M)
.
Минусы:
- Если данные не отсортированы, сортировка требует времени и памяти.
- Неэффективен для неравенств, если данные не подготовлены.
Что такое индекс? Какие индексы есть в Sql Server?
Информация
В SQL Server индексы используются для ускорения поиска и обработки данных. Они реализованы как структуры данных, которые позволяют быстро находить строки в таблице по заданным критериям.
Кластеризованный индекс (Clustered Index)
- Определяет физический порядок хранения данных в таблице.
- Таблица может иметь только один кластеризованный индекс.
- Если индекс не создан, данные хранятся в неупорядоченной куче (Heap).
- Структура B+-дерева
- Корневые и промежуточные узлы хранят ключи для навигации.
- Листовые узлы — страницы данных таблицы.
Некластеризованный индекс (Non-Clustered Index)
- Структура B-дерева, аналогичная кластеризованному индексу, но без переупорядочивания данных таблицы.
- Таблица может иметь до 999 некластеризованных индексов
- Листовые узлы содержат ключи индекса и указатели на данные (RID — для кучи, кластеризованный ключ — для таблиц с кластеризованным индексом).
Уникальный индекс (Unique Index)
- Гарантирует уникальность значений в индексируемых столбцах.
- Может быть как кластеризованным, так и некластеризованным.
- Запрещает дубликаты значений (включая
NULL
, если столбец не допускаетNULL
).
Составной индекс (Composite Index)
- Индекс по нескольким столбцам.
- Порядок столбцов важен: запросы должны использовать префиксные столбцы индекса.
Покрывающий индекс (Covering Index)
- Включает все столбцы, необходимые для выполнения запроса, чтобы избежать обращения к таблице.
- Использует ключевые столбцы и включенные столбцы (
INCLUDE
).
Фильтрованный индекс (Filtered Index)
- Оптимизирован для работы с подмножеством данных (например, часто запрашиваемые строки).
- Создается с условием
WHERE
, которое фильтрует данные. - Меньший размер и высокая производительность для определенных запросов.
Columnstore индекс
- Оптимизирован для аналитических запросов (OLAP) с агрегацией больших объемов данных.
- Хранит данные в колоночном формате, а не построчно.
- Эффективен для операций
GROUP BY
,SUM
,AVG
.
XML и JSON индексы
- Ускорение работы с XML- и JSON-данными.
Какие операции доступа к данным можно увидеть в плане запроса? Что про них можно сказать?
Наводящие вопросы
- Например Index Seek или Table Scan, в чем разница?
Информация
В SQL Server Index Seek, Table Scan и другие операции — это физические операции, которые выполняются для доступа к данным при выполнении запросов. Они отражают, как SQL Server получает данные из таблиц и индексов.
Index Seek
SQL Server использует индекс для поиска конкретных строк. Это операция, при которой оптимизатор “переходит” к нужным данным через структуру B-дерева индекса.
Index Scan
SQL Server сканирует весь индекс (все его страницы) для поиска данных.
Table Scan
SQL Server сканирует всю таблицу (все её страницы) для поиска данных.
Clustered Index Seek
SQL Server использует кластеризованный индекс для поиска конкретных строк.
Clustered Index Scan
SQL Server сканирует весь кластеризованный индекс (все его страницы).
Key Lookup (Bookmark Lookup)
SQL Server использует некластеризованный индекс для поиска строк, но затем обращается к кластеризованному индексу или куче для получения остальных данных.
RID Lookup
SQL Server использует некластеризованный индекс для поиска строк, но затем обращается к куче (Heap) по идентификатору строки (RID).
Что такое селективность и почему ее важно учитывать?
Наводящие вопросы
- чем отличается столбец
Gender
иPhoneNumber
?
Информация
Селективность в базах данных — это мера уникальности значений в столбце или комбинации столбцов. Она показывает, насколько эффективно индекс может фильтровать данные при выполнении запросов. Селективность напрямую влияет на производительность индексов и выбор оптимального плана выполнения запросов.
Селективность определяется как отношение количества уникальных значений в столбце к общему количеству строк в таблице.
- Высокая селективность: Столбец содержит много уникальных значений (близко к 1).
Пример:Email
,ID
,PhoneNumber
. - Низкая селективность: Столбец содержит мало уникальных значений (близко к 0).
Пример:Gender
,Status
,IsActive
.
Почему селективность важна для индексов?
- Высокоселективные индексы позволяют быстро находить нужные строки, так как они сокращают количество данных для сканирования.
- Оптимизатор SQL Server использует статистику по индексам, включая селективность, чтобы выбрать оптимальный план выполнения запроса.
- Если индекс имеет низкую селективность, оптимизатор может решить, что сканирование таблицы (Table Scan) будет быстрее, чем использование индекса (Index Seek).
- Если отдельный столбец имеет низкую селективность, добавьте к нему высокоселективные столбцы.
Что такое SARG предикаты?
Наводящие вопросы
- Будет ли работать индекс если к столбцу применить функцию или использовать
like
?
Информация
SARG-предикаты (Search ARGument) в SQL Server — это условия в запросах, которые могут эффективно использовать индексы для поиска данных. Правильное использование SARG-предикатов позволяет SQL Server выполнять операции Index Seek (поиск по индексу) вместо Index Scan (полное сканирование индекса), что значительно ускоряет выполнение запросов.
Как сделать предикат SARG-совместимым?
Избегайте функций, вычислений и LIKE
с начальным %
для индексированных столбцов.
Это же относится и к приведению типов, особенно часто проблемы возникают с varchar
. Поиск по аргументу с типом nvarchar
или N’привет’ работать не будет. Если у вас в БД тип varchar
и вы используете какую либо ORM, то нужно этот момент предусмотреть.
В композитных индексах ситуация аналогичная, необходимо следить за первым столбцов в индексе.
Избегайте функций и вычислений с индексированными столбцами
Вместо:
SELECT * FROM Employees WHERE YEAR(HireDate) = 2023;
Используйте:
SELECT * FROM Employees
WHERE HireDate >= '2023-01-01' AND HireDate < '2024-01-01';
Используйте LIKE
с начальным символом
Вместо:
SELECT * FROM Customers WHERE LastName LIKE '%son';
Используйте:
SELECT * FROM Customers WHERE LastName LIKE 'son%';
Переносите вычисления на другую сторону условия
Вместо:
SELECT * FROM Orders WHERE TotalAmount * 1.1 > 1000;
Используйте:
SELECT * FROM Orders WHERE TotalAmount > 1000 / 1.1;
Что такое статистика в Sql Server и зачем она нужна?
Информация
Статистика в SQL Server — это объекты базы данных, которые хранят информацию о распределении значений в столбцах таблиц и индексов. Эти данные используются оптимизатором запросов для построения оптимальных планов выполнения запросов. Статистика помогает оценить, сколько строк будет обработано на каждом этапе запроса, и выбрать наиболее эффективные операции (например, Index Seek вместо Table Scan).
Статистика в SQL Server — это ключевой элемент оптимизации запросов.
Оптимизатор SQL Server анализирует статистику, чтобы определить:
- Какой индекс использовать.
- В каком порядке соединять таблицы.
- Использовать ли параллельное выполнение.
- Оценить стоимость операций (например, сортировку или фильтрацию).
- Статистика позволяет предсказать, сколько строк будет возвращено после применения условий
WHERE
,JOIN
,GROUP BY
и других операций.
Статистика хранит следующие данные
- Гистограмма (Histogram): Показывает распределение значений в первом ключевом столбце индекса.
- Каждый шаг (step) гистограммы содержит диапазон значений и их частоту.
- Максимальное количество шагов — 200 (для больших таблиц данные усредняются).
- Плотность (Density): Вероятность уникальности комбинации столбцов.
- Рассчитывается как
1 / количество уникальных значений
.
- Рассчитывается как
- Количество строк (Number of Rows): Общее число строк в таблице на момент создания статистики.
- Количество уникальных значений (Number of Distinct Values).
Как создается и обновляется статистика?
- SQL Server автоматически создает статистику для индексированных столбцов и столбцов, участвующих в условиях запросов (если включена опция
AUTO_CREATE_STATISTICS
). - Статистика обновляется автоматически при изменении данных, если превышен порог изменений:
- Пустая таблица → после вставки любой строки.
- Менее 500 строк → после изменения 500 строк.
- Более 500 строк → после изменения 20% строк + 500 строк.
- Опция
AUTO_UPDATE_STATISTICS
управляет этим поведением.
- Команда
UPDATE STATISTICS
В чем отличие временной таблицы и табличного типа?
Информация
Временные таблицы (#table
) и табличные переменные (DECLARE @table TABLE
) в SQL Server служат для временного хранения данных, но имеют принципиальные различия в реализации и производительности.
Временная таблица (#table
)
Временные таблицы предпочтительны для работы с большими данными, сложными запросами и операциями, требующими оптимизации через индексы.
- Создается в базе данных
tempdb
(как физическая таблица). - Данные хранятся на диске (хотя могут кэшироваться в памяти).
- Поддерживает индексы, статистику, ограничения (PK, FK, CHECK) и триггеры.
- Может участвовать в транзакциях (откатывается при
ROLLBACK
). - Видима в рамках текущей сессии или хранимой процедуры (включая вложенные процедуры).
##table
доступна для всего инстанса- Удаляется автоматически при закрытии сессии или явно через
DROP TABLE
. - Оптимизатор SQL Server использует статистику для построения эффективного плана выполнения.
Табличная переменная (@table
)
Табличные переменные подходят для временного хранения небольших данных и упрощенных сценариев.
- Хранится в оперативной памяти (но при нехватке памяти может быть выгружена в
tempdb
). - Не поддерживает индексы (кроме первичного ключа и уникальных ограничений)
- Нет статистики. Оптимизатор предполагает, что таблица содержит 1 строку (если не указано
OPTION (RECOMPILE)
). - Не участвует в транзакциях (изменения не откатываются при
ROLLBACK
). - Видима только в текущем пакете (например, внутри одной хранимой процедуры или скрипта).
- Удаляется автоматически после завершения выполнения пакета.
Что такое транзакция?
Информация
Логическая единица объединяющая несколько операций с БД.
Какие модели транзакций в БД знаете?
Информация
ACID и BASE.
Что такое ACID?
Информация
Набор требований к транзакционной системе.
Атомарность (Atomicity)
Набор операций в рамках транзакции выполняются как single unit of work. Все операции выполняются полностью и фиксируются(commit) или все изменения откатываются(rollback).
Согласованность (Consistency)
Транзакция переводит базу данных из одного согласованного состояния в другое, сохраняя её целостность.
На уровне базы данных можно создавать ограничения целостности (integrity constraints).
Но не все условия согласованности данных может гарантировать СУБД, например если условия охватывают сразу несколько таблиц. Тогда гарантом согласованности выступает приложение.
Изолированность (Isolation)
Параллельные транзакции не влияют друг на друга. Результаты одной транзакции не видны другим до её завершения.
Механизмы синхронизации выполнения параллельных транзакций.
Долговечность (Durability)
Гарантия того, что если транзакция успешно зафиксирована, то изменения не будут потеряны.
Что такое BASE?
Информация
Модель BASE — это альтернативный подход к проектированию распределённых систем и баз данных, который противопоставляется классической модели ACID. BASE акцентирует внимание на высокой доступности и масштабируемости, жертвуя строгой согласованностью данных. Эта модель часто используется в NoSQL-системах и облачных хранилищах, где важна обработка больших объёмов данных в реальном времени.
Basically Available (Базовая доступность)
Система гарантирует доступность данных даже в условиях частичных сбоев (например, при отказе узлов сети). Запросы к данным всегда получают ответ, который может быть неполным или устаревшим, но система продолжает работать.
Soft state (Гибкое состояние)
Состояние данных может меняться со временем даже без внешних операций (например, из-за фоновой синхронизации между узлами). Система не гарантирует мгновенной согласованности между репликами.
Eventual consistency (Согласованность в конечном счёте)
Если в систему не вносятся новые изменения, через некоторое время все узлы придут к согласованному состоянию. Однако в момент выполнения операций данные могут быть временно несогласованными.
ACID гарантирует целостность и точность данных, а BASE обеспечивает доступность и масштабируемость.
Какие ограничения целостности (integrity constraints) можно использовать для согласованности (consistency)?
Информация
NOT NULL
- Гарантирует, что столбец не может иметьNULL
-значениеUNIQUE
- Гарантирует, чтобы все значения в столбце будут уникальнымиPRIMARY KEY
- КомбинацияNOT NULL
иUNIQUE
. Уникальный идентификатор строки.FOREIGN KEY
- Обеспечивает ссылочную целостность между таблицами.CHECK
- Гарантирует, что значения в столбце удовлетворяют определенному условиюDEFAULT
- Устанавливает значение по умолчанию для столбца, если значение не указано.
За счет чего БД может гарантировать Долговечность (Durability)?
Наводящие вопросы
- Зачем нужен Журнал транзакций(Transaction Log) в Sql Server или Журнал предзаписи(Write-Ahead Log) в других СУБД?
Информация
Принцип WAL заключается в том, что все изменения данных сначала записываются в журнал, а только потом применяются к самой базе данных. Это гарантирует, что в случае сбоя изменения могут быть восстановлены из журнала.
В случае аварийного завершения работы СУБД журнал позволяет восстановить данные до согласованного состояния. Это достигается за счёт повторения (redo) завершённых транзакций и отмены (undo) незавершённых.
Для чего еще нужен журнал транзакций?
Информация
Журнал используется для создания резервных копий и восстановления базы данных до определённого момента времени (Point-in-Time Recovery).
В распределённых системах журнал может использоваться для синхронизации данных между узлами (например, в репликации или шардинге).
Какие могут быть проблемы с усечением журнала?
Информация
SQL Server не может усечь журнал транзакций и повторно использовать его пространство. В этих случаях файл журнала продолжает увеличиваться, пока не заполнит весь диск.
Причину можно посмотреть в log_reuse_wait_desc
в представлении sys.databases
.
LOG_BACKUP
— одно из наиболее распространенных ожиданий в базах данных с моделями восстановленияFULL
иBULK-LOGGED
. Оно обозначает, что журнал не может быть усечен из-за отсутствия последних резервных копий журнала транзакций.ACTIVE_TRANSACTION
указывает на то, что журнал не удается усечь из-за старой незавершенной транзакции.AVAILABILITY_REPLICA
обычно возникают при определенных проблемах в группах доступности: например, когда вторичный узел недоступен, репликация между узлами запаздывает или вторичные реплики не успевают воспроизводить изменения со скоростью нагрузки.DATABASE_MIRRORING
возникает в системах, где используется технология зеркального отображения баз данных.REPLICATION
возникает, когда агент чтения журнала запаздывает, собирая записи журнала для процессов репликации транзакций или отслеживания измененных данных (CDC).
Что такое блокировки (locks)?
Информация
Блокировки (locks) в SQL Server используются, чтобы обеспечивать согласованность транзакций и требования к изоляции данных. Блокировки не позволяют обновлять одни и те же данные сразу нескольким транзакциям.
Блокировки устанавливаются и удерживаются на ресурсах, таких как строки данных, страницы, разделы, таблицы (объекты) и базы данных.
Что такое deadlocks? Почему возникают?
Информация
Взаимная блокировка — это особый случай блокирования, когда несколько сеансов или несколько потоков выполнения в рамках одного сеанса блокируют друг друга. Когда это происходит, SQL Server принудительно завершает одну из транзакций, чтобы остальные могли продолжить выполнение.
Уровни изоляции транзакций в SQL Server
Информация
Уровень изоляции определяет, как транзакции взаимодействуют с данными при параллельном выполнении. SQL Server поддерживает стандартные уровни изоляции ANSI, а также дополнительные режимы, такие как Snapshot и Read Committed Snapshot.
Каждый уровень решает определённые проблемы(аномалии) параллелизма.
Разница между стандартными уровнями изоляции в значительной степени объясняется количеством необходимых для их реализации блокировок.
Read Uncommitted (Чтение незафиксированных данных)
Аномалия грязного чтения (dirty read) возникает, когда транзакция читает еще не зафиксированные изменения, сделанные другой транзакцией.
- Не устанавливает блокировок на чтение.
Read Committed (Чтение зафиксированных данных)
Аномалия неповторяющегося чтения (non-repeatable read) возникает, когда транзакция читает одну и ту же строку два раза, а в промежутке между чтениями вторая транзакция изменяет (или удаляет) эту строку и фиксирует изменения. Тогда первая транзакция получит разные результаты.
- Блокировка на запись (X-lock) удерживается до конца транзакции.
- Блокировка на чтение (S-lock) снимается сразу после чтения.
Repeatable Read (Повторяемое чтение)
Аномалия фантомного чтения (phantom read) возникает, когда одна транзакция два раза читает набор строк по одинаковому условию, а в промежутке между чтениями другая транзакция добавляет строки, удовлетворяющие этому условию, и фиксирует изменения. Тогда первая транзакция получит разные наборы строк.
- Блокировка на чтение (S-lock) удерживается до конца транзакции.
Serializable (Сериализуемость)
Уровень Serializable должен предотвращать любые аномалии. Это означает, что на таком уровне разработчику приложения не надо думать об изоляции. Если транзакции выполняют корректные последовательности операторов, работая в одиночку, данные останутся согласованными и при одновременной работе этих транзакций.
- Блокировка диапазонов ключей (Key-Range locks) для предотвращения фантомных записей.
Snapshot (Снимок данных)
Этот уровень изоляции обеспечивает согласованность на уровне транзакций. Сеансы работают со снимком данных (data snapshot) на момент начала транзакции. Они не видят никаких изменений данных, зафиксированных после этого момента.
Не возникает блокирования между операциями чтения и записи; операции чтения не устанавливают совмещаемые блокировки. Кроме того, значительно уменьшается блокирование между операциями записи, потому что они не устанавливают блокировки обновления, а вместо этого используют записи из хранилища версий во время просмотра обновлений.
Read Committed Snapshot (RCSI)
Оптимистичная версия уровня Read Committed. Чтение данных через снимок на момент начала запроса.
Запросы SELECT
не устанавливают блокировок (S) и читают записи «старой» версии, а не блокируются из-за несовместимости блокировок (S)/(X).
Для операций записи ничего не меняется: как и на пессимистичных уровнях изоляции, запросы на изменение данных по-прежнему устанавливают блокировки (U) и (X) и могут блокировать друг друга.
Управление параллелизмом. Оптимистичное и Пессимистическое.
Информация
Пессимистическое управление
Пессимистическая блокировка (pessimistic locking) запрещает любые изменения данных другими запросами до завершения текущей транзакции.
Уровни изоляции Read Committed, Repeatable Read, Serializable.
Пессимистическая блокировка подходит для систем с высокой конкурентной нагрузкой, где критически важно предотвратить потерю данных. Например, она эффективна в банковских системах, где проводятся финансовые транзакции.
Оптимистичное управление
Оптимистическая блокировка исходит из предположения, что конфликты случаются редко. Она не блокирует данные, но проверяет, изменились ли они с момента чтения до записи.
Уровни изоляции Snapshot и Read Committed Snapshot.
- Версионирование строк (хранятся в tempdb).
- При конфликте обновления возникает ошибка Update Conflict.
Оптимистическая блокировка лучше справляется с задачами, где конфликты случаются редко. Например, ее выгодно использовать для приложений с низкой вероятностью одновременного изменения одних и тех же записей, обеспечивая более высокую доступность и производительность.
Что важно знать и учитывать разработчику приложений при работе с разными уровнями изоляции?
Информация
При пессимистическом подходе(Read Committed, Repeatable Read, Serializable) транзакция может на долго быть заблокирована. Нужно учитывать таймаут драйвера. У ADO.NET по дефолту 30сек. Еще возможно ошибки с deadlock.
При оптимистичном подходе(Snapshot, Read Committed Snapshot) будут возникать ошибки Update Conflict. Нужно предусмотреть механизмы повторных выполнений(retry).
Комментарии в Telegram-группе!