Pull to refresh

Comments 27

Ну я бы еще добавил абзац про UNLOGGED таблицы и TRUNCATE. И про настройки ядра linux, в частности vm.zone_reclaim_mode. Еще вы рекомендуете на мой взгляд слишком маленькие значения shared_buffers. Зависит, конечно, от системы, но 128mb стандартный минимум для *nix, 64mb для windows. У себя использую около 30% от RAM минимум.
128mb стандартный минимум для *nix

Если базе выделять в сумме 512mb. Вообще данная утилита для простейшей настройки — pgtune.leopard.in.ua/ Брать 1/4 для shared_buffers было установленно давно через практическое применение. Понятное дело, что иногда нужно и 80% памяти давать, зависит от размера базы и метода её использования.
Более 40% выделять не стоит, 80% буфера уже система не даст, у нее самой кэша не хватит для такого. shared_buffers зависит в основном от системы и от платформы. Плюс, почему вы пишете что зависит от базы, если емнип это настройка на уровне кластера.
Вы идете от системы, а я иду от памяти. Я не говорю процент от всей системной памяти. На сервере может быть 2Гб памяти, но базе я могу выделить только 1Гб, а значит 25-30% идут от этого числа. shared_memory на 32 битных системах можно поднять до 2.5-3Гб (но не нужно), а на 64 битных нет предела (достаточно большой).

Плюс, почему вы пишете что зависит от базы, если емнип это настройка на уровне кластера.

shared_memory в первую очередь используется для данных, с которыми активно ведется работа. Если база помещается в 50% памяти, то выделив 50% под shared_memory может дать хорошую производительность для базы.
А почему вы привязываете параметр глобального кэширования рабочих данных кластера, к объему базы. Баз, например, может быть несколько. Если вы называете кластер базой — нужно срочно исправляться, т.к. настраиваются параметры отдельно для баз и отдельно для кластера. Тот же fsync можно настроить только для кластера, а unlogged таблицы только на уровне базы. Во-вторых, если вы выделяете 1 Гб оперативной памяти для запуска кластера, при чем тут объем базы. В кэш попадают еще и запросы, промежуточные выборки, промежуточные таблицы и куча другой информации которая в холодной базе на диске не хранится. Память в shared memory обращает система уже через свой кэш. Плюс минимумы на 9.2 и минимумы на 9.3 различаются на порядок из-за перехода с sysv на mmap.
А почему вы привязываете параметр глобального кэширования рабочих данных кластера, к объему базы. Баз, например, может быть несколько.

Может, но в проектах с высокой нагрузкой в основном работа идет с одной базой. Для шаред хостинга схема тюнинга совсем другая.

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


Основное предназначение shared_buffers — кэш блоков таблиц и индексов. Чем большая часть данных там лежит, тем лучше для операций чтения. По поводу 25% можно даже найти на официальной документации — www.postgresql.org/docs/devel/static/runtime-config-resource.html
Ну дак вы сами себе противоречите тогда. Идеальный вариант загрузить в шаред всю базу вместе с хэшами индексов и чтобы осталось место для других данных, тогда надо ставить кэш больше базы, а шаред буфер больше кэша. В итоге мы раньше упремся в ограничение системы на memory map, либо будем подгонять систему с железом под конкретную базу, а не наоборот.
А какие данные еще вы имеете ввиду, кроме размера базы (таблицы + индексы), которые будут в shared_buffers? Размер базы в shared_buffer как я и писал раньше, зачем больше?
Мы кажется не понимаем друг друга. shared_buffers это не общий размер кэша, это размер окна памяти который постгрес может расшарить между внутренними процессами вызвав mmap. Полный размер кэша может быть гораздо больше в пределах объемов виртуальной памяти. Объем shared_buffers имеет техническое ограничение в связи с механизмом выделения такой памяти ядром.
Мы кажется не понимаем друг друга.

Мне тоже так кажется.

shared_buffers это не общий размер кэша, это размер окна памяти который постгрес может расшарить между внутренними процессами вызвав mmap.

shared_buffers настройка в PostgreSQL указывает размер всего буфера, что может использовать PostgreSQL инстанс. Про «окно» я не понял, и возможно, не знаю что с ними.

Объем shared_buffers имеет техническое ограничение в связи с механизмом выделения такой памяти ядром.

Возможно мы о разном говорим, но как я знаю, каждый процесс на 32 битной машине лимитирован в 4ГБ адресного пространства, где хотя бы 1ГБ (в Линуксе) зарезервирован ядром. Это означает, что не зависимо, сколько на машине памяти, каждый PostgreSQL инстанс сможет обратится максимум к 3ГБ памяти. Тоесть максимум для shared_buffers — 2-2.5ГБ. Но на 64 битах нет такого ограничения.
Нет, есть память, а есть shared_memory (memory map). За общий объем кэша в виртуальной памяти отвечает effective_cache_size. Там планировщик прикидывает сколько памяти он сможет отожрать, какой объем индексов переместить в кэш и т.д. Именно значение effective_cache_size отвечает за то что вы имеете в виду: какой объем холодных данных швырнуть в память и сколько места мы можем отожрать сверху под промежуточные таблицы. Я сейчас намеренно не опускаюсь до уровня нод. Если effective_cache_size не хватает для выполнения запросов из кэша выбрасываются индексы и данные таблиц в пользу памяти для запросов.
shared_buffers это вообще о другом. Под капотом кластера куча процессов, минимум один для каждого подключения, плюс системные. Выкинув в кэш таблицу с индексами для одного процесса мы не можем дать туда доступ другому. Для этого часть данных перемещается в shared memory, которая свободно адресуется между процессами, но выделение памяти ядром идет по другой схеме. Данные из общего кэша перекидываются shared mem по мере надобности. Shared memory отдельно кэшируется системой и отдельно сбрасывается на диск, для ядра эта память очень специфична и дороже в обслуживании чем обычная. Поэтому и ограничения.
Как вы взялись писать рекомендации по тюнингу не зная механизма выделения памяти в постгресе я вообще не понимаю.
И как раз в shared memory кроется разница в рекомендациях под windows и *nix: спавн процессов в винде очень дорогой, по сравнению с никсами, в итоге рекомендовано использовать минимум процессов для подключения в windows, в таком случае издержки на shared memory минимальны, т.к. используется небольшой пул процессов, а то и промежуточная между клиентом и кластером очередь, у которой вообще одно подключение и соответственно один процесс, в последнем случае shared memory нужен только для внутренних работ кластера, там и 32мб хватит.
effective_cache_size — это размер файлового кеша, shared_buffers — размер shared memory. effective_cache_size используется для построения плана запроса (помещаются ли данные запроса в эту память? использовать агресивный план или придется делать sequence scan в таблице на фаловой системе?).
Как вы взялись писать рекомендации по тюнингу не зная механизма выделения памяти в постгресе я вообще не понимаю.

Странно, я пишу про одно, вы — про другое. С чего вы решили о моей не компетентности — не понятно. Вы просто пытаетесь мне что то доказать, я просто не пойму что. Возьмите параграф из книги где по вашему написано не верно, проведите исправление и пришлите пул реквест.
Насчет пул реквеста ок, пришлю. А про кэш сайзы: я сам уже обжегся, когда тюнил базу для своих специфических задач. Информация на сайте — плод правок начиная с версии 7.0, после 9.3 по хорошему им нужно часть переписать. Раньше на никсах была резкая деградация при превышении значением shared_buffers внутренних лимитов системы. С одной стороны: сильная «процессоориентированность» постгреса, с другой стороны бездумные рекомендации, с третьей стороны дешевый IPC в linux, в итоге у shared_buffers какой-то ореол серебряной пули появился. 25-40% от оперативной памяти это эстимейт памяти которую ядро сможет отмаппить без особых проблем. Кэш сайз это кэш сайз, а на диске он или в оперативке, это системе решать. Можно было железно застолбить оперативку запрашивая память для IPC, а не просто память, этим и воспользовались убив двух зайцев. В доках непрозрачно написано о механизмах, в итоге все в заблуждении.
Дискуссия будет длительная. Просто хочу в конце добавить. Robert Haas два года назад писал (еще до перехода PostgreSQL на nmap), что выдавали «львиную» долю памяти (shared_buffers), что давало хорошую производительность rhaas.blogspot.com/2012/03/tuning-sharedbuffers-and-walbuffers.html (у EnterpriseDB достаточно клиентов с PostgreSQL для таких исследований). Так что 40% точно не предел.
Я попозже развернуто напишу все. Ж)
И вот изюминкой бы была поваренная книга Postgresql собирающая кластер :)
Как и любой повар, сначала нужно узнать: «Вам кластер с чем подавать?». Я имею ввиду, что для кластера есть много разных решений :) Добавлять все в одну поваренную книгу будет трудозатратно.
Невозможность скачать в .epub по прямой ссылке из самого ipad повергло меня сегодня утром в дичайшую фрустрацию.
Да, пару владельцев iPad мне уже писали, что PostgreSQL фигня, потому что его на iPad нельзя поставить.
Раз уж я привлёк ваше внимание, скажите, пожалуйста что думаете насчет мониторинга переполнения work_mem путём сбора статистики о размере и количестве temp_files?

В postgresql, начиная с 9.2 это можно смотреть через

select datname,temp_files,temp_bytes from pg_stat_database;


В более ранних версиях, можно дёргать из логов, предварительно включив рубильник в конфиге:
log_temp_files = 0
В основном мониторим через парсинг логов, но такой подход тоже подойдет. Такую статистику нужно куда то собирать на график, что бы было видно в какие пики что происходит с базой.
Я вот прошелся у себя где-то по десятку основных серверов постгри и с радостью обнаружил, что везде work_mem хватает. Используем от 64 до 256 MB при общей памяти 64-128-160 RAM.
В логах log_temp_files включен на всех серверах изначально.
И вообще, у меня в парке нет уже тормозящих постгресов. Аж грустно стало — потюнить уже нечего )
Sign up to leave a comment.

Articles