PostgreSQL давно заслужил репутацию одного из самых мощных и надёжных систем управления базами данных, активно используемых во множестве производственных систем. Обычно разработчики, администраторы и инженеры стремятся повысить его производительность, снижая задержки, оптимизируя конфигурации и эффективно используя ресурсы. Однако необычный эксперимент показал, что PostgreSQL можно заставить работать в разы медленнее всего лишь изменением параметров конфигурации postgresql.conf. И всё это — усилиями одного человека, который, обладая свободным временем и желанием поэкспериментировать, решил поставить цель максимально замедлить работу сервера базы данных.
В этой статье мы рассмотрим, как можно искусственно сделать PostgreSQL в десятки тысяч раз медленнее, опираясь целиком на конфигурационные настройки, и как это отражается на ключевых аспектах работы СУБД. Главное ограничение автора — изменения должны быть только в postgresql.conf, без удалений индексов, изменения кода или аппаратных средств. Такой подход гарантирует, что база данных продолжит работать, но будет максимально неэффективной. Первым шагом было радикальное уменьшение размера буфера shared_buffers, который отвечает за кэширование страниц базы данных в памяти.
В стандартном варианте этой настройке выделяется достаточно большой объем — в эксперименте было 10 гигабайт. Для замедления работы его снизили до минимальной возможной величины — всего 8 мегабайт, что в десятки тысяч раз ниже изначального значения. Такая мелкая кэш-память стала причиной резкого увеличения количества системных вызовов чтения дисковых страниц, так как данные больше не находились в оперативной памяти, а пришлось извлекать почти напрямую с диска. Это моментально снизило пропускную способность системы примерно в семь раз, что уже является серьёзным показателем деградации скорости. Дальнейшее уменьшение shared_buffers до 2 мегабайт привело к ещё большему падению производительности — TPS (транзакций в секунду) рухнули до уровня значительно ниже половины тысячи, что примерно в 15 раз хуже предыдущего результата и почти в 15 раз хуже базовой конфигурации.
Отчасти это связано с тем, что слишком маленький кэш не способен удерживать даже минимальное количество активных страниц, необходимых для обработки привычных запросов, заставляя PostgreSQL безостановочно работать с дисковыми операциями, что сильно тормозит работу. Следующим методом замедления стала конфигурация процессов автосбора мусора (autovacuum). В нормальных условиях autovacuum запускается не слишком часто, чтобы не создавать лишнюю нагрузку. Однако для максимального упрощения работы и растягивания времени обработки был установлен порог триггера автосбора минимальным — в достаточно частых интервалах, максимально быстрый период между запусками и минимальное количество изменений для активации. Все ограничения на метрики подсчёта «стоимости» операций автосбора были сняты, что вынудило его запускаться практически каждую секунду.
Такое поведение означает, что сервер постоянно отвлекается на дополнительные ресурсоёмкие операции, не давая соединениям полноценно обрабатывать транзакции. Немаловажное значение также имела настройка объёма выделяемой памяти для работы процессов уборки — maintenance_work_mem — которая была уменьшена до 128 килобайт. Это привело к тому, что сам процесс сборки мусора работает менее эффективно, медленно обновляя статистику и структуры данных, что в свою очередь негативно отражается на работе планировщика запросов. Изменения в параметрах ведения журнала (логирования) — в частности, включение подробного логирования всех операций autovacuum — позволило получить отчёты с детальной статистикой, подтверждающей частые и ресурсоёмкие запуски процессов контроля и чистки. Это позволило анализировать настоящий «бутылочный горлышко» производительности и понимать, насколько именно затраты времени уходит на побочные процессы, а не на работу с транзакциями.
Особое внимание уделялось настройкам WAL (Write-Ahead Logging) — особенностям хранения и обработки журнала транзакций. Чтобы ухудшить производительность, параметры были настроены максимально агрессивно для частых и излишних операций сброса данных на диск. Задача заключалась в том, чтобы WAL очищался и чекпоинтировался слишком часто, без возможности эффективно кешировать промежуточные данные. Все параметры — от величины WAL до промежутков checkpoint — были настроены так, чтобы происходила большая нагрузка на диск и процессоры. Политика синхронизации журнала была изменена на open_datasync — вариант, который считается более медленным, что сказалось на скоростных характеристиках записи.
Кроме того, для эффекта были включены дополнительные функции ведения журналов логических изменений, подсчёта времени ввода-вывода, а параметр завершения checkpoint был установлен в минимальное значение, исключая распределение нагрузки по времени. В итоге наблюдались частые операции записи малыми порциями, что серьёзно увеличивало издержки и снижало TPS. Для того чтобы снизить эффективность использования индексов, что обычно помогает ускорять поиск и выборку данных, в конфигурации были заданы абсурдно высокие расходы на случайный доступ к страницам и обработку кортежей через индекс. Это заставляет планировщик запросов PostgreSQL отдавать предпочтение полным последовательным сканированиям таблиц, которые, при таких обрезанных настройках кэша и усиленном дисковом I/O, работают гораздо медленнее, чем поиск по индексам. И наконец, благодаря новым возможностям в PostgreSQL 18, автор смог настроить параметр io_method для создания искусственного узкого места в работе ввода-вывода.
Установив значение worker с ограничением io_workers до одного, вся работа с диском стала выполняться одной ниткой, тогда как изначально система способна параллельно обрабатывать множество операций. В результате серьёзно сократилась общая производительность за счёт создания единой очереди на поручение операций чтения и записи. Результатом всех проделанных манипуляций стала производительность ниже даже одного завершённого запроса в секунду — более чем в 42 000 раз медленнее по сравнению с базовыми настройками PostgreSQL. В контексте нагрузки в сто одновременных соединений и 120-секундного теста, показатель лично измеренный экспериментатором составил всего 11 успешно выполненных транзакций. Что же можно вынести из такого необычного и своего рода антиподхода? Во-первых, гибкость PostgreSQL действительно безгранична — можно не только ускорять работу, но и создавать конфигурации, которые сделают её почти невозможной.
Во-вторых, комфортная и стабильная работа баз данных сильно зависит от сбалансированной настройки ключевых параметров: размера кэша, алгоритмов автосбора, параметров журнала транзакций, стоимости операций выборки и параллелизма ввода-вывода. В-третьих, эксперименты подобного рода дают ценное понимание уязвимых мест и взаимодействий внутри системы, раскрывая более тонкие моменты, которые не очевидны при традиционных измерениях и оптимизациях. С технической точки зрения, самые масштабные замедления провоцируют постоянные операции ввода-вывода и масштабный overhead от параллельных процессов автосбора и аналитики таблиц при ограниченных ресурсах и агрессивных настройках. При этом работа планировщика запросов с изменёнными параметрами стоимости случайного доступа минимизирует использование индексов, что усугубляет сложность обработки типичных транзакций. Для разработчиков и администраторов, желающих глубже понять, как настройки PostgreSQL влияют на производительность, подобный эксперимент может стать уникальной демонстрацией внутренней механики СУБД.
Более того, знание о том, как можно ухудшить систему, поможет избежать подобных «ошибок» в реальной жизни, которые могут возникнуть, например, при некорректной настройке, случайных изменениях конфигураций или при неправильном понимании параметров. Если подведём итог, то искусственное замедление PostgreSQL — это не просто причуда или невозможная задача, а демонстрация удивительной комплексности и разнообразия опций конфигурации базы данных. С лёгкостью можно сделать систему непроизводительной, не меняя ни единой строки кода или оборудования — только лишь меняя параметры управления. А значит, правильный мониторинг, грамотная настройка и чёткое понимание функционала являются ключом к успешному администрированию и использованию PostgreSQL. В завершение отметим, что эксперимент проводился на современном железе: процессоре Ryzen 7950x, 32 гигабайтах оперативной памяти и быстром SSD, что ещё более подчёркивает влияние именно программных настроек.
Так что, если вы хотите «убить» базу данных, не прибегая к радикальным методам — достаточно заняться детальной настройкой postgresql.conf. Но для продуктивной работы, конечно, лучше делать всё наоборот — использовать знания о том, как PostgreSQL работает в хорошем режиме, чтобы раскрыть потенциал этого могучего инструмента.