Простаивающие процессы postgres занимают много памяти
Я пытаюсь понять, почему ~30 простаивающих процессов postgres занимают так много памяти для конкретного процесса после нормального использования. Я использую Postgres 9.3.1 и CentOS release 6.3 (Final).
Используя top
, Я вижу, что многие из соединений postgres используют до 300 МБ (в среднем ~200 МБ) общей (RES-SHR) памяти:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3534 postgres 20 0 2330m 1.4g 1.1g S 0.0 20.4 1:06.99 postgres: deploy mtalcott 10.222.154.172(53495) idle
9143 postgres 20 0 2221m 1.1g 983m S 0.0 16.9 0:14.75 postgres: deploy mtalcott 10.222.154.167(35811) idle
6026 postgres 20 0 2341m 1.1g 864m S 0.0 16.4 0:46.56 postgres: deploy mtalcott 10.222.154.167(37110) idle
18538 postgres 20 0 2327m 1.1g 865m S 0.0 16.1 2:06.59 postgres: deploy mtalcott 10.222.154.172(47796) idle
1575 postgres 20 0 2358m 1.1g 858m S 0.0 15.9 1:41.76 postgres: deploy mtalcott 10.222.154.172(52560) idle
есть около 29 общих соединений простоя. Эти бездействующие соединения продолжают расти в памяти, пока машина не начнет использовать swap, а затем производительность скрежещет, чтобы остановиться. Как и ожидалось, сброс соединения очищает память конкретного процесса. Такое же количество подключений на одном компьютере использует только 20% памяти (с 0 swap) при периодическом повторном подключении. За какую информацию держатся эти процессы? Я бы ожидать длительные, ожидания и Postgres процессы имеют схожие памяти на новый, не праздные.
стоит отметить: я сильно использую схемы. При каждом запросе моего приложения я устанавливаю и сбрасываю путь поиска.
1 ответов
какую информацию держат эти процессы? Я бы ожидать длительные, ожидания и Postgres процессы имеют схожие памяти на новый, не праздные.
на самом деле существует довольно много вещей, которые Postgres будет кэшировать в локальной памяти после их загрузки:
- relcache (дескрипторы отношений)
- catcache (записи системного каталога)
- скомпилированные деревья для plpgsql функции
для большинства случаев использования все они составляют незначительное количество. Ключом здесь было интенсивное использование схем и влияние на relcache. Эта база данных содержит ~500 схем, каждая с одинаковыми ~90 таблицами. Для Postgres, хотя схемы все одинаковы, это работает до 45 000 таблиц (500*90).
каждый запрос кэшировал некоторые дескрипторы отношений таблиц в памяти (чаще всего в другой схеме, чем предыдущий запрос), постепенно заполняя relcache. К сожалению, Postgres не предлагает способ ограничить размер этих кэшей, поскольку накладные расходы, вероятно, будут контрпродуктивными для большинства случаев использования.
возможные решения:
- повторное подключение после определенного количества запросов
- добавить больше памяти
- объединение соединений, чтобы поставить потолок на количество соединений postgres с помощью pgpool-II или PgBouncer
спасибо тому лейну и Мерлину Монкуру за помощь в этом над списки рассылки Postgres.