Один из моих серверов PostgreSQL содержит несколько (1-3) баз данных, которые получают постоянный поток данных. Данные не особенно структурированы, они составляют текущее время и множество наблюдаемых данных для этого конкретного момента. Скорость передачи данных довольно высока; для одной базы данных она составляет около гигабайта в день, для другой - около одной десятой. Я не ожидаю, что этот показатель увеличится. Производительность чтения является гораздо более низким приоритетом и в настоящее время приемлема.
В логах у меня есть это сообщение:
LOG: checkpoints are occurring too frequently (15 seconds apart)
HINT: Consider increasing the configuration parameter "checkpoint_segments".
Это значение в настоящее время установлено в 16, что любезно предоставлено pgtune
.
Какие настройки я должен рассмотреть, чтобы улучшить производительность записи? Я бы предпочел сохранить как можно больше безопасности. Учитывая объем поступающих данных, я мог бы согласиться потерять некоторые недавние данные в случае сбоя, если большая часть данных была неповрежденной.
Изменить: я сейчас использую PostgreSQL 9.0, но я планирую обновить до 9.1. Я не публикую подробности об оборудовании, потому что, хотя я признаю их важность, мне, в конечном счете, потребуется провести эту оптимизацию на нескольких машинах с очень разнообразным оборудованием. Если для ответа требуется оборудование, пожалуйста, дайте мне общую информацию, чтобы я мог применить ответ к машинам с различными конфигурациями оборудования.
источник
checkpoint_segments
в соответствии с рекомендациями? Что произошло?Ответы:
1 гигабайт в день - не такая высокая нагрузка при записи. Распространяется в течение дня, что составляет около 50 Кбайт в секунду. Медленный флэш-накопитель USB может справиться с этим. Я предполагаю, что это более бурный все же. Как подсказывает a_horse_with_no_name, увеличьте сегменты контрольных точек. 100 или около того не необычно.
Затем увеличьте значение
checkpoint_timeout
до 1 часа, а также увеличьте значениеcheckpoint_completion_target
до 1,0 (100%). Цель завершения сообщает PostgreSQL, как агрессивно писать в фоновом режиме, чтобы завершить x% перед запуском контрольной точки, что вынуждает сразу выписывать все данные из WAL и замедляет систему для сканирования, пока это происходит.Причина, по которой вы обычно не устанавливаете его на 100%, заключается в том, что довольно часто запись в один и тот же блок выполняется более одного раза, и, задерживая запись WAL в основное хранилище, вы предотвращаете двойную запись одного и того же блока без какой-либо причины.
Если маловероятно, что вы будете записывать в один и тот же блок более одного раза до того, как истечет время ожидания, то есть все, что вы делаете, это вставляете, а затем устанавливаете его довольно высоко, имеет смысл повысить его до 0,9 или около того. Худшее, что может случиться, - это то, что вы будете писать чуть чаще, чем в противном случае, но влияние контрольных точек будет значительно снижено.
источник
В очень «тяжелой» системе записи вы, вероятно, будете ограничены скоростью записи WAL во время пиковой активности.
Если вы действительно можете «принять потерю некоторых недавних данных при сбое», вы можете отключить синхронную фиксацию, которая:
Если вы можете изменить свое оборудование, вы можете рассмотреть любой из них для оптимизации записи:
--редактировать
Исходя из вашего комментария к превосходному ответу @ Скотта : «Объем записи практически полностью одинаков» и предполагаемая скорость передачи данных «50 Кбайт в секунду», я сомневаюсь, что вам нужно делать что-либо, что может привести к потере данных. Возможно, это помогло бы узнать, на что настроены некоторые другие ваши параметры конфигурации.
источник
Вы также можете проверить частоту / размер ваших коммитов: недавно я столкнулся с проблемой, когда пытался обновить> 1 миллион записей за одну транзакцию. Я получил сообщения журнала, аналогичные описанным в OP, но транзакция не могла завершиться даже через несколько часов. Когда я разбил запись на несколько небольших транзакций (10 000 записей или около того), общее требуемое время сократилось до 15 минут.
Я думаю, что произошло то, что Postgres потратил так много времени на написание логов, что checkpoint_timeout истек, прежде чем он смог добиться существенного прогресса в сохранении записей. Я не уверен, что это объяснение верно. Я все еще получаю предупреждения, но все записи в конечном итоге обрабатываются. Однако мне понадобился (и нашел) программный обходной путь, а не тот, который требует реконфигурации базы данных.
Смотрите также http://www.postgresql.org/docs/9.3/static/wal-configuration.html
источник