Обновить

Будущее PostgreSQL: как 64-битный счетчик транзакций решает проблему масштабирования

Уровень сложностиСредний
Время на прочтение7 мин
Количество просмотров14K
Всего голосов 54: ↑54 и ↓0+65
Комментарии30

Комментарии 30

Как упоминалось выше, в каждом кортеже (он же tuple в английской документации) хранятся xmin и xmax. Получается, что в каждый кортеж теперь надо писать не 8 байт, а 16.

А как оно "включается" на уже существующей БД? Поднимается бэкап на версии Postgres c имплементированным 64-bit xid и что потом? Оба столбца каждой строки каждой таблицы апдейтится под новый тип данных или что? Или всё остаётся как есть и только в следующее изменение кортежа меняется тип этих столбцов? Или вообще всё иначе?

Это неточность формулировки. Правильно должно звучать так: надо было бы писать не 8, а 16 (в статье исправил тоже). Именно по этой причине мы не пошли таким путём. Мы храним туплы в старом 32–х битном формате, сохраняя 8 байт ксидов для каждого тупла, но дополнительно размещаем на странице “базу”, сложение с которой и выдаёт нам 8-ми байтный ксид.

Ага! Спасибо! Теперь понятно.

Эта база ведь прибавляется и к xmin, и к xmax всех туплов на этой странице?

А если разница между xmin и xmax туплов на одной странице вдруг станут отличаться больше чем на 4млрд? :) понятно что маловероятная ситуация...

Почему маловероятная? Автор же сам пишет, что 32-биный счетчик за сутки может переполняться. Удалили запись с возрастом два дня - и привет. Или я что-то неправильно понимаю?

Правильно понимаете. Конечно проблема существует и является ограничением текущей реализации. Если базу не получится сдвинуть, то будет ошибка. Но такие ситуации, когда в одном блоке разница между двумя номерами транзакций должна быть меньше 2**32, бывают значительно реже, чем ограничение на разницу 2**31 на всех блоках всего кластера.

При поднятии бэкапа все счётчики сбрасываються и заполняються уже средствами текущего движка СУБД.

Поэтому размерность кортежей в исходной БД роли не играет

Ну, я больше про тип спрашивал, но не про значения. Но там выше объяснили, что не изменяется как-бы ничего.

postgres плохо подходит для высоконагруженных транзакционных субд в первую очередь вовсе не из-за размерности xid. Главная причина - механизм версионности, который плодит версии строки внутри того же сегмента данных, что приводит к распуханию сегментов данных, потом к необходимости вакуума по тем же страницам данных, а потом и к дефрагментации из-за этого (и необходимости в vacuum full). Это все просто антипаттерн для системы где много изменений в данных. И сравните это с эталоном - Oracle, где старые версии строки хранятся в отдельном сегменте данных undo log, и поэтому: 1. Не распухает основной сегмент данных. 2. Очистка старых версий (вакуум) НЕ мешает работе с основными данными, 3. дефрагментация из-за пустых версий отсутствует. (единственное где из-за этого оракл проиграет - при Rollback-ах. Но много ли их выообще?? )

Это фатальный недостаток который в PG принципиально не излечим

Интересно, не думал об этом.
Можете посоветовать пост/статью на эту тему со сравнением популярных DB?

Ссылки на превосходство «эталона» ничем не обоснованы, так как бенчмарки с участием Оракла без письменного разрешения Оракла законодательно запрещены. Все крупнейшие базы реализованы на различных вариантах mvcc, бенчмарки показывают, что реализация в целом неплохая и конкурентоспособная. Сейчас статьи нет под рукой, но поищу и приложу ссылки на статьи с бенчмарками версионного контроля в базах.

orioledb придёт, порядок наведёт.

Там очень глобальные доработки в ядре и я сильно сомневаюсь что удастся их пропихнуть в основной состав Pg.

А переходить в чистом виде на OrioleDB не каждый решиться без поддержки.

И кстате пока в OrioleDB нельзя создавать индексы отличные от B-Tree, но очень ждем что команда Александра Короткова это решит.

Там патчи направлены на расширение функционала "table access method".

Часть патчей уже приняли, остальные ожидается в 18 версии.

Основное будет реализовано как расширение. Так что не всё так плохо.

К сожалению да, слабое место postgree на высоких нагрузках это MVCC.

Оракл точно так же на высоких нагрузках поднимает лапки с ORA-01555: snapshot too old. Я бы сказал, что современные СУБД — это ПО с помощью которого можно получать нужные результаты, но только если уметь это делать. Родовые недостатки есть у всех.

