Примечание переводчика: это перевод статьи Лоренца Альбе, старшего консультанта и инженера технической поддержки CYBERTEC. В ней рассматриваются мощь и преимущества использования открытого исходного кода в PostgreSQL, а также его влияние на развитие технологий и сообщества. Дальше идёт текст оригинала.
На тренинге по настройке autovacuum один из участников спросил меня: «Почему значение autovacuum_vacuum_scale_factor
равно 0,2?» Отвергнув соблазн ответить догадкой или остротой в духе «Потому что потому!» или «Не устраивает — поменяй!», я решил воспользоваться случаем и явить истинное могущество открытого исходного кода. Меня так воодушевил этот опыт, что я решил поделиться им с вами.

Ужасный вопрос «Почему?»
Каждый, у кого есть дети, научился бояться вопроса «Почему?». Часто на такой вопрос сложно или вообще нереально ответить, а со временем понимаешь, что детям просто нравится ставить взрослых в тупик своими почемучками. С годами я уяснил для себя, что за наивным детским «Почему?» почти всегда стоит нечто большее, а именно:
Расскажи мне об этом поподробнее! Это так интересно (да и спать идти неохота)!
Почему так происходит? Так быть не должно!
Как математик и инженер-компьютерщик, я воспринимаю вопросы слишком буквально. Понимание контекста (из тех, что приведены выше), помогло мне находить более уместные ответы. Взрослые не так уж сильно отличаются от детей. Поэтому, когда они начинают спрашивать «Почему?» вместо «Как?», я пытаюсь понять, что действительно имеется в виду. В примере, который я привёл во введении, вопрос «Почему?» был продиктован скорее интересом, поэтому я и решил углубиться в него.
Истинная сила открытого исходного кода
Я особо не задумывался о могуществе открытого исходного кода, пока не услышал выступление Саймона Фиппса на European PGDay в 2010 году. В этом разделе он — тот гигант, на чьих плечах я стою!
Неужели главная причина использовать Open Source — это дешевизна?
Многие считают, что главное достоинство открытого программного обеспечения в том, что за него не нужно платить лицензионные отчисления. Это может быть существенным преимуществом. Но всё же общая стоимость владения Open Source-ПО не будет нулевой:
его нужно интегрировать в ваш ландшафт (по крайней мере, настроить мониторинг и резервное копирование);
нужно обучить людей или приобрести внешнюю экспертизу для настройки, эксплуатации и обслуживания программного обеспечения;
нужна поддержка на тот случай, если вы столкнётесь с проблемами, которые не сможете решить самостоятельно.
Настоящие преимущества Open Source-ПО
Главные преимущества открытого программного обеспечения заключаются не в его бесплатности, а в более очевидных моментах:
Вам не нужно писать в поддержку, чтобы понять, что означает сообщение об ошибке. Можно просто поискать его в исходниках. Скорее всего, даже человек, не писавший этого кода, поймёт, в чём дело.
Можно развернуть сколько угодно тестовых и dev-окружений, не беспокоясь о соблюдении условий лицензии (как в случае с коммерческими приложениями). Какой смысл в кластере Kubernetes, который позволяет создать инстанс базы данных одним нажатием кнопки, если сначала нужно проверить, разрешает ли это лицензия?
Что касается поддержки, то вы не зависите от милости одного вендора. Другие могут изучить исходники и оказывать поддержку третьего уровня (L3). Такая здоровая конкуренция выгодна клиенту.
Если разработчик перестанет поддерживать ПО, вы не останетесь у разбитого корыта (вспомните Oracle Forms). Если программное обеспечение достаточно популярно, кто-нибудь другой подхватит его и будет поддерживать. В крайнем случае всегда можно нанять разработчиков.
Качество ПО часто выше. Чем больше людей смотрит исходный код, тем выше вероятность найти ошибки и уязвимости. Плюс разработчики вынуждены ответственно относиться к своему делу: в закрытом ПО велик соблазн сделать что-то на скорую руку и не очень качественно. Но вот с PostgreSQL такой фокус не пройдёт. Прежде чем отправить туда подобную «халтуру», я бы сто раз подумал! Там за такое из города выгонят и камнями побьют.
Что касается знаний о «внутрянке» программного обеспечения, то вы не зависите от милости консультантов, которые на конференции перебросились парой слов с кем-то, кто знает кого-то, обладающего такой информацией. Закрытое ПО часто окружено удивительным количеством мифов и слухов, но не все из них соответствуют действительности.
Я решил проиллюстрировать последний тезис и сделать это вместе со своими учениками. Для этого я выяснил, чем руководствовались разработчики, устанавливая значение по умолчанию для параметра autovacuum_vacuum_scale_factor
.
Получаем исходный код
Поскольку я постоянно работаю с исходниками PostgreSQL, они у меня уже есть на машине. Впрочем, получить их несложно. Приложение I документации PostgreSQL ссылается на вики-страницу PostgreSQL. На ней написано, как клонировать репозиторий исходного кода PostgreSQL. Все, что нужно, — установить Git. После этого можно выполнить:
git clone https://git.postgresql.org/git/postgresql.git
Будет создана директория postgresql
с полной историей исходного кода PostgreSQL начиная с 1996 года. Теперь достаточно просто в неё перейти.
Поиск по сообщениям коммитов
Перейдя в репозиторий исходного кода PostgreSQL, мы сможем просматривать сообщения коммитов. Часто этого достаточно, чтобы получить нужный ответ:
git log
Поскольку список очень длинный, Git запускает пейджер. С хорошим пейджером можно искать текст в сообщениях коммитов, что я и сделал, поискав «autovacuum_vacuum_scale_factor»
. В итоге нашёлся единственный коммит от 2020 года, который исправил что-то в документации. Так что тут, похоже, тупик.
Впрочем, часто для ответа на вопрос достаточно сообщения коммита. Разумеется, эффективность такого подхода напрямую зависит от того, насколько информативны сами сообщения.
Сегодня сообщения к коммитам в PostgreSQL преимущественно идеальны: они содержат описание решённой проблемы, использованного подхода и ссылку на соответствующую дискуссию (к этому вопросу мы ещё вернёмся). Но если заглянуть дальше в прошлое, можно наткнуться на куда менее информативные сообщения вроде «Патч количества строк от Брюса». Но те безмятежные дни давно миновали. В общем, в следующий раз, когда будете писать сообщение к коммиту типа «Поправил пару багов», стоит остановиться и подумать. Ведь через пару лет вы ещё спасибо себе скажете за внятное описание того, что тогда нагородили.
Ищем нужное место в исходниках
Поскольку лог не принёс ничего полезного, придётся копнуть глубже. Первое, что нужно сделать, — найти место в исходниках, где определяется значение по умолчанию. Если вы плохо знакомы с исходным кодом PostgreSQL, это может оказаться непростым делом. Впрочем, найти параметр по его имени не так уж и сложно:
git grep autovacuum_vacuum_scale_factor
Получаем довольно короткий список:
doc/src/sgml/config.sgml:
doc/src/sgml/config.sgml: autovacuum_vacuum_scale_factor (floating point)
doc/src/sgml/config.sgml: autovacuum_vacuum_scale_factor
doc/src/sgml/ref/create_table.sgml:
doc/src/sgml/ref/create_table.sgml: autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor
doc/src/sgml/ref/create_table.sgml: autovacuum_vacuum_scale_factor
src/backend/access/common/reloptions.c: "autovacuum_vacuum_scale_factor",
src/backend/access/common/reloptions.c: {"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
src/backend/postmaster/autovacuum.c: * autovacuum_vacuum_scale_factor GUC variable. Ditto for analyze.
src/backend/utils/misc/guc_tables.c: {"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM,
src/backend/utils/misc/postgresql.conf.sample:#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum
src/bin/psql/tab-complete.c: "autovacuum_vacuum_scale_factor",
src/bin/psql/tab-complete.c: "toast.autovacuum_vacuum_scale_factor",
Файлы sgml — это документация, которая является частью исходного кода в PostgreSQL. Просмотр остальных упоминаний не займёт много времени. Если вы знаете, что такое GUC, — хорошо. Если нет, посмотрите в списке акронимов в приложении L документации по PostgreSQL.
Соответствующий фрагмент кода в guc_tables.c
выглядит следующим образом:
struct config_real ConfigureNamesReal[] =
{
[...]
{
{"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM,
gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."),
NULL
},
&autovacuum_vac_scale,
0.2, 0.0, 100.0,
NULL, NULL, NULL
},
[...]
}
Теперь мы знаем, где в исходном коде запрятано значение по умолчанию для autovacuum_vacuum_scale_factor
. Но как оно туда попало?
Путешествуем в прошлое
Назад в 2022-й
Можно воспользоваться git blame
, чтобы увидеть, откуда берутся отдельные строки в исходниках:
git blame src/backend/utils/misc/guc_tables.c
Видим:
0a20ff54f5e6 (Tom Lane 2022-09-13 11:05:07 -0400 3938) {"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM,
0a20ff54f5e6 (Tom Lane 2022-09-13 11:05:07 -0400 3939) gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."),
0a20ff54f5e6 (Tom Lane 2022-09-13 11:05:07 -0400 3940) NULL
0a20ff54f5e6 (Tom Lane 2022-09-13 11:05:07 -0400 3941) },
0a20ff54f5e6 (Tom Lane 2022-09-13 11:05:07 -0400 3942) &autovacuum_vac_scale,
0a20ff54f5e6 (Tom Lane 2022-09-13 11:05:07 -0400 3943) 0.2, 0.0, 100.0,
0a20ff54f5e6 (Tom Lane 2022-09-13 11:05:07 -0400 3944) NULL, NULL, NULL
Что это за коммит такой — 0a20ff54f5e6
? Можно, конечно, и через веб-интерфейс Git посмотреть, но проще в командной строке:
git show 0a20ff54f5e6
Видим следующее:
commit 0a20ff54f5e66158930d5328f89f087d4e9ab400
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue Sep 13 11:05:07 2022 -0400
Split up guc.c for better build speed and ease of maintenance.
guc.c has grown to be one of our largest .c files, making it
a bottleneck for compilation. It's also acquired a bunch of
knowledge that'd be better kept elsewhere, because of our not
very good habit of putting variable-specific check hooks here.
Hence, split it up along these lines:
* guc.c itself retains just the core GUC housekeeping mechanisms.
* New file guc_funcs.c contains the SET/SHOW interfaces and some
SQL-accessible functions for GUC manipulation.
* New file guc_tables.c contains the data arrays that define the
built-in GUC variables, along with some already-exported constant
tables.
[...]
Перевод
коммит 0a20ff54f5e66158930d5328f89f087d4e9ab400
Автор: Том Лэйн <tgl@sss.pgh.pa.us>
Дата: Вт, 13 сентября 11:05:07 2022 -0400
Разбил guc.c для повышения скорости сборки и простоты обслуживания.
guc.c разросся до неприличных размеров. Это один из самых больших наших .c-файлов и серьёзный тормоз для компиляции. Также он содержит кучу информации, которой место в другом файле. Это произошло из-за нашей не самой удачной практики размещать в guc.c хуки проверок для каждой переменной.
Поэтому разбил его следующим образом:
* В guc.c остались только основные механизмы обслуживания GUC.
* В новый файл guc_funcs.c переехали интерфейсы SET/SHOW и некоторые доступные для SQL функции для работы с GUC.
* Новый файл guc_tables.c содержит массивы данных, которые определяют встроенные переменные GUC, а также некоторые уже экспортированные таблицы констант.
Так что это был всего лишь коммит, который порефакторил код. До него весь код был в guc.c
. Перейдём к предыдущему коммиту:
git checkout 0a20ff54f5e6~1
Назад в 2011-й
Ещё раз воспользуемся git blame
:
git blame src/backend/utils/misc/guc.c
На этот раз видим:
29094193f526 (Tom Lane 2005-07-14 05:13:45 +0000 3885) {"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM,
29094193f526 (Tom Lane 2005-07-14 05:13:45 +0000 3886) gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."),
29094193f526 (Tom Lane 2005-07-14 05:13:45 +0000 3887) NULL
29094193f526 (Tom Lane 2005-07-14 05:13:45 +0000 3888) },
29094193f526 (Tom Lane 2005-07-14 05:13:45 +0000 3889) &autovacuum_vac_scale,
2594cf0e8c04 (Tom Lane 2011-04-07 00:11:01 -0400 3890) 0.2, 0.0, 100.0,
2594cf0e8c04 (Tom Lane 2011-04-07 00:11:01 -0400 3891) NULL, NULL, NULL
Хм, в коммите 2594cf0e8c04 что-то интересное:
git show 2594cf0e8c04
Увы, это очередной коммит, поменявший API (то есть к конкретным значениям autovacuum он отношения не имеет):
commit 2594cf0e8c04406ffff19b1651c5a406d376657c
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu Apr 7 00:11:01 2011 -0400
Revise the API for GUC variable assign hooks.
[...]
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 2151fde3618..5e4904aeb7f 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
[...]
@@ -2297,7 +2479,8 @@ static struct config_real ConfigureNamesReal[] =
NULL
},
&autovacuum_vac_scale,
- 0.2, 0.0, 100.0, NULL, NULL
+ 0.2, 0.0, 100.0,
+ NULL, NULL, NULL
},
{
{"autovacuum_analyze_scale_factor", PGC_SIGHUP, AUTOVACUUM,
[...]
Перевод
коммит 2594cf0e8c04406ffff19b1651c5a406d376657c
Автор: Том Лэйн <tgl@sss.pgh.pa.us>
Дата: Чт, 7 апреля 00:11:01 2011 -04:00
Пересмотр API для хуков, присваивающих значения GUC-переменным.
Перейдём к предыдущему коммиту:
git checkout 2594cf0e8c04~1
Смотрим, как менялся код в 2006-м
Выполняем git blame src/backend/utils/misc/guc.c
и видим:
29094193f526 (Tom Lane 2005-07-14 05:13:45 +0000 2295) {"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM,
29094193f526 (Tom Lane 2005-07-14 05:13:45 +0000 2296) gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."),
29094193f526 (Tom Lane 2005-07-14 05:13:45 +0000 2297) NULL
29094193f526 (Tom Lane 2005-07-14 05:13:45 +0000 2298) },
29094193f526 (Tom Lane 2005-07-14 05:13:45 +0000 2299) &autovacuum_vac_scale,
e0938c3f5b03 (Bruce Momjian 2006-09-02 23:12:16 +0000 2300) 0.2, 0.0, 100.0, NULL, NULL
Вот оно! Коммит e0938c3f5b03 — это как раз то, что нужно:
commit e0938c3f5b03e48bca32fe903f057e5777d43df8
Author: Bruce Momjian <bruce@momjian.us>
Date: Sat Sep 2 23:12:16 2006 +0000
Make autovacuum behavior more agressive, per discussion on hackers list
--- was part of autovacuum default 'on' patch that was reverted, but we
want this part.
Peter Eisentraut
[...]
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index fb12bd7adfc..f985c9da423 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
[...]
@@ -1738,7 +1738,7 @@ static struct config_real ConfigureNamesReal[] =
NULL
},
&autovacuum_vac_scale,
- 0.4, 0.0, 100.0, NULL, NULL
+ 0.2, 0.0, 100.0, NULL, NULL
},
{
{"autovacuum_analyze_scale_factor", PGC_SIGHUP, AUTOVACUUM,
[...]
Перевод
коммит e0938c3f5b03e48bca32fe903f057e5777d43df8
Автор: Брюс Момджян <bruce@momjian.us>
Дата: Сб, 2 сентября 23:12:16 2006 +0000
Делаем поведение autovacuum более агрессивным, как обсуждалось в рассылке для разработчиков. --- Изначально это было частью патча, включавшего autovacuum по умолчанию, но тот патч убрали, а эта часть нам нужна.
Питер Айзентраут
Получается, в 2006 году значение autovacuum_vacuum_scale_factor
было уменьшено с 0,4 до 0,2.
Ищем рассылку разработчиков
Чтобы разобраться в причинах этого изменения, стоит почитать обсуждение в списке рассылки. В проекте PostgreSQL есть архив рассылок, так что найти его не составит труда. Кстати, сейчас найти нужное место стало ещё проще, потому что теперь принято ссылаться на обсуждение прямо в описании коммита.
Для лучших результатов я воспользовался расширенным поиском по архиву. Сузил поиск до списка рассылки «pgsql-hackers», ввёл «autovacuum aggressive» в строку поиска, установил «Дата: любая» и «Сортировать по дате в обратном порядке». Получил кучу результатов, но на второй странице нашлась та самая ветка за август 2006 года.
Суммируя, Род Тейлор тогда заявил, что коэффициент масштабирования следует сделать более агрессивным, и предложил значение 0,1. Его поддержали Мэтью Т. О'Коннор и Джим К. Нэсби. Кроме того, Джим предложил значение 0,2. ИТАГАКИ Такахиро предложил использовать значение ниже 0,1, чтобы уменьшить разбиение страниц в индексе. Питер Айзентраут предложил 0,08, но Мэтью Т. О'Коннор посчитал это слишком резким изменением. Питер обозначил 0,2 в качестве компромисса. Джош Беркус счёл это слишком агрессивным и хотел остаться на 0,4. В конце концов Брюс Момджян разрешил спор, просто согласившись с предложением Питера.
Для понимания исторического контекста важно знать: до версии 8.1 (вышла в 2005 году) autovacuum был так называемым contrib module (тогда ещё не было понятия расширений). Начиная с версии 8.3 (2008 год), autovacuum стал включаться по умолчанию. То есть в то время autovacuum ещё находился на стадии эксперимента, и многие пользователи по-прежнему полагались на cron (планировщик задач) для регулярного запуска VACUUM. Да, то ещё было времечко.
Заключение
В PostgreSQL и исходный код, и обсуждения, которые приводят разработчиков к определённому решению, доступны для всеобщего обозрения. Я показал это на примере выше, выяснив причины, стоящие за значением параметра autovacuum_vacuum_scale_factor
, которое ему присваивается по умолчанию. В случае открытого программного обеспечения вроде PostgreSQL вы перестаёте быть всего лишь пассивным потребителем. Чувствуете, что 18 лет опыта и новые реалии являются достаточным основанием, чтобы что-то поменять? Тогда вступайте в ряды разработчиков, подключайтесь к рассылке и предлагайте свои идеи! Добро пожаловать в сообщество!
P. S.
Читайте также в нашем блоге: