Spill-файлы
Обзор
Spill-файлы (также известные как work-файлы) создаются на диске, если оперативной памяти становится недостаточно для хранения временных данных, формируемых при выполнении запросов к БД. Временные данные могут включать в себя хеши JOIN
, результаты сортировки, перераспределенные таблицы и так далее. Директорию для хранения spill-файлов можно определять с помощью серверного конфигурационного параметра temp_tablespaces.
Поскольку spill-файлы хранятся на жестком диске, а скорость чтения/записи данных для дисков значительно ниже по сравнению с RAM — общее время выполнения запросов возрастает. Это может также привести к увеличению очередей на получение ресурсов со стороны других пользователей. В идеальном случае запросов, формирующих spill-файлы, быть не должно. Однако небольшое количество spill-файлов допускается. Фактически они обеспечивают выполнение запросов, несмотря на ограниченный размер RAM. Но стоит избегать запросов, формируюших избыточное число spill-файлов.
Существует несколько типовых ситуаций, когда возможна генерация большого количества spill-файлов:
-
В системе присутствует skew данных. Как избежать этого, можно узнать в разделе Рекомендации по равномерному распределению данных.
-
Объем памяти, выделенный под выполнение запросов, слишком мал. Контролировать его величину возможно с помощью серверных конфигурационных параметров
max_statement_mem
иstatement_mem
. Также существует возможность настройки ресурсных групп. -
Запрос не оптимизирован:
-
Выражение DISTINCT применяется к большому количеству столбцов. Каждая уникальная комбинация столбцов, указанных в
DISTINCT
, будет помещаться в оперативную память. Соответственно, чем больше таких комбинаций будет обнаружено, тем быстрее произойдет заполнение памяти и начнут создаваться spill-файлы. Рекомендуется ограничивать число искомых полей, а также не помещать в выражениеDISTINCT
столбцы с данными большого размера. -
Используется сортировка с помощью ORDER BY. Промежуточные результаты сортировки изначально сохраняются в RAM. Чем больше объем данных, которые предстоит отсортировать, тем быстрее начнется генерация spill-файлов. В Greenplum не рекомендуется использовать сортировку в запросах, особенно для больших таблиц. Вместо этого лучше сортировать результаты непосредственно в приемнике данных (на стороне клиента).
-
Большой объем данных обрабатывается без использования фильтров в секции WHERE. При выполнении
JOIN
-запросов данные одной из таблиц помещаются в хеш-таблицу в оперативной памяти. Соответственно, если искомые строки этой таблицы не будут отфильтрованы — память очень быстро переполнится. Рекомендуется по возможности всегда использовать фильтры, особенно на даты и время. Даже если есть необходимость выборки за весь период — желательно сформировать несколько запросов за короткие временные промежутки, после чего можно объединить результаты с помощьюUNION ALL
. Такой подход эффективнее попытки обработать все данные целиком. -
Хеш-таблица, создаваемая при выполнении JOIN-запросов, строится на основе большей из таблиц. При выполнении
INNER JOIN
хеш-таблица, которая упоминалась выше, строится по таблице с наименьшим объемом данных (чтобы минимизировать использование оперативной памяти). Однако, например, при использованииLEFT JOIN
за основу для хеша всегда берется таблица, указанная справа, независимо от ее объема, что может привести к проблемам, если эта таблица в паре наибольшая. Поэтому внимательно следите за порядком таблиц в запросах. Также старайтесь минимизировать количество извлекаемых столбцов.
-
РЕКОМЕНДАЦИЯ
|
Анализ использования spill-файлов
Дефолтная схема gp_toolkit
содержит ряд представлений (views), показывающих информацию по всем запросам, которые используют spill-файлы в настоящий момент времени. Эти представления могут быть полезны для анализа запросов, их оптимизации и своевременного предотвращения сбоев в системе:
-
gp_workfile_entries
— показывает операторы (query operators), вызвавшие создание spill-файлов на диске на сегментах в текущий момент времени. Одна результирующая строка относится к одному оператору.СтруктураСтолбец Описание datname
Название базы данных
pid
Идентификатор серверного процесса (process ID)
sess_id
Идентификатор сессии (session ID)
command_cnt
Идентификатор запроса (command ID)
usename
Название роли
query
Запрос к БД, выполняемый в текущий момент времени
segid
Идентификатор сегмента. Ссылается на
gp_segment_configuration.content
. Дополнительную информацию можно получить в разделе Таблицы системного каталога → gp_segment_configuration статьи Таблицыslice
Слайс (slice) плана выполнения запроса. Указывает на часть плана, выполняемую в текущий момент времени
optype
Тип оператора (query operator), вызвавшего создание spill-файла
size
Общий объем сгенерированных spill-файлов на сегменте (в байтах)
numfiles
Количество созданых spill-файлов
prefix
Префикс, используемый для обозначения группы связанных друг с другом spill-файлов
Пример:
SELECT * FROM gp_toolkit.gp_workfile_entries;
Результат:
datname | pid | sess_id | command_cnt | usename | query | segid | slice | optype | size | numfiles | prefix ---------+------+---------+-------------+---------+---------------------------------------------+-------+-------+--------+---------+----------+-------- adb | 5332 | 65 | 42 | gpadmin | SELECT DISTINCT(id1,id2,gen1,gen2) from t1; | -1 | 0 | Sort | 4292608 | 1 | Sort_1 (1 row)
-
gp_workfile_usage_per_query
— показывает запросы (queries), вызвавшие создание spill-файлов на диске на сегментах в текущий момент времени. Одна результирующая строка относится к одному запросу.StructureСтолбец Описание datname
Название базы данных
pid
Идентификатор серверного процесса (process ID)
sess_id
Идентификатор сессии (session ID)
command_cnt
Идентификатор запроса (command ID)
usename
Название роли
query
Запрос к БД, выполняемый в текущий момент времени
segid
Идентификатор сегмента. Ссылается на
gp_segment_configuration.content
. Дополнительную информацию можно получить в разделе Таблицы системного каталога → gp_segment_configuration статьи Таблицыsize
Общий объем сгенерированных spill-файлов на сегменте (в байтах)
numfiles
Количество созданых spill-файлов
Пример:
SELECT * FROM gp_toolkit.gp_workfile_usage_per_query;
Результат:
datname | pid | sess_id | command_cnt | usename | query | segid | size | numfiles ---------+------+---------+-------------+---------+---------------------------------------------+-------+----------+---------- adb | 5332 | 65 | 42 | gpadmin | SELECT DISTINCT(id1,id2,gen1,gen2) from t1; | -1 | 20807680 | 1 (1 row)
-
gp_workfile_usage_per_segment
— показывает общий объем дискового пространства, занимаемый spill-файлами на каждом сегменте в текущий момент времени. Одна результирующая строка относится к одному сегменту.СтруктураСтолбец Описание segid
Идентификатор сегмента. Ссылается на
gp_segment_configuration.content
. Дополнительную информацию можно получить в разделе Таблицы системного каталога → gp_segment_configuration статьи Таблицыsize
Общий объем сгенерированных spill-файлов на сегменте (в байтах)
numfiles
Количество созданых spill-файлов
Пример:
SELECT * FROM gp_toolkit.gp_workfile_usage_per_segment;
Результат:
segid | size | numfiles -------+----------+---------- 5 | 0 | 13 | 0 | 10 | 0 | 11 | 0 | 1 | 0 | 6 | 0 | 12 | 0 | 0 | 0 | 2 | 0 | 7 | 0 | 15 | 0 | 4 | 0 | 8 | 0 | 3 | 0 | -1 | 31752192 | 1 14 | 0 | 9 | 0 | (17 rows)
ПРИМЕЧАНИЕПриведенные выше представления могут просматривать все пользователи. Однако те из них, кто не является суперпользователем, могут получить информацию только по тем БД, которые доступны для их ролей.
Управление генерацией spill-файлов
Для ограничения количества spill-файлов и размера выделяемого им дискового пространства можно использовать несколько конфигурационных параметров. Их описание приведено ниже.
Название | Описание | Значение по умолчанию | Тип |
---|---|---|---|
gp_workfile_limit_files_per_query |
Максимальное количество spill-файлов, допустимое для создания одним запросом на одном сегменте. При превышении лимита возникает следующая ошибка: |
100000 |
master |
gp_workfile_limit_per_query |
Максимальный размер дискового пространства, выделяемого под spill-файлы, которые генерируются одним запросом на одном сегменте (в КБ). При превышении лимита возникает следующая ошибка: |
25000000 |
master |
gp_workfile_limit_per_segment |
Максимальный размер дискового пространства, выделяемого под spill-файлы, которые генерируются всеми запущенными запросами на одном сегменте (в КБ). При превышении лимита возникает следующая ошибка: |
50000000 |
local |
gp_workfile_compression |
Определяет, нужно ли использовать сжатие данных для spill-файлов, генерируемых операциями hash aggregation или hash join при выполнении запросов. Значение по умолчанию |
off |
master |
ВАЖНО
|