Снапшоты

Что такое снапшоты

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

Для уровня изоляции Read Committed просто создается отдельный новый и новый снапшот на каждую команду.

В PostgreSQL снапшот определяется следующими тремя значениями

  • xmin, это первая из активных транзакций на момент создания снапшота.
  • xmax - это номер текущей транзакции + 1, то есть номер еще не существующей транзакции.
  • Список еще не завершенных на момент создания снапшота транзакций, список необходим, тк в постгрес не хранится информация когда и какая транзакция завершилась, а значит чтобы знать незакоммитченные транзакции на момент создания снапшота, нужно выписать все активные транзакции.

Также вспомним что запись строки держит под собой еще два номера xmin и xmax. Первый говорит о том, когда эта строка была добавлена, а второй, какой транзакцией эта строка была удалена/изменена.

Таким образом, при выполнении операции чтения из снапшота, запросу необходимо просто прочитать только те записи, которые лежат за горизонтом событий, а также у которых xmin лежит в промежутке [xmin;xmax) транзакции и не лежит в списке активных транзакций на момент создания снапшота.

Собственные изменения

Все усложняет тот факт, что команды в рамках одной транзакции не должны видеть изменения от команд которые произошли после (Такое возможно при использовании например курсора)

Для этого в заголовке версии строки есть специальное поле (которое отображается в псевдостолбцах cmin и cmax), показывающее порядковый номер операции внутри транзакции. Cmin представляет номер для вставки, cmax — для удаления

Горизонт событий

При работе со снимками можно задуматься об одной вещи, когда мы создаем снимок мы видим какие транзакции сейчас активны и можем легко определить самый маленький номер из них. Он и будет определять горизонт, за которым неактуальные версии строк в этой БД уже никогда не будут видны ни одной транзакции.

А именно следующие строки
Все строки, у которых xmax < 100, можно считать точно никому не нужными, тк они удалились транзакцией которую уже все взяли и возьмут в свои снапшоты

Такие версии строк могут быть очищены — именно поэтому понятие горизонта так важно с практической точки зрения.
Pasted image 20250529212319.png

  • old_snapshot_threshold определяет максимальное время жизни снимка. После этого времени сервер получает право удалять неактуальные версии строк, а если они понадобятся «долгоиграющей» транзакции, но она получит ошибку snapshot too old.
  • idle_in_transaction_session_timeout определяет максимальное время жизни бездействующей транзакции. После этого времени транзакция прерывается.