Совершенно верно. Большинство же "проблем" Постгреса - это в большей степени проблемы пользователя с Ораклом Головного Мозга. Который десятки лет ничего кроме Оракла не видел и теперь хочет чтоб везде было "как в Оракле" и ни как иначе.

Разве этот фатальный недостаток, который принципиально не излечим, не нивелируется CoW?

нет

Стоит добавить что это сделало невозможным использование служебного столбца xmin для разрешения конфликтов доступа в оптимистичной модели Entity Framework Core в .NET. Именно его предлагают использовать в ванильном PostgreSQL для этих целей. Официальный драйвер PostgreSQL логично не может больше смапить этот столбец в Postgres Pro Enterprise на тип unsigned int, потому что ожидается другой тип. И это явилось для нас очень неприятным открытием и послужило отказом от использования Postgres Pro Ent.

Да, есть такое. Но на Майкрософт мы повлиять не можем. С другой стороны, все понимают что рано или поздно в ванилле тип данных тоже изменится, после чего им придется изменить свой драйвер.

P.s. в standart версии ксиды хранятся по старорежимному, так что если нет потребности именно в ent, это не будет проблемой.

Это с скорее к разработчикам драйвера npgsql, но они вряд ли что то будут делать, чего нет в ванили. Кстати в последних версиях он поддерживает тип xid8. Но при попытке создания xmin с этим типом в enterprise через model (code) first, все равно получаю в БД xid, и оно конечно не работает. Надо будет попробовать покопаться во внутрянке драйвера когда будет время, может удастся научить его работать с вашими xid. Некоторые наши заказчики настаивают на использовании именно Postgres Pro Enterprise.

Тоже столкнулись с этой проблемой при реализации оптимистической блокировки EF, пока решения нет. и тоже использовать xid8 не получилось, может быть вендер "Pro Ent" что-то будет рекомендовать?

Это называется не «решили проблему», а «отложили проблему на неопределённое время». («Проблема 2000» передаёт горячий привет эстафету «проблеме 2038»).

Хочу использовать поле xmin как номер версии записи в коде go, чтобы случайно не записать в БД устаревшую версию записи из памяти.
Сейчас это бесполезно т.к. 32битный ИД может стать меньше чем был.
Хочу 64битный xmin :-)

Можно сделать колонку и класть туда 64 битный "xmin здорового человека" используя txid_current()

Сдается мне что проблема 32-битного счетчика транзакций в большой мере надуманная.

Почему за все годы никто в глобальной pgdg не серьезно задумался об этом?

Скорее всего 99,99% инсталляций не сталкиваются с подобной проблемой даже близко. А в тех случаях когда это все-таки "выстреливает" имело место изначально "кривая" архитектура приложения(АПП и БД в комплексе)

Вот бы об этом были первые же два абзаца...

Но даже это не основная проблема. Как упоминалось выше, в каждом кортеже (он же tuple в английской документации) хранятся xmin и xmax. Получается, что в каждый кортеж теперь надо было бы писать не 8 байт, а 16. А при условии что минимальный кортеж — это 24 байта, размер базы начинает стремительно увеличиваться.

Дополню, что проблема более комплексная. Просто добавить по 8 байт к каждой записи — не такая уж большая проблема. Самые объёмные таблицы в современных базах имеют довольно большие по размеру строки и суммарное увеличение от простой замены xmin/xmax на 8-байтные числа повлечёт увеличение размера баз хорошо если на 1-2%. По нынешним меркам это ничножная плата за отсутствие wraparound. Скорее всего современные файловые системы со сжатием вообще не покажут никакой существенной разницы. Сложности в другом. Чтобы сделать такую замену надо поменять формат хранения блоков и, следовательно, переписать всю базу в новый формат. То есть потеря обратной совместимости, до свидания pg_upgrade --link, и вообще быстрое обновление на такой формат невозможно. Для больших баз, а 64-битный счётчик транзакций нужен именно им, это серьёзный аргумент против. Вот и думает сообщество, хитровывернутая математика база+смещение со всей её сложностью и потенциальными проблемами (читай — багами), или таки честные 64 бита с необходимостью тяжёлой миграции на новый формат. А сама необходимость в 64-битном счётчике давно уже очевидна.

Думаю, имеет смысл сразу закладывать возможность дальнейшего расширения, иначе получится очередное "640kb хватит всем"

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Информация

Сайт
www.postgrespro.ru
Дата регистрации
Дата основания
Численность
501–1 000 человек
Местоположение
Россия
Представитель
Иван Панченко