Skip to content

MVCC в PostgreSQL — это плохо, как и у других

Radim Marek: PostgreSQL's MVCC is bad. So is everyone else's


Первое, что вы, вероятно, узнаете о Postgres, если следите за людьми, которым он не нравится, — это то, что MVCC — это плохо. Ошибка дизайна сорокалетней давности. Её признаки повсюду: раздутые таблицы, удваивающиеся в размере, 32-битный лимит счётчика транзакций, бесконечная борьба с VACUUM, кошмары с мёртвыми кортежами. Это подтверждается и авторитетами: Uber измерил амплификацию (здесь - усиление) записи в 2016 году и ушёл на MySQL из-за этого; группа баз данных Энди Павло назвала MVCC частью PostgreSQL, которую они ненавидят больше всего. Это реально. Postgres настолько плох, насколько это возможно.



Хотя всё это не преувеличено, это сводится к реальному дизайнерскому выбору. Раздувание, амплифицированные записи, постоянный уход за VACUUM — все эти обвинения связаны с решением, а не с дефектом, и мы воспроизводим каждое из них ниже на живом экземпляре PostgreSQL 19 beta2, чтобы вы могли увидеть ущерб своими глазами. Но вердикт, который распространяется из сообщества в сообщество, всегда останавливается на один вопрос раньше: по сравнению с чем? Что вместо этого делают все другие движки, и во что это обходится?



Потому что MVCC не является опциональным. Любая база данных, которая хочет, чтобы читатели не блокировали писателей, должна где-то хранить несколько версий строк, и каждый движок, который это делает, отвечает на одни и те же четыре вопроса:



  1. Где живут старые версии? В самой таблице или в отдельной структуре?

  2. В каком направлении указывают цепочки версий? От старых к новым или от новых к старым?

  3. На что указывают индексы? На физическое расположение строки или на логический ключ?

  4. Кто выполняет очистку и когда? Фоновый процесс позже или сама транзакция?



Ответы PostgreSQL: в таблице, от старых к новым, физическое расположение, фоновый процесс позже. Каждая стоимость, которую перечисляют критики, следует из этих четырёх ответов. И каждая альтернатива — это другой набор ответов, где счёт выставляется кому-то другому: писателю, читателю истории, tempdb, кэшу, компактору. Одна из них потратила годы инженерной работы, чтобы купить одно свойство, которое дизайн PostgreSQL имел бесплатно с первого дня. Все они терпят неудачу по-разному, когда транзакция остаётся открытой во время обеда...

Продолжить чтение "MVCC в PostgreSQL — это плохо, как и у других"

Всё о GUC по порядку: full_page_writes

Автор Christophe Pettus: All Your GUCs in a Row: full_page_writes


full_page_writes — это логический параметр, по умолчанию включён, его контекст — sighup, устанавливается в postgresql.conf или в командной строке. Это причина, по которой аварийное восстановление вообще работает, и это также причина, по которой ваш график WAL имеет «пилообразную» форму.

Продолжить чтение "Всё о GUC по порядку: full_page_writes"

CONVERT_IMPLICIT: Почему SQL Server игнорирует ваш индекс

Пересказ статьи rebecca@sqlfingers. CONVERT_IMPLICIT: Why SQL Server Is Ignoring Your Index


Вы построили индекс и протестировали запрос в SSMS. Index seek. Идеально. Вы пошли домой.

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

Это CONVERT_IMPLICIT - один из наиболее скрытых убийц производительности в SQL Server. Никаких ошибок. Никаких предупреждений в журнале приложения. Запрос возвращает правильные результаты, а ваш индекс отлично структурирован, но оптимизатор его не использует, поскольку тип данных, приходящих из приложения, не соответствует типу данных столбца - и SQL Server должен преобразовывать каждую строку, прежде чем он сможет выполнить сравнение.

Здесь рассказывается, как найти, понять и доказать разработчику, который продолжает говорить вам, что "все прекрасно работает на моей машине". Продолжить чтение "CONVERT_IMPLICIT: Почему SQL Server игнорирует ваш индекс"

Новости за 2026-08-29 - 2026-09-04

§ Лидеры недели

	Участник		w_sel	all_sel	select	dml	Всего	Рейтинг
Цыбин А.В. (magicdragon) 4 38 11 3 14 1524
Шибаев (saah) 4 90 9 0 9 537
Скоков Б.С. (leks$$) 4 48 8 0 8 1097
Виноградова С.М. (Tigra1) 2 154 7 0 7 148
Powkh N.M. (I_AiLL_I) 4 4 5 21 26 4141

§ Претенденты на попадание в TOP 100

Рейтинг	 Участник (решенные задачи, время в днях)
148 Tigra1 (154, 31.674)
Продолжить чтение "Новости за 2026-08-29 - 2026-09-04"

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

SHRIDHAR KHANAL: The Right Way to Give a Third-Party DBA Access to Your PostgreSQL Database


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



За эти годы я был по обе стороны этого разговора. Я был внешним администратором, которого подключали к базе данных клиента, и я был внутренним инженером, решающим, какой доступ предоставить. Шаблон, который я собираюсь вам показать, — это тот, к которому я бы прибег в любой из этих ситуаций: специально созданная, не-суперпользовательская роль, которая даёт внешней команде ровно то, что им нужно для реальной работы, и ничего лишнего.

Продолжить чтение "Правильный способ предоставить доступ к вашей базе данных PostgreSQL стороннему администратору"

Всё о GUC по порядку: fsync

Christophe Pettus: All Your GUCs in a Row: fsync


fsync — это логический параметр, по умолчанию включён, его контекст — sighup, поэтому его можно изменить перезагрузкой конфигурации без перезапуска. Это также самая опасная настройка в postgresql.conf. Большинство параметров из этой серии при неправильной установке стоят вам плохого плана или некоторой потраченной впустую памяти. Этот же параметр при неправильной установке стоит вам кластера.


Продолжить чтение "Всё о GUC по порядку: fsync"

GIN-индексы в PostgreSQL

Автор: Klaus Aschenbrenner: GIN Indexes in PostgreSQL


Если вы пришли из SQL Server (как в моём случае), индексы PostgreSQL могут показаться сначала знакомыми — существуют B-tree индексы, составные индексы, покрывающие индексы. А затем вы сталкиваетесь с запросами вроде:



WHERE payload @> '{"type":"payment","status":"failed"}'


или:



WHERE tsv @@ plainto_tsquery('postgresql')


В этот момент большинство разработчиков SQL Server задают два вопроса:



  1. Что это за операторы?

  2. Почему для этого PostgreSQL требуется совершенно другой тип индекса?


Продолжить чтение "GIN-индексы в PostgreSQL"

Всё о GUC по порядку: from_collapse_limit

Christophe Pettus: All Your GUCs in a Row: from_collapse_limit


Почти никто не использует форму запроса, которой управляет этот параметр:



SELECT * FROM x, y, (SELECT * FROM a, b, c WHERE something) AS ss
WHERE somethingelse;


Но вы постоянно создаёте её, не желая того. Ссылка на представление, содержащее соединение, приводит к тому, что определение представления подставляется вместо ссылки, и планировщик видит именно это: подзапрос в вашем списке FROM. Вложенные представления, SQL, сгенерированный ORM, и всё, что построено из многократно используемых фрагментах запросов, попадает к планировщику в этой форме. from_collapse_limit решает, что планировщик будет с этим делать.

Продолжить чтение "Всё о GUC по порядку: from_collapse_limit"

Всё о GUC по порядку: file_extend_method

Автор: Christophe Pettus: All Your GUCs in a Row: file_extend_method


file_extend_method — это «запасной выход» в тушке регулятора настройки. Он существует для одной цели: позволить вам отключить оптимизацию PostgreSQL 16 на тех файловых системах, где эта оптимизация вела себя некорректно.

Продолжить чтение "Всё о GUC по порядку: file_extend_method"

Зачем использовать составной индекс в SQL Server

Пересказ статьи Deepak Vohra. Why use a Composite Index in SQL Server


Запросы SQL могут выполняться долго, особенно на больших таблицах, при отсутствии надлежащего индексирования. Полное сканирование таблицы может быть затратной операцией, когда все, чего хочет пользователь, - это извлечь небольшое число строк на основе нескольких столбцов и фильтра WHERE. Как правильно проиндексировать наши таблицы для поддержки запросов по нескольким столбцам?

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

Не существует специальной настройки, требуемой для использования составных индексов. SQL Server поддерживает составные индексы. Для демонстрации функциональности я использую SQL Server 2022, исполняемый на Windows 10, с SQL Server Management Studio (SSMS) 2022. Продолжить чтение "Зачем использовать составной индекс в SQL Server"

Всё о GUC по порядку: file_copy_method

Christophe Pettus: All Your GUCs in a Row: file_copy_method


file_copy_method — это перечисление из двух значений с совершенно невероятной отдачей. Одна из его настроек позволяет копировать базу данных примерно за долю секунды, независимо от того, имеет ли база данных размер один гигабайт или один терабайт. Другая — это способ, которым PostgreSQL всегда это делал. Перечисление является новым в PostgreSQL 18, и интересное значение — clone.

Продолжить чтение "Всё о GUC по порядку: file_copy_method"

Обновление PostgreSQL с 9.6 до 17 с помощью pg_upgrade

SHRIDHAR KHANAL: Upgrading PostgreSQL 9.6 to 17 with pg_upgrade


При обновлении между основными версиями PostgreSQL есть несколько способов. Дамп и восстановление (dump/restore) — самый простой с точки зрения понимания, но время простоя растёт прямо пропорционально размеру базы данных, поэтому для всего, что больше нескольких терабайт, этот вариант не подходит. Логическая репликация позволяет добиться почти нулевого времени простоя, но она работает только начиная с PostgreSQL 10; если ваш исходный кластер работает на версии ниже 10, этот путь в нативном виде недоступен. Остаётся pg_upgrade — инструмент, поддерживаемый сообществом для обновления основных версий «на месте». С флагом –link он создаёт жёсткие ссылки вместо копирования файлов данных, поэтому сам шаг обновления остаётся быстрым, независимо от размера базы данных.


Эта статья основан на обновлении с версии 9.6 до 17 на Ubuntu с использованием pg_upgrade. Я проведу вас через каждый этап, отмечу моменты, которые застают людей врасплох, и поделюсь проверочными запросами, которые мы выполняем после завершения обновления.

Продолжить чтение "Обновление PostgreSQL с 9.6 до 17 с помощью pg_upgrade"

Всё о GUC по порядку: extra_float_digits

Автор: Christophe Pettus: All Your GUCs in a Row: extra_float_digits


extra_float_digits — это настройка, чья задача изменилась под ней. На протяжении большей части истории PostgreSQL она принуждала к выбору между выводом чисел с плавающей точкой, который был удобен для чтения, и выводом, который был абсолютно точным, и нельзя было иметь и то, и другое. Начиная с PostgreSQL 12 вам больше не нужно выбирать, поэтому параметр, к которому вы, возможно, привыкли прибегать, теперь вам редко понадобится.


Продолжить чтение "Всё о GUC по порядку: extra_float_digits"

Всё о GUC по порядку: external_pid_file

Christophe Pettus: All Your GUCs in a Row: external_pid_file


PostgreSQL уже записывает PID-файл. Каждый раз при запуске postmaster он помещает postmaster.pid в каталог данных и удаляет его при чистом завершении работы. Этот файл является блокировкой, которая предотвращает запуск второго postmaster с тем же каталогом данных, и содержит восемь строк с деталями работающего экземпляра: PID, каталог данных, время запуска, порт, каталог сокетов и так далее. external_pid_file не заменяет его. Он просит postmaster записать второй, гораздо меньший файл в другом месте.

Продолжить чтение "Всё о GUC по порядку: external_pid_file"

Новости за 2026-08-22 - 2026-08-28

§ Лидеры недели

	Участник		w_sel	all_sel	select	dml	Всего	Рейтинг
Цыбин А.В. (magicdragon) 4 34 8 6 14 1799
Виноградова С.М. (Tigra1) 2 152 6 0 6 151
Скоков Б.С. (leks$$) 3 44 5 0 5 1182

§ Претенденты на попадание в TOP 100

Рейтинг	 Участник (решенные задачи, время в днях)
151 Tigra1 (152, 29.339)
Продолжить чтение "Новости за 2026-08-22 - 2026-08-28"