Не так давно, на одном из внутренних докладов о PG разгорелся спор о том,
достаточно ли бит для хранения
идентификаторов транзакций. С одной стороны это не так уж мало, а с другой
стороны некоторые вспомнили возмущения на форумах, в которых говорилось, что на
дворе 21 век и пора уж расширить айдишники до современных размеров и убирать
эти "костыли" с ротацией. Посему, ниже коротенечко покажу на сколько
хватает текущего размера айдишника, зачем может понадобиться его
увеличивать и что такое "прошлое" и "будущее" в контексте транзакции.
Логично будет посмотреть на типы данных в PG и выбрать подходящий из существующих. То есть подойти могут bigint или decimal/numeric. В первом случае - это 8 байт (в 2 раза больше байт чем текущий transaction id), во втором - "user-specified precision up to 131072 digits before the decimal point". Иными словами, текущие 4 294 967 296 можно заменить либо на 18 446 744 073 709 551 616, либо на что-то космическое с 131072 знаками до запятой.
Всё пространство из значений,
условно, разбивается пополам. Вот хорошая иллюстрация, взятая отсюда:
Более подробно принцип работы можно проиллюстрировать следующим примером.
Чтобы не путаться в больших цифрах представим, что у нам доступно уникальных значения для идентификаторов
транзакций. Тогда
предыдущие
транзакции - это прошлое и столько же следующих транзакций - это будущее. Далее
представим, что текущая транзакция имеет номер 42. Тогда диапазон от
и до 42 - это прошлое,
а от 43 и до
- это будущее. Иначе говоря: всё что принадлежит отрезку
- это прошлое, а всё что принадлежит
- это
будущее. Тонкий момент с чётким указанием границ "прошлого" и "будущего" пока оставим в стороне.
Исходя из вышесказанного очевидно, что пока все существующие номера транзакций находятся в прошлом - всё хорошо. Но прошлое сдвигается вперёд с каждым новым номером и в какой-то момент транзакции из прошлого могут попасть в будущее. Эта проблема хорошо описана в вышеприведённых ссылках на русском и на английском.
Конечно же всё зависит от нагрузки. Но нужно помнить, что для запросов на чтение реальный tid не выделяется, учитываются только транзакции, изменяющие данные. Итого: ниже приведено несколько графиков зависимости времени до ротации от числа реальных транзакций в секунду.
Видим, что для нагрузки меньше 100 запросов в секунду транзакции будут ротироваться чуть ли не раз в год. Абсолютно не проблема, ибо ни одна транзакция в приличной БД не может непрерывно длиться год.
А вот что получается для более нагруженных случаев:
Если у вас 10 000 запросов в секунду, то ротация будет не реже раза в 2.5 дня. И тут уж могут быть различные проблемы. Но, с другой стороны, если у вас 10 000 запросов в БД и вы ещё не упали - вы знаете как работать с БД и в курсе о большинстве возможных проблем :)
PG, как и любую другую приличную БД, пишут умные дяди и тёти и 4 байта для tid вполне достаточно для современных условий эксплуатации.