17.4. Управление ресурсами ядра#
17.4. Управление ресурсами ядра #
Tantor BE иногда может исчерпывать различные ограничения операционной системы, особенно когда на одной системе работает несколько копий сервера или в очень больших установках. В этом разделе объясняются ресурсы ядра, используемые Tantor BE, и шаги, которые можно предпринять для решения проблем, связанных с потреблением ресурсов ядра.
17.4.1. Общая память и семафоры #
Для работы Tantor BE требуется, чтобы операционная система предоставляла возможности обмена данными между процессами (IPC), в частности общую память и семафоры. В системах, на базе Unix, обычно предоставляются “System V” IPC, “POSIX” IPC или оба вида. Windows имеет собственную реализацию этих возможностей, о которой здесь не рассказывается.
По умолчанию, Tantor BE выделяет очень малое количество общей памяти System V, и гораздо больше анонимной общей памяти mmap
.
Также можно использовать одну большую область общей памяти System V (см. shared_memory_type).
Кроме того, при запуске сервера создается значительное количество семафоров, которые могут быть как вида System V, так и POSIX. В настоящее время на системах Linux и FreeBSD используются POSIX-семафоры, в то время как на других платформах используются семафоры System V.
Функции IPC System V обычно ограничены глобальными пределами выделения. Когда Tantor BE превышает один из этих пределов, сервер откажется запускаться и должен выдать информативное сообщение об ошибке, описывающее проблему и что с ней делать. (См. также Раздел 17.3.1). Соответствующие параметры ядра имеют одинаковые имена в разных системах; Таблица 17.1 дает обзор. Однако, методы их установки различаются. Ниже приведены рекомендации для некоторых платформ.
Таблица 17.1. System V IPC Параметры
Имя | Описание | Значения, необходимые для запуска одного экземпляра Tantor BE |
---|---|---|
SHMMAX | Максимальный размер сегмента общей памяти (в байтах) | не менее 1 кБ, но по умолчанию обычно гораздо больше |
SHMMIN | Минимальный размер сегмента общей памяти (в байтах) | 1 |
SHMALL | Общее количество доступной общей памяти (в байтах или страницах) | то же самое, что и SHMMAX , если в байтах,
или ceil(SHMMAX/PAGE_SIZE) , если в страницах,
плюс место для других приложений |
SHMSEG | Максимальное количество сегментов общей памяти на процесс | требуется только 1 сегмент, но значение по умолчанию гораздо выше |
SHMMNI | Максимальное количество общих сегментов памяти в системе | аналогично SHMSEG , плюс место для других приложений |
SEMMNI | Максимальное количество идентификаторов семафоров (т.е. наборов) | по крайней мере ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16) плюс место для других приложений |
SEMMNS | Максимальное количество семафоров в системе | ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16) * 17 плюс место для других приложений |
SEMMSL | Максимальное количество семафоров в наборе | не менее 17 |
SEMMAP | Количество записей в карте семафоров | см. текст |
SEMVMX | Максимальное значение семафора | не менее 1000 (По умолчанию часто устанавливается значение 32767; не изменяйте, если необходимо) |
Tantor BE необходимо несколько байтов общей памяти System V
(обычно 48 байтов на 64-битных платформах) для каждой копии сервера.
На большинстве современных операционных систем достаточно легко выделить такой объем памяти.
Однако, если вы запускаете много копий сервера или явно указываете серверу использовать большие объемы общей памяти System V (см.
shared_memory_type и dynamic_shared_memory_type), может потребоваться
увеличить значение SHMALL
, которое представляет собой общий объем общей памяти System V
в системе. Обратите внимание, что на многих системах SHMALL
измеряется в страницах,
а не в байтах.
Меньше вероятность возникновения проблем вызывает минимальный размер для общих сегментов памяти (SHMMIN
), который должен быть не более примерно 32 байт для Tantor BE (обычно это всего лишь 1). Максимальное количество сегментов в системе (SHMMNI
) или на процесс (SHMSEG
) маловероятно вызовет проблемы, если они установлены в ноль.
При использовании семафоров System V,
Tantor BE использует один семафор на каждое разрешенное соединение
(max_connections), разрешенный процесс автovacuum
(autovacuum_max_workers), разрешенный процесс отправки WAL
(max_wal_senders), и разрешенный фоновый
процесс (max_worker_processes), в наборах по 16.
Каждый такой набор будет
также содержать 17-й семафор, который содержит “магическое
число”, для обнаружения коллизий с наборами семафоров, используемыми
другими приложениями. Максимальное количество семафоров в системе
задается параметром SEMMNS
, который, следовательно, должен быть как минимум
таким же высоким, как max_connections
плюс
autovacuum_max_workers
плюс max_wal_senders
,
плюс max_worker_processes
, плюс один дополнительный для каждых 16
разрешенных соединений плюс рабочих процессов (см. формулу в Таблица 17.1). Параметр SEMMNI
определяет предел на количество наборов семафоров, которые могут
существовать в системе одновременно. Следовательно, этот параметр должен быть как минимум
ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16)
.
Снижение количества
разрешенных соединений является временным решением для сбоев,
которые обычно формулируются запутанно как “Нет места
на устройстве”, из функции semget
.
В некоторых случаях может потребоваться увеличить значение параметра SEMMAP
до значения, по крайней мере, порядка значения SEMMNS
. Если в системе присутствует этот параметр (многие системы его не имеют), он определяет размер карты ресурсов семафоров, в которой каждый непрерывный блок доступных семафоров требует записи. При освобождении набора семафоров он либо добавляется к существующей записи, смежной с освобожденным блоком, либо регистрируется в новой записи карты. Если карта заполнена, освобожденные семафоры теряются (до перезагрузки). Фрагментация пространства семафоров со временем может привести к меньшему количеству доступных семафоров, чем должно быть.
Различные другие настройки, связанные с “отменой семафора”, такие как
SEMMNU
и SEMUME
, не влияют на
Tantor BE.
При использовании семафоров POSIX, количество необходимых семафоров такое же, как и для System V, то есть один семафор на каждое разрешенное соединение (max_connections), разрешенный процесс автovacuum (autovacuum_max_workers), разрешенный процесс отправки WAL (max_wal_senders), и разрешенный фоновый процесс (max_worker_processes). На платформах, где этот вариант предпочтителен, нет конкретного ограничения ядра на количество семафоров POSIX.
- AIX
Необходимости в особой настройке для таких параметров, как
SHMMAX
, не должно возникать, так как, по-видимому, они настроены таким образом, чтобы позволить использовать всю память в качестве общей памяти. Такая конфигурация обычно используется для других баз данных, таких как DB/2.Может быть необходимо изменить глобальную информацию
ulimit
в файле/etc/security/limits
, так как значения по умолчанию для жестких ограничений размера файлов (fsize
) и количества файлов (nofiles
) могут быть слишком низкими.- FreeBSD
Настройки общей памяти по умолчанию обычно достаточно хороши, если только вы не установили
shared_memory_type
вsysv
. Системные семафоры V не используются на этой платформе.Настройки IPC по умолчанию можно изменить с помощью интерфейсов
sysctl
илиloader
. Следующие параметры можно установить с помощьюsysctl
:#
sysctl kern.ipc.shmall=32768
#
sysctl kern.ipc.shmmax=134217728
Чтобы сделать эти настройки постоянными после перезагрузки, измените файл
/etc/sysctl.conf
.Если вы установили
shared_memory_type
в значениеsysv
, вам также может потребоваться настроить ядро для блокировки System V общей памяти в оперативной памяти и предотвращения ее выгрузки в подкачку. Это можно сделать с помощью параметраsysctl
kern.ipc.shm_use_phys
.Если вы работаете в тюрьме FreeBSD, вы должны установить параметр
sysvshm
в значениеnew
, чтобы у него было собственное отдельное пространство имен System V для общей памяти. (До FreeBSD 11.0 было необходимо разрешить общий доступ к пространству имен IPC хоста из тюрем и принимать меры для избежания конфликтов).- NetBSD
Настройки общей памяти по умолчанию обычно достаточно хороши, если только вы не установили
shared_memory_type
в значениеsysv
. Обычно вам потребуется увеличить значенияkern.ipc.semmni
иkern.ipc.semmns
, так как значения по умолчанию в NetBSD для этих параметров слишком малы и вызывают дискомфорт.Параметры IPC могут быть настроены с помощью команды
sysctl
, например:#
sysctl -w kern.ipc.semmni=100
Чтобы сделать эти настройки постоянными после перезагрузки, измените файл
/etc/sysctl.conf
.Если вы установили
shared_memory_type
в значениеsysv
, вам также может потребоваться настроить ядро для блокировки System V общей памяти в оперативной памяти и предотвращения ее выгрузки в подкачку. Это можно сделать с помощью параметраsysctl
kern.ipc.shm_use_phys
.- OpenBSD
Настройки общей памяти по умолчанию обычно достаточно хороши, если только вы не установили
shared_memory_type
вsysv
. Обычно вам захочется увеличитьkern.seminfo.semmni
иkern.seminfo.semmns
, так как значения по умолчанию в OpenBSD для этих параметров слишком малы и вызывают дискомфорт.Параметры IPC могут быть настроены с помощью команды
sysctl
, например:#
sysctl kern.seminfo.semmni=100
Чтобы сделать эти настройки постоянными после перезагрузки, измените файл
/etc/sysctl.conf
.- Linux
Настройки общей памяти по умолчанию обычно достаточно хороши, если только вы не установили
shared_memory_type
вsysv
, и даже тогда только в старых версиях ядра, которые поставлялись с низкими значениями по умолчанию. Системные семафоры System V не используются на этой платформе.Настройки размера общей памяти можно изменить через интерфейс
sysctl
. Например, чтобы разрешить 16 ГБ:$
sysctl -w kernel.shmmax=17179869184
$
sysctl -w kernel.shmall=4194304
Чтобы сделать эти настройки постоянными после перезагрузки, см.
/etc/sysctl.conf
.- macOS
Настройки общей памяти и семафоров по умолчанию обычно достаточно хороши, если вы не установили
shared_memory_type
в значениеsysv
.Рекомендуемый способ настройки общей памяти в macOS - создать файл с именем
/etc/sysctl.conf
, содержащий присваивания переменных, например:kern.sysv.shmmax=4194304 kern.sysv.shmmin=1 kern.sysv.shmmni=32 kern.sysv.shmseg=8 kern.sysv.shmall=1024
Обратите внимание, что в некоторых версиях macOS все пять параметров общей памяти должны быть установлены в файле
/etc/sysctl.conf
, иначе значения будут проигнорированы.SHMMAX
может быть установлено только как кратное числу 4096.SHMALL
измеряется в страницах размером 4 кБ на данной платформе.Возможно изменить все, кроме
SHMMNI
, на лету, используя sysctl. Однако лучше всего настроить предпочтительные значения через/etc/sysctl.conf
, чтобы значения сохранялись после перезагрузки.- Solaris
illumos Настройки общей памяти и семафоров по умолчанию обычно оптимальны для большинства приложений Tantor BE. В Solaris значение
SHMMAX
составляет одну четверть от общего объема RAM системы. Чтобы дополнительно настроить это значение, используйте настройки проекта, связанные с пользователемpostgres
. Например, выполните следующую команду от имени пользователяroot
:projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres
Эта команда добавляет проект
user.postgres
и устанавливает максимальный объем общей памяти для пользователяpostgres
в 8 ГБ. Изменения вступят в силу при следующем входе пользователя или при перезапуске Tantor BE (не перезагрузке). Предполагается, что Tantor BE запущен пользователемpostgres
в группеpostgres
. Перезагрузка сервера не требуется.Другие рекомендуемые изменения настроек ядра для серверов баз данных, которые будут иметь большое количество соединений, включают:
project.max-shm-ids=(priv,32768,deny) project.max-sem-ids=(priv,4096,deny) project.max-msg-ids=(priv,4096,deny)
Кроме того, если вы запускаете Tantor BE внутри зоны, вам может потребоваться увеличить лимиты использования ресурсов зоны. См. "Глава 2: Проекты и задачи" в Руководство системного администратора для получения дополнительной информации о
projects
иprctl
.
17.4.2. systemd RemoveIPC #
Если systemd используется, необходимо обратить внимание на то, чтобы ресурсы IPC (включая общую память) не были преждевременно удалены операционной системой. Это особенно важно при установке PostgreSQL из исходного кода. Пользователи пакетов распространения PostgreSQL меньше подвержены этому влиянию, так как пользователь postgres
обычно создается как системный пользователь.
Настройка RemoveIPC
в logind.conf
определяет, будут ли удалены IPC-объекты
при полном выходе пользователя. Системные пользователи не подпадают под это
правило. По умолчанию эта настройка в стандартной версии systemd включена, но
в некоторых операционных системах она отключена.
Типичным наблюдаемым эффектом при включении этой настройки является то, что объекты общей памяти, используемые для параллельного выполнения запросов, удаляются на видимо случайные моменты времени, что приводит к ошибкам и предупреждениям при попытке открытия и удаления их, например
WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No such file or directory
Различные типы объектов IPC (общая память против семафоров, System V против POSIX) обрабатываются немного по-разному systemd, поэтому можно заметить, что некоторые ресурсы IPC не удаляются так же, как другие. Однако не рекомендуется полагаться на эти тонкие различия.
Пользователь “выходит из системы” может происходить в рамках обслуживания
задания или вручную, когда администратор входит в систему
от имени пользователя postgres
или что-то подобное, поэтому в общем случае его сложно
предотвратить.
Что такое “системный пользователь” определяется
во время компиляции systemd из
настройки SYS_UID_MAX
в файле /etc/login.defs
.
Упаковочные и развертывающие скрипты должны быть осторожными при создании пользователя postgres
в качестве системного пользователя с использованием команды useradd -r
, adduser --system
или аналогичной.
В противном случае, если учетная запись пользователя была создана неправильно или не может быть изменена, рекомендуется установить
RemoveIPC=no
в файле /etc/systemd/logind.conf
или другом соответствующем
файле конфигурации.
Предостережение
По крайней мере, одно из этих двух условий должно быть обеспечено, иначе сервер PostgreSQL будет очень ненадежным.
17.4.3. Ограничения ресурсов #
Unix-подобные операционные системы применяют различные виды ограничений ресурсов, которые могут помешать работе вашего сервера Tantor BE. Особенно важны ограничения на количество процессов на пользователя, количество открытых файлов на процесс и объем памяти, доступный каждому процессу. Каждый из них имеет "жесткий" и "мягкий" пределы. Мягкий предел - это то, что на самом деле учитывается, но его можно изменить пользователем до жесткого предела. Жесткий предел может быть изменен только root-пользователем. Вызов системы setrlimit
отвечает за установку этих параметров. Встроенная команда оболочки ulimit
(для оболочек Bourne) или limit
(для оболочки csh) используется для управления ограничениями ресурсов из командной строки. В системах, основанных на BSD, файл /etc/login.conf
управляет различными ограничениями ресурсов, установленными при входе в систему. См. документацию операционной системы для получения подробной информации. Соответствующие параметры - maxproc
, openfiles
и datasize
. Например:
default:\ ... :datasize-cur=256M:\ :maxproc-cur=256:\ :openfiles-cur=256:\ ...
(-cur
- это мягкий предел. Добавьте
-max
для установки жесткого предела).
Ядра также могут иметь системные ограничения на некоторые ресурсы.
На Linux параметр ядра
fs.file-max
определяет максимальное количество открытых файлов, которое поддерживает ядро. Его можно изменить с помощьюsysctl -w fs.file-max=
. Чтобы сохранить настройку после перезагрузки, добавьте присваивание вN
/etc/sysctl.conf
. Максимальное ограничение файлов на процесс устанавливается во время компиляции ядра; см./usr/src/linux/Documentation/proc.txt
для получения дополнительной информации.
Сервер Tantor BE использует один процесс на соединение, поэтому вам следует предусмотреть не менее столько процессов, сколько разрешено соединений, в дополнение к тому, что вам нужно для остальной части вашей системы. Обычно это не является проблемой, но если вы запускаете несколько серверов на одной машине, могут возникнуть проблемы с ресурсами.
Ограничение по умолчанию на количество открытых файлов в фабрике часто устанавливается на "социально дружественные" значения, которые позволяют множеству пользователей сосуществовать на одной машине, не используя неподходящую долю системных ресурсов. Если вы запускаете много серверов на одной машине, то это, возможно, то, что вам нужно, но на выделенных серверах вы можете захотеть увеличить это ограничение.
С другой стороны, некоторые системы позволяют отдельным процессам открывать большое количество файлов; если это делают более нескольких процессов, то легко можно превысить системное ограничение. Если вы обнаружите, что это происходит и вы не хотите изменять системное ограничение, вы можете установить параметр конфигурации Tantor BE max_files_per_process, чтобы ограничить количество открытых файлов.
Еще одно ограничение ядра, которое может вызвать беспокойство при поддержке большого количества клиентских подключений, — это максимальная длина очереди подключений сокета. Если в течение очень короткого периода поступит больше запросов на подключение, чем это значение, некоторые из них могут быть отклонены до того, как сервер Tantor BE сможет обработать запросы, и эти клиенты получат неинформативные ошибки подключения, такие как “Ресурс временно недоступен” или “Подключение отклонено”. По умолчанию ограничение длины очереди составляет 128 на многих платформах. Чтобы увеличить его, настройте соответствующий параметр ядра через sysctl, затем перезапустите сервер Tantor BE. Параметр называется по-разному: net.core.somaxconn
на Linux, kern.ipc.soacceptqueue
на новых версиях FreeBSD и kern.ipc.somaxconn
на macOS и других вариантах BSD.
17.4.4. Перераспределение памяти в Linux #
По умолчанию, поведение виртуальной памяти в Linux не является оптимальным для Tantor BE. Из-за того, как ядро реализует перераспределение памяти, ядро может завершить работу постмастера Tantor BE (супервизора серверного процесса), если требования к памяти как у Tantor BE, так и у другого процесса приведут к исчерпанию виртуальной памяти системы.
Если это произойдет, вы увидите сообщение ядра, которое будет выглядеть примерно так (обратитесь к документации и конфигурации вашей системы, чтобы узнать, где искать такое сообщение):
Out of Memory: Killed process 12345 (postgres).
Это указывает на то, что процесс postgres
был завершен из-за нехватки памяти.
Хотя существующие подключения к базе данных будут продолжать функционировать
нормально, новые подключения не будут приниматься. Для восстановления
необходимо перезапустить Tantor BE.
Один из способов избежать этой проблемы - запустить Tantor BE на машине, где вы можете быть уверены, что другие процессы не будут использовать всю память. Если память ограничена, увеличение пространства подкачки операционной системы может помочь избежать проблемы, поскольку убийца процессов из-за нехватки памяти (OOM) вызывается только тогда, когда физическая память и пространство подкачки исчерпаны.
Если сама Tantor BE является причиной нехватки памяти в системе, вы можете избежать проблемы, изменив конфигурацию. В некоторых случаях может помочь снижение параметров конфигурации, связанных с памятью, особенно shared_buffers
, work_mem
и hash_mem_multiplier
. В других случаях проблема может быть вызвана разрешением слишком большого количества подключений к самому серверу базы данных. Во многих случаях лучше уменьшить max_connections
и вместо этого использовать внешнее программное обеспечение для пула подключений.
Возможно изменить поведение ядра так, чтобы оно не “перераспределяло” память. Хотя эта настройка не предотвратит полное вызова OOM killer, она значительно снизит вероятность его вызова и, следовательно, обеспечит более надежное поведение системы. Для этого выбирается строгий режим перераспределения памяти с помощью sysctl
:
sysctl -w vm.overcommit_memory=2
или разместите эквивалентную запись в /etc/sysctl.conf
.
Также можно изменить связанный параметр
vm.overcommit_ratio
. Подробности см. в документации ядра
файл https://www.kernel.org/doc/Documentation/vm/overcommit-accounting.
Другой подход, который можно использовать с изменением или без изменения параметра vm.overcommit_memory
, заключается в установке процесс-специфического значения приоритета коррекции OOM для процесса постмастер в значение -1000
, тем самым гарантируя, что он не будет выбран OOM-убийцей. Самый простой способ сделать это - выполнить следующую команду
echo -1000 > /proc/self/oom_score_adj
в Tantor BE стартовом скрипте непосредственно перед вызовом postgres
.
Обратите внимание, что это действие должно быть выполнено от имени root, иначе оно не будет иметь эффекта;
поэтому скрипт запуска, принадлежащий root, является самым простым местом для этого. Если вы
сделаете это, вам также следует установить эти переменные окружения в стартовом
скрипте перед вызовом postgres
:
export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0
Эти настройки приведут к тому, что дочерние процессы постмастер будут работать с нормальной настройкой OOM score, равной нулю, чтобы OOM -убийца все еще мог на них нацеливаться при необходимости. Вы можете использовать другое значение для PG_OOM_ADJUST_VALUE
, если нужно, чтобы дочерние процессы работали с другой настройкой OOM score. (PG_OOM_ADJUST_VALUE
также можно опустить, в этом случае оно устанавливается по умолчанию равным нулю). Если вы не установите PG_OOM_ADJUST_FILE
, дочерние процессы будут работать с той же настройкой OOM score, что и постмастер, что не рекомендуется, поскольку весь смысл заключается в том, чтобы обеспечить постмастеру предпочтительную настройку.
17.4.5. Огромные страницы Linux #
Использование больших страниц уменьшает накладные расходы при использовании больших смежных блоков памяти, как это делает Tantor BE, особенно при использовании больших значений shared_buffers. Чтобы использовать эту функцию в Tantor BE, вам необходим ядро с CONFIG_HUGETLBFS=y
и CONFIG_HUGETLB_PAGE=y
. Вам также потребуется настроить операционную систему для предоставления достаточного количества больших страниц нужного размера. Параметр, вычисляемый во время выполнения, shared_memory_size_in_huge_pages сообщает количество требуемых больших страниц. Этот параметр можно просмотреть до запуска сервера с помощью команды postgres
такой как:
$postgres -D $PGDATA -C shared_memory_size_in_huge_pages
3170 $grep ^Hugepagesize /proc/meminfo
Hugepagesize: 2048 kB $ls /sys/kernel/mm/hugepages
hugepages-1048576kB hugepages-2048kB
В этом примере значение по умолчанию составляет 2 МБ, но вы также можете явно запросить
либо 2 МБ, либо 1 ГБ с помощью huge_page_size, чтобы адаптировать
количество страниц, рассчитанных по
shared_memory_size_in_huge_pages
.
В этом примере нам необходимо как минимум 3170
огромных страниц,
но более крупное значение будет соответствующим, если другие программы на машине
также нуждаются в огромных страницах.
можно установить это с помощью:
# sysctl -w vm.nr_hugepages=3170
Не забудьте добавить эту настройку в /etc/sysctl.conf
,
чтобы она применялась после перезагрузки. Для нестандартных размеров
больших страниц можно использовать вместо этого:
# echo 3170 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
Также возможно указать эти настройки при загрузке системы, используя параметры ядра, такие как hugepagesz=2M hugepages=3170
.
Иногда ядро не может сразу выделить желаемое количество больших страниц из-за фрагментации, поэтому может потребоваться повторить команду или перезагрузить систему. (Сразу после перезагрузки большая часть памяти машины должна быть доступна для преобразования в большие страницы). Чтобы проверить ситуацию с выделением больших страниц определенного размера, используйте:
$ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
Может потребоваться также предоставить пользователю операционной системы сервера баз данных разрешение на использование огромных страниц, установив vm.hugetlb_shm_group
через sysctl и/или предоставив разрешение на блокировку памяти с помощью ulimit -l
.
По умолчанию Tantor BE использует huge pages, если это возможно, с размером huge page, установленным по умолчанию в системе, и в случае неудачи переходит на обычные страницы. Чтобы обеспечить использование huge pages, вы можете установить huge_pages в on
в файле postgresql.conf
. Обратите внимание, что с этой настройкой Tantor BE не сможет запуститься, если недостаточно huge pages.
Для подробного описания функции Linux huge pages ознакомьтесь с https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt.