Найти в Дзене
Postgres Professional

В PostgreSQL стало на одно старое ограничение меньше: MultiXactOffset перевели на 64 бита

Это касается не редкой внутренней детали, а механизма мультитранзакций, который используется при блокировках строк, SELECT ... FOR SHARE/UPDATE и проверке внешних ключей. Когда одну строку блокируют несколько транзакций, PostgreSQL не может сохранить их прямо в t_xmax: это поле в заголовке записи вмещает только одно значение. Поэтому в строке хранится идентификатор мультитранзакции, а ее состав PostgreSQL берет из pg_multixact: offsets указывает смещение, members хранит список участников. Проблема была в том, что offsets оставался 32-битным. При этом мультитранзакции неизменяемы: если к блокировке добавляется еще одна транзакция, создается новая структура. Из-за этого при повторных блокировках одной и той же строки офсеты могут расти квадратично — 1, 3, 6, 10. На нагруженных системах это создавало реальный риск переполнения, а заметить его заранее было непросто. Теперь PostgreSQL использует 8-байтные offsets, и риск такого переполнения минимален. Компромисс тоже есть: сегменты offse

В PostgreSQL стало на одно старое ограничение меньше: MultiXactOffset перевели на 64 бита. Это касается не редкой внутренней детали, а механизма мультитранзакций, который используется при блокировках строк, SELECT ... FOR SHARE/UPDATE и проверке внешних ключей.

Когда одну строку блокируют несколько транзакций, PostgreSQL не может сохранить их прямо в t_xmax: это поле в заголовке записи вмещает только одно значение. Поэтому в строке хранится идентификатор мультитранзакции, а ее состав PostgreSQL берет из pg_multixact: offsets указывает смещение, members хранит список участников.

Проблема была в том, что offsets оставался 32-битным. При этом мультитранзакции неизменяемы: если к блокировке добавляется еще одна транзакция, создается новая структура. Из-за этого при повторных блокировках одной и той же строки офсеты могут расти квадратично — 1, 3, 6, 10. На нагруженных системах это создавало реальный риск переполнения, а заметить его заранее было непросто.

Теперь PostgreSQL использует 8-байтные offsets, и риск такого переполнения минимален. Компромисс тоже есть: сегменты offsets выросли вдвое, а при обновлении нужна дополнительная конвертация через pg_upgrade. Но взамен PostgreSQL получает больше запаса до жестких лимитов и более предсказуемое администрирование.

Подробно о том, как устроены мультитранзакции, почему именно offsets были узким местом и что меняет этот патч, рассказали на Хабре.

Читайте нас в MAX 🤩