max_connections — это бюджет памяти и автоматический выключатель, носящий костюм ёмкости. Он не решает, сколько запросов ваш сервер может выполнять одновременно; это решают количество ядер и хранилище, и они были решены, когда вы покупали оборудование. max_connections решает, сколько клиентских серверных процессов PostgreSQL создаст, прежде чем начнёт говорить «нет», и, что менее очевидно, сколько разделяемой памяти он откладывает в предположении, что каждый из них может появиться.
max_active_replication_origins — это десятилетний комментарий XXX, который наконец был оплачен. Он появился в PostgreSQL 18, и он существует потому, что то, чем он управляет, с 9.5 занимало число у другого параметра. На 14–17 число источников репликации, которые может отслеживать подписчик, задаётся max_replication_slots, параметром, чья настоящая работа — на издателе; с 16 документация всё равно перечисляет его в разделе для подписчика с примечанием, что он «также применяется на отправляющем сервере, но с другим значением». Отдельный параметр был впервые предложен в 2021 году и никуда не пошёл. Он ждал 18.
Небольшая настройка, которую большинство команд либо игнорируют, либо угадывают. Вот быстрая версия, а затем полный разбор.
Ключевые моменты
Fillfactor задаёт, насколько полно Postgres упаковывает каждую страницу таблицы при записи, оставляя остальное как свободное пространство для будущих обновлений, которые попадут на место (HOT-обновления), что сокращает WAL и ввод-вывод.
Начальная формула: 100 − (средний размер строки ÷ 8 192 × 100). Получите средний размер строки из pg_relation_size() и n_live_tup, запускайте после недавнего ANALYZE.
Для таблиц с интенсивными обновлениями берите значение ниже начального числа, чтобы оставить больше места для повторных перезаписей на месте.
Не устанавливайте по умолчанию для каждой таблицы 70 или 80. Рассчитывайте из реального размера строки таблицы и характера обновлений, затем корректируйте на основе наблюдаемой доли HOT и раздувания.
maintenance_work_mem — это параметр памяти, который ведёт себя так, как люди ошибочно предполагают, что ведёт себя work_mem: одно выделение, для одной операции, в одном сеансе, и число, которое вы задаёте, — это число, которое используется. work_mem — это допуск на каждую сортировку, каждый хеш, каждого исполнителя, который один запрос может затребовать дюжину раз. maintenance_work_mem — это потолок. Документация говорит, что «безопасно устанавливать это значение значительно больше work_mem», и это одно из немногих мест, где вам дают разрешение быть щедрым, и в основном они правы. Эта статья о «в основном».
Ваша база данных работает как часы — пока простой DELETE не поставит её на колени. Что пошло не так? Хотя мы склонны сосредотачиваться на оптимизации операций SELECT и INSERT, мы часто упускаем из виду скрытую сложность DELETE. А ведь удаление ненужных данных столь же важно. Устаревшие или нерелевантные данные могут раздувать вашу базу данных, снижать производительность и делать обслуживание кошмаром. Хуже того, хранение некоторых типов данных без действительного обоснования может даже привести к проблемам соответствия.
maintenance_io_concurrency — это effective_io_concurrency для работы, которую документация описывает как выполняемую «от имени множества клиентских сеансов». Эта фраза — весь смысл дизайна: VACUUM выплачивает долг по вводу-выводу, который накопил каждый сеанс, поэтому он может разумно быть более агрессивным в упреждающем чтении, чем любой из них. Механически эти два параметра — одна и та же ручка, включая трёхэтапную историю того, что означает число, и я не буду повторять это здесь. Эта статья о том, какая работа управляется им, потому что список не таков, как подсказывает название.
logical_decoding_work_mem — это то, сколько чужой незафиксированной транзакции walsender будет держать в памяти, прежде чем начнёт записывать эту транзакцию на диск во второй раз.
"SQL Server медленный". Как часто вы слышали это? Наиболее часто недовольство возникает при проблемах с производительностью, но во многих случаях это утверждение не выдерживает анализа. Чаще всего SQL Server просто реагирует на возлагаемую на него рабочую нагрузку, и сама рабочая нагрузка является проблемой.
SQL Server не гадает. Он точно показывает, где он потратил время и почему. Если проблема в движке, данные это покажут. Если нет, он покажет это так же ясно. Цель состоит в отделении догадок от фактов и проверки, действительно ли узкое место находится в SQL Server, а не в слое приложения.
Начнем со статистики ожиданий
Первый шагом является проверка статистики ожидания, которая дает непосредственный взгляд на то, где SQL Server проводит время в ожидании. Если имеется узкое место во вводе-выводе, блокировке или записи в журнал транзакций, это будет отражено в ожиданиях.
Продолжить чтение "Когда SQL Server не является узким местом"
Это самые старые параметры журналирования, которые PostgreSQL всё ещё поставляет, и вывод выглядит соответственно. Каждый из них — булев параметр, по умолчанию выключен, контекст superuser, и каждый заставляет серверный процесс вызывать getrusage() до и после одной стадии выполнения оператора и записывать разницу в журнал на уровне LOG. log_parser_stats покрывает парсер, анализ разбора и переписчик (три блока на оператор, по одному на стадию); log_planner_stats покрывает планировщик; log_executor_stats покрывает исполнитель; а log_statement_stats покрывает весь оператор, поэтому он отказывается включаться вместе с любым из других трёх, и они отказываются включаться вместе с ним. Вывод для одного SELECT count(*) при включённом log_statement_stats:
log_lock_waits — самый дешёвый детектор конкуренции за блокировки, который поставляет PostgreSQL, и вплоть до версии 18 он по умолчанию выключен. Включите его. PostgreSQL 19 сделает это за вас.
Эти два параметра отвечают на один и тот же вопрос об одном и том же процессе: что делает процесс запуска и почему он ещё не закончил? Процесс запуска — это серверный процесс, который воспроизводит WAL. На первичном сервере он существует только во время восстановления после сбоя, и пока он существует, ничто другое не может подключиться; клиент получает FATAL: the database system is not yet accepting connections. Когда он завершается, он выходит, и postmaster открывает двери. На standby он никогда не завершается; он воспроизводит в течение всей жизни сервера, и вопрос там не в том, как далеко он продвинулся, а в том, почему он остановился. Один параметр — для каждой из ситуаций, и оба отвечают в журнале сервера, потому что в обеих ситуациях журнал — единственное место, куда можно посмотреть.
По-настоящему полезный параметр, о котором почти никто не знает. Добавлен в PostgreSQL 14, по умолчанию выключен, исправляет конкретную патологию, которую каждый, кто запускал аналитические нагрузки, пережил хотя бы раз.