Postgresql ошибка нехватка памяти

Обновлено: 07.07.2024

Для облегчения загрузки больших объемов данных в базу данных PostgreSQL, вам может понадобиться увеличить значения shared_buffers и max_locks_per_transaction в файле postgresql.conf.

shared_buffers

Параметр shared_buffers задает объем памяти, используемой для буферов разделяемой памяти. В документации PostgreSQL указано, что по причинам производительности вам возможно потребуется использовать большее значение параметра, чем минимальное значение в 128 КБ, либо значение в 16 KБ умноженное на число, установленное для параметра max_connections. Рекомендуется, чтобы shared_buffers был установлен на использование нескольких десятков мегабайт для боевого экземпляра.

При загрузке больших объемов данных, вы часто нуждаетесь в более высоком значении shared_buffers, чем значение установленное по умолчанию в 32 МБ. После изменения этого параметра в файле postgresql.conf, вам необходимо перезапустить кластер базы данных.

max_locks_per_transaction

Значение max_locks_per_transaction указывает число объектов базы данных, которые могут быть заблокированы одновременно. В большинстве случаев, значения по умолчанию 64 бывает достаточно. Тем не менее, при загрузке большого количества данных (например, несколько тысяч) сразу, число одновременных заблокированных для транзакции объектов может превысить 64.

Это не взаимосвязь один-к-одному между конкурентными блокировками и количеством наборов данных; другими словами, если вы загружаете 3000 наборов данных, вам не нужно увеличивать max_locks_per_transaction до 3000. Вначале раскомментируйте параметр max_locks_per_transaction и увеличьте его значение до 100 перед загрузкой в пакетном режиме.

При изменении параметра max_locks_per_transaction, вы должны перезагрузить сервер.

Увеличение значения любого из данных параметров может привести к запросу базой данных большего объема разделяемой памяти, чем допускает операционная система. Сведения о том, как можно увеличить разделяемую память в вашей операционной системе, находятся в разделе Управление ресурсами ядра (Managing Kernel Resources) в Документации PostgreSQL.

cursor_tuple_fraction

Значение cursor_tuple_fraction используется планировщиком PostgreSQL для оценки необходимого набора строк, возвращаемого запросом. По умолчанию, в файле postgresql.conf cursor_tuple_fraction имеет значение 0.1, это означает, что первые 10 процентов строк (или объектов) результата возвращаются быстро, для возвращения остальных строк требуется время.

Если вы хотите изменить процент результата, который отображается планировщиком PostgreSQL при подключении к не-ArcGIS приложениям, измените значение параметра cursor_tuple_fraction в файле postgresql.conf.

Когда для запросов данных применяется ArcGIS 10.2 или более поздней версии, всегда используется значение 1.0, это означает, что данные не отображаются до возвращения 100 процентов результатов. Измененное значение cursor_tuple_fraction в файле postgresql.conf не применяется при доступе к базе данных из ArcGIS. Чтобы изменить значение, используемое ArcGIS, необходимо задать переменную среды cursor_tuple_fraction для сеанса или всей системы.

Повышение производительности сторонних пространственных SQL-запросов

При выполнении SQL-запросов вне ArcGIS, которые возвращают пространственных столбцы ST_Geometry из бизнес-таблицы, можно повысить производительность запросов, если вы установите системную переменную среды, ST_GEOMETRY_OUTPUT_FORMAT, для вывода в тип ST_Geometry, а не в расширенное стандартное текстовое представление (WKT).

По умолчанию, ST_GEOMETRY_OUTPUT_FORMAT установлен на ST_GEOMETRY, это означает, что возвращается 16-ричное представление. Это необходимо для создания работоспособной резервной копии базы геоданных. Вы можете изменить эту переменную на TYPE, если вы хотите улучшить производительность SQL-запросов. Если вы установите эту переменную, потому что вы планируете сделать ряд пространственных запросов SQL, убедитесь, что удалили ее после того, как вы завершите ваши запросы, а затем перезапустите кластер базы данных PostgreSQL.

Переменная должна быть установлена на компьютере, где запущен PostgreSQL.

Для ОС Linux, установите переменную оболочки, из которой запускаете SQL-запросы. Для оболочки bash, синтаксис выглядит следующим образом:

Для оболочки csh, синтаксис выглядит следующим образом:

В Windows, создайте системную переменную среды в свойствах системы.

Имя переменной: ST_GEOMETRY_OUTPUT_FORMAT

Значение переменной: TYPE

После установки данной переменной, вам необходимо перезапустить кластер базы данных PostgreSQL.

Жил на Винде-7, имел забитый на 70% 500Гб SSD диск, все было хорошо. Но потребовалось установить Ubuntu. Ставил через WUBI, т.к. другие более подробные мануалы по установке ниасилил. Сейчас при старте компа появляется выбор из 2 операционок (как надо) и еще какой-то Граб (по ошибке поверил одному описанию установки, но это вроде не мешает). Параметры системы: Память 3,6 ГиБ, Диск 18,2 ГБ. По команде free -h выдает

гуглил - пишут, что можно настраивать postgres, чтобы он не был таким прожорливым. А я не знаю, может у меня настолько мало свободной памяти, что это уже не поможет? И можно ли теперь как-то добавить еще памяти в систему, или уже поздно, диск размечался при установке? Переставлять все по новой? И весь установленный уже софт и т.п.? Что скажете, доктора?


А я не знаю, может у меня настолько мало свободной памяти, что это уже не поможет?

У тебя свободно примерно 1.8 Гб, постгрес настроен на то, чтобы откушать сразу 2.2Гб.

Настроить Postgres можно, но лучше ответить на вопрос, почему у тебя так мало памяти доступно на сервере. И почему некруглое число.

Ты где сервер видишь? У него десктоп на 4 гига, доступно 3.6

Deleted ( 10.10.17 22:20:59 )
Последнее исправление: Deleted 10.10.17 22:21:22 (всего исправлений: 1)

наверни свапца, места хватает же пока

Спасибо, навернул 5 ГБ (!) свапца, теперь из 2 докер-контейнеров стартует первый, а второй валится (раньше было наоборот :)). Но сейчас я могу их оба запустить руками не через compose а через docker start (хотя может так запускается не все что нужно, буду смотреть дальше). И да, со свапцом оно стало время от времени виснуть наглухо, перезгружаюсь регулярно.


ППЦ! тебе постгрес - для одноэс?


Я поверил установщику, который по умолчанию запросил 18ГБ.

Сейчас то что делать? Имеет смысл параметры Постгреса крутить?


Действительно, куда могло место деться…


Где запускается постгрес, там и сервер. Пусть даже он развёрнут на ноутбуке под подушкой.

Со свапцом жилось тяжко, все время зависала система, и много из того что нужно вообще не стартовало. Только что докупил один модуль памяти на 8 гигов - и навскидку все стало гораздо веселее, и даже работает. Насчет все/не все буду дальше смотреть.

Вообще моя материнка умеет в 32 гига максимум (есть 4 слота, можно во все поставить по 8 гигов), есть возможность для апгрейда еще. Просто по умолчанию стояла 32 бит Винда, которая не умеет физически больше 4 гигов ОЗУ подключать, поэтому и было такое железо.

Я также попытался запустить pgtune, который дал следующую рекомендацию с более настроенными параметрами, но это ничего не изменило. Он предлагает shared_buffers размером 1/4 ОЗУ, что, по-видимому, согласуется с рекомендациями в других местах (и в частности в PG wiki).

Я попытался переиндексировать всю базу данных после изменения настроек (используя reindex database ), но это тоже не помогло. Я играл с shared_buffers и work_mem. Постепенно изменяя их с очень консервативных значений по умолчанию (128 КБ / 1 МБ), постепенно снижается производительность.

Я запустил EXPLAIN (ANALYZE,BUFFERS) несколько запросов, и виновник, похоже, в том, что Hash Join значительно медленнее. Мне не понятно почему.

Чтобы привести конкретный пример, у меня есть следующий запрос. Он работает

2100 мс в конфигурации по умолчанию и

3300 мс в конфигурации с увеличенным размером буфера:

EXPLAIN (ANALYZE,BUFFERS) для запроса выше:

Вопрос в том, почему я наблюдаю снижение производительности при увеличении размеров буфера? У машины точно не хватает памяти. Выделение, если для разделяемой памяти в ОС задано ( shmmax и shmall ) очень большое значение, это не должно быть проблемой. Я не получаю никаких ошибок в журнале Postgres либо. Я использую автовакуум в конфигурации по умолчанию, но не ожидаю, что это как-то связано с этим. Все запросы выполнялись на одной и той же машине с интервалом в несколько секунд, только с измененной конфигурацией (и перезапускали PG).

Изменить: Я только что нашел один особенно интересный факт: когда я выполняю тот же тест на моем iMac в середине 2010 года (OSX 10.7.5) также с Postgres 9.2.1 и 16 ГБ оперативной памяти, я не испытываю замедления. В частности:

Когда я делаю точно такой же запрос (тот, что выше) с точно такими же данными на сервере, я получаю 2100 мс с work_mem = 1 МБ и 3200 мс с 96 МБ.

У Mac есть SSD, так что это понятно быстрее, но он демонстрирует поведение, которое я ожидаю.

Похоже, что в более медленном случае каждый шаг постоянно медленнее. Остальные настройки остались прежними? О, и доложите, пожалуйста, ответьте на свой вопрос, если найдете ответ! (Это разрешено, даже поощряется). Я действительно удивляюсь, насколько Postgres похож на Oracle в этом отношении: я помню курс Джонатана Льюиса (гуру Oracle), в котором он продемонстрировал, что выделение большего количества памяти для сортировок иногда делает их медленнее. Я забыл подробности, но это было связано с тем, что Oracle выполняет частичные сортировки, а затем записывает их во временное хранилище, а затем объединяет их позже. Каким-то образом больше памяти замедлило этот процесс.

Прежде всего, имейте в виду, что work_mem выполняется для каждой операции, и поэтому он может быстро стать чрезмерным. В общем, если у вас нет проблем с медленной сортировкой, я оставляю work_mem в покое, пока она вам не понадобится.

Глядя на ваши планы запросов, меня поражает то, что обращения к буферу сильно различаются, если смотреть на эти два плана, и что даже последовательное сканирование выполняется медленнее. Я подозреваю, что проблема связана с кэшированием с упреждающим чтением и нехваткой места для этого. Это означает, что вы смещаете память для повторного использования индексов и чтения таблиц на диске.

Насколько я понимаю, PostgreSQL будет смотреть на кеш для страницы перед чтением ее с диска, потому что он не знает, будет ли кеш ОС содержать эту страницу. Поскольку страницы затем остаются в кеше и поскольку этот кеш медленнее, чем кеш ОС, это меняет виды запросов, которые выполняются быстро, по сравнению с типами, которые выполняются медленно. На самом деле, читая планы, кроме проблем с work_mem, похоже, что вся информация вашего запроса поступает из кеша, но вопрос в том, какой именно кеш.

work_mem : сколько памяти мы можем выделить для сортировки или связанной операции соединения. Это для каждой операции, а не для оператора или серверной части, поэтому один сложный запрос может многократно использовать этот объем памяти. Не ясно, что вы достигаете этого предела, но это стоит отметить и знать. если вы увеличите это значение слишком сильно, вы потеряете память, которая может быть доступна для кэша чтения и общих буферов.

shared_buffers : сколько памяти выделить для действительной очереди страниц PostgreSQL. Теперь, в идеале, интересный набор вашей базы данных должен оставаться в кеше памяти здесь и в буферах чтения. Тем не менее, это гарантирует, что наиболее часто используемая информация во всех бэкэндах кэшируется, а не сбрасывается на диск. В Linux этот кеш значительно медленнее, чем дисковый кеш ОС, но он гарантирует, что дисковый кеш ОС не работает и прозрачен для PostgreSQL. Это довольно ясно, где ваша проблема.

Так что получается, что когда у нас есть запрос, мы сначала проверяем общие буферы, так как PostgreSQL хорошо знает этот кеш, и ищем страницы. Если их там нет, мы просим ОС открыть их из файла, и если ОС кэширует результат, она возвращает кэшированную копию (это быстрее, чем общие буферы, но Pg не может определить, кэширована она или включена. диск и диск намного медленнее, поэтому PostgreSQL обычно не использует этот шанс). Имейте в виду, что это также влияет на случайный и последовательный доступ к страницам. Таким образом, вы можете получить лучшую производительность при более низких настройках shared_buffers.

У меня есть ощущение, что вы, вероятно, получите лучшую или, по крайней мере, более стабильную производительность в средах с высоким уровнем параллелизма и большими настройками shared_buffer. Также имейте в виду, что PostgreSQL захватывает эту память и удерживает ее, поэтому, если в системе выполняются другие функции, буферы чтения будут хранить файлы, прочитанные другими процессами. Это очень большая и сложная тема. Большие параметры общего буфера обеспечивают лучшие гарантии производительности, но могут в некоторых случаях обеспечивать меньшую производительность.

(0) сколько памяти на сервере и какие сейчас параметры?

max_connections
shared_buffers
effective_cache_size
maintenance_work_mem
wal_buffers
work_mem

(0) таки не хватает постгри или 1С-серверу или у вас всё на 1 сервере?
Ограничения по памяти на 1 меня сколько?

ни версии платформы 1С и ее разрадности, ни версии УНФ, ни версии постгри, ни версии ОСи - ничего! И кто-то должен оп и чего-то насоветовать.

Ну установите самый последний из существующих, так в нем обновленные уже готовые какие-то настройки будут

в настройках сервера 1с, там где локальный кластер, вызываешь свойства правой кнопкой мышью и если в поле допустимый объем памяти стоит вместо нуля какое то значение в кб то увелич его
Ошибка, грузит около 20 мин, выдает ошибку недостаточно памяти. как понять какой именно памяти ему не хватает?
при этом на жестком диске до ошибки сжирает почти 3гб
Вангую - памяти не хватает серверу предприятия. Если бы памяти было мало СУБД, то в тексте ошибки было-бы что-то указывающее на Postgres. Что-то типа ошибка SQL
(8) в диспетчере на момент перед самой ошибкой кто сжирает памяти много и сразу после ошибки ее высвобождает?
(8) На момент возникновения ошибки в логи PostgreSQL что пишется? Что-нибудь вроде "out of memory" или "Недостаточно памяти для получения результата запроса к базе данных"?
(15) Попробуй на клиенте запустить 64 бита версию платформы
(17) не все, а платформа на сервере. На клиенте может и 32 стоять вполне себе успешно. Ну в режиме толстого клиента пробуй запустить.
(17) просто сжирание на локальном клиенте временного файла до 3 Гб как бы намекает на предел в памяти, который давно существует в майкрософтовых 32бита процессах - 3 ГБ с копейками. Какие-то особенности системы. В теории:
2 ГБ - знаковое целое int.
4 ГБ - беззнаковое целое int
внутренние особенности решения на винде 4 ГБ не позволяют, а только 3 ГБ

(20) Ну вот и еще одну техническую подробность удалось вытащить клещами.
Вообще-то в терминале можно поставить ограничение

А с локальных компов доступ к серверу в принципе возможен? С клиента без использования терминала что выдает? Просто по РДП без терминала на самом сервере с его же платформой.

На всякий случай, выше указывалось проверить сколько памяти задано в настройках агента сервера 1С на каждый рабочий процесс. Вот на это тоже можно посмотреть. Но эта настройка тогда будет давать такую же ошибку при работе с сервером в клиенте с локального компа, без терминала.

но ошибка по рдп
Поменял еще раз параметры postgre перечитал конфу перезагрузил службы. Пока грузит ошибку не выдает. но база растет как на дрожжах. уже на 1гб выросла.
такими темпами каждое закрытие месяца по 2гб не очень хорошо

(22) по росту базы ничего не скажу

Если бы проблема была "на стороне сервера", а не клиента, то при любом способе подключения клиентского было бы одинаковая проблема.

Читайте также: