Неблокирующие запросы¶
Ситуации возможных блокировок¶
При работе с распределенными SQL-запросами следует принимать в расчет следующие факторы:
- SQL-запрос может вызывать значительные задержки и блокировать транзакционный поток, что будет мешать выполнению других запросов
- SQL-запрос не должен приводить к исчерпанию памяти на отдельных узлах кластера
- при объединении результатов локальных запросов в виртуальную таблицу на узле-маршрутизаторе нужно следить, чтобы эта таблица не разрасталась бесконтрольно
Включение неблокирующего режима¶
Неблокирующий режим выполнения SQL позволяет длительно выполняющимся запросам передавать управление планировщику, предотвращая блокировку event loop и обеспечивая выполнение других задач на экземпляре. По умолчанию неблокирующий режим отключен.
Включение и отключение режима выполняется с помощью параметра sql_preemption.
Интервал кооперативных переключений настраивается параметром sql_preemption_interval_us (в микросекундах). Меньшие значения повышают отзывчивость event loop, но увеличивают накладные расходы на переключения. Большие значения снижают накладные расходы, но могут ухудшать отзывчивость при выполнении длительных запросов.
Примеры¶
ALTER SYSTEM SET sql_preemption = true; -- включить
ALTER SYSTEM SET sql_preemption_interval_us = 500; -- интервал 500 мкс
Как это работает¶
В потенциально долгих участках выполнения запроса (на координаторе и узле хранения)
периодически вызывается «кооперативная» передача управления (yield), если
с момента последнего переключения прошло не менее sql_preemption_interval_us.
Внутри интерпретатора локального SQL (VDBE) задействован callback, который может передать управление планировщику при достижении заданного интервала.
Важно
Внутри явной локальной транзакции VDBE не делает yield, чтобы не нарушать атомарность.
На стороне исполнителя DML при необходимости допускается разбиение длинной модификации данных на несколько атомарных шагов: перед yield текущие изменения атомарно фиксируются, после возврата начинается фиксация новой партии данных. Это позволяет разгрузить event loop, сохранив прогресс выполнения.
Ограничения и семантика¶
При неблокирующем выполнении длительные DML могут быть применены несколькими шагами. Это повышает отзывчивость узла, но может изменить гранулярность атомарности по сравнению с единственной большой фиксацией. Планируйте обработку ошибок и повторов с учетом возможных частичных применений.
Неблокирующий режим не отменяет ограничений на ресурсы и объем промежуточных данных; используйте параметры из раздела ниже для защиты кластера.
Параметры для ограничения запросов¶
Чтобы избежать чрезмерной нагрузки и роста промежуточных данных, используйте
следующие параметры (через OPTION(...) в запросах):
SQL_VDBE_OPCODE_MAX, ограничение на максимальное количество команд при исполнении локального плана виртуальным движком базы данных (VDBE) на экземпляре кластера.SQL_MOTION_ROW_MAX, ограничение на максимальное число строк в промежуточной виртуальной таблице, собирающей результаты отдельных локальных запросов.
Параметр SQL_VDBE_OPCODE_MAX ограничивает счетчик команд при исполнении
скомпилированного запроса из
опкодов в VDBE-машине (число команд
прямо пропорционально числу опкодов). Ограничение влияет на количество
обработанных кортежей локальным SQL на узлах кластера в DQL-запросах и
позволяет предотвратить выполнение SQL-команды в тех случаях, если
запрашиваемая таблица слишком велика. Это может сигнализировать
пользователю о необходимости переделать запрос (например, отказаться от
полного сканирования (SELECT * ...) такой таблицы в пользу выборке
данных по индексу).
См. также:
Примеры¶
Тестовые таблицы
Примеры использования команд включают в себя запросы к тестовым таблицам.
Пример совместного использования SQL_VDBE_OPCODE_MAX и SQL_MOTION_ROW_MAX:
SELECT * FROM warehouse OPTION(SQL_VDBE_OPCODE_MAX = 30, SQL_MOTION_ROW_MAX = 5);
+----+----------+---------+
| ID | ITEM | TYPE |
+=========================+
| 1 | "bricks" | "heavy" |
|----+----------+---------|
| 2 | "bars" | "light" |
|----+----------+---------|
| 3 | "blocks" | "heavy" |
|----+----------+---------|
| 4 | "piles" | "light" |
|----+----------+---------|
| 5 | "panels" | "light" |
+----+----------+---------+
(5 rows)
Если ограничения не позволяют выполнить запрос, то будет возвращена ошибка.
При меньших значениях SQL_VDBE_OPCODE_MAX:
---
- null
- ("Reached a limit on max executed vdbe opcodes. Limit: XX\")
...
При слишком низком значении SQL_MOTION_ROW_MAX:
---
- null
- (Exceeded maximum number of rows (4) in virtual table: Х\")
...