linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it worksскоро
  • Уроки
  • База знаний
  • Собеседование
home/postgres/kb/MVCC и видимость/snapshot-export

kb/mvcc ── MVCC и видимость ── advanced

Экспорт снимка между сессиями

pg_export_snapshot() возвращает идентификатор снимка, а другая сессия через SET TRANSACTION SNAPSHOT берёт ровно тот же снимок и видит данные в том же срезе времени. Так работает параллельный pg_dump: все рабочие процессы выгружают согласованную копию. Экспортирующая транзакция должна оставаться открытой.

view as markdownaka: export-snapshot, set-transaction-snapshot

Снимок (см. snapshot) - это компактный набор чисел. Раз так, его можно не только взять, но и передать другой сессии, чтобы две транзакции видели базу в одинаковом срезе времени.

Как передать снимок

В первой сессии экспортируем снимок изнутри открытой транзакции:

sql
BEGIN;
SELECT pg_export_snapshot();
-- 00000006-00000002-1
-- транзакцию НЕ коммитим: пока она открыта, снимок «живёт»

Во второй сессии берём этот же снимок первым же действием транзакции:

sql
BEGIN;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION SNAPSHOT '00000006-00000002-1';
-- теперь эта транзакция видит данные точно так же, как первая

С этого момента обе сессии видят один и тот же набор версий: чужие коммиты, случившиеся после экспорта, скрыты от обеих.

Жёсткие условия

Механизм требовательный, и не зря:

  • принимающая транзакция должна быть на уровне Repeatable Read или Serializable (см. isolation-levels) - на Read Committed снимок берётся на каждый оператор, делить нечего;
  • SET TRANSACTION SNAPSHOT должен идти до любого запроса в транзакции, пока у неё ещё нет собственного снимка;
  • экспортирующая транзакция обязана оставаться открытой, пока все принимающие не подхватили снимок. Закроется раньше - идентификатор станет недействительным.

Зачем это нужно: параллельный бэкап

Главный потребитель - pg_dump -j (параллельная выгрузка). Чтобы дамп был согласованным, все рабочие процессы должны видеть базу в один и тот же момент. Ведущий процесс экспортирует снимок, остальные подхватывают его через SET TRANSACTION SNAPSHOT - и выгружают разные таблицы, но из одного среза времени. Без этого параллельный дамп мог бы поймать половину таблиц до чужого коммита, половину после, и получить несогласованную копию.

Экспорт снимка - это не способ «поделиться данными» между сессиями, а способ договориться о точке во времени, из которой обе на эти данные смотрят.

§ команды

bash
SELECT pg_export_snapshot();

Выдать идентификатор текущего снимка (внутри открытой транзакции)

bash
SET TRANSACTION SNAPSHOT '00000006-00000002-1';

Принять чужой снимок первым действием своей транзакции

bash
BEGIN ISOLATION LEVEL REPEATABLE READ;

Уровень, на котором приём снимка вообще имеет смысл

§ см. также

  • snapshotСнимок данных (snapshot)Снимок - это не копия данных, а три числа: xmin, xmax и список активных xid между ними. Плюс правило, как по ним решать видимость версии. По снимку транзакция отделяет «прошлое» (зафиксировано до неё) от «настоящего» (идёт прямо сейчас) и «будущего» (ещё не начато). Дёшево по памяти, дорого по числу соединений.
  • isolation-levelsУровни изоляции в PostgreSQLPostgreSQL различает три уровня изоляции. Read Committed (по умолчанию) берёт свежий снимок на каждый оператор. Repeatable Read берёт один снимок на транзакцию и держит его до конца. Serializable добавляет проверку, что транзакции можно выстроить в строгий порядок. Грязного чтения в PostgreSQL не бывает ни на одном уровне.
  • virtual-xidВиртуальные и реальные xidКаждая транзакция сразу получает виртуальный xid - дешёвую пару «бэкенд/счётчик», которая ничего не расходует. Настоящий 32-битный xid выдаётся только когда транзакция впервые что-то пишет. Поэтому read-only транзакции не тратят xid вовсе - это бережёт ограниченное пространство счётчика и отдаляет wraparound.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